/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0

THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.

See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */


"use strict";
var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var ts;
(function (ts) {
    // WARNING: The script `configurePrerelease.ts` uses a regexp to parse out these values.
    // If changing the text in this section, be sure to test `configurePrerelease` too.
    ts.versionMajorMinor = "3.9";
    /** The version of the TypeScript compiler release */
    ts.version = "3.9.7";
    /**
     * Returns the native Map implementation if it is available and compatible (i.e. supports iteration).
     */
    /* @internal */
    function tryGetNativeMap() {
        // eslint-disable-next-line no-in-operator
        return typeof Map !== "undefined" && "entries" in Map.prototype ? Map : undefined;
    }
    ts.tryGetNativeMap = tryGetNativeMap;
    /* @internal */
    ts.Map = tryGetNativeMap() || (function () {
        // NOTE: createMapShim will be defined for typescriptServices.js but not for tsc.js, so we must test for it.
        if (typeof ts.createMapShim === "function") {
            return ts.createMapShim();
        }
        throw new Error("TypeScript requires an environment that provides a compatible native Map implementation.");
    })();
    /* @internal */
    var Comparison;
    (function (Comparison) {
        Comparison[Comparison["LessThan"] = -1] = "LessThan";
        Comparison[Comparison["EqualTo"] = 0] = "EqualTo";
        Comparison[Comparison["GreaterThan"] = 1] = "GreaterThan";
    })(Comparison = ts.Comparison || (ts.Comparison = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    ts.emptyArray = [];
    /** Create a new map. */
    function createMap() {
        return new ts.Map();
    }
    ts.createMap = createMap;
    /** Create a new map from an array of entries. */
    function createMapFromEntries(entries) {
        var map = createMap();
        for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
            var _a = entries_1[_i], key = _a[0], value = _a[1];
            map.set(key, value);
        }
        return map;
    }
    ts.createMapFromEntries = createMapFromEntries;
    /** Create a new map from a template object is provided, the map will copy entries from it. */
    function createMapFromTemplate(template) {
        var map = new ts.Map();
        // Copies keys/values from template. Note that for..in will not throw if
        // template is undefined, and instead will just exit the loop.
        for (var key in template) {
            if (hasOwnProperty.call(template, key)) {
                map.set(key, template[key]);
            }
        }
        return map;
    }
    ts.createMapFromTemplate = createMapFromTemplate;
    function length(array) {
        return array ? array.length : 0;
    }
    ts.length = length;
    /**
     * Iterates through 'array' by index and performs the callback on each element of array until the callback
     * returns a truthy value, then returns that value.
     * If no such value is found, the callback is applied to each element of array and undefined is returned.
     */
    function forEach(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var result = callback(array[i], i);
                if (result) {
                    return result;
                }
            }
        }
        return undefined;
    }
    ts.forEach = forEach;
    /**
     * Like `forEach`, but iterates in reverse order.
     */
    function forEachRight(array, callback) {
        if (array) {
            for (var i = array.length - 1; i >= 0; i--) {
                var result = callback(array[i], i);
                if (result) {
                    return result;
                }
            }
        }
        return undefined;
    }
    ts.forEachRight = forEachRight;
    /** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
    function firstDefined(array, callback) {
        if (array === undefined) {
            return undefined;
        }
        for (var i = 0; i < array.length; i++) {
            var result = callback(array[i], i);
            if (result !== undefined) {
                return result;
            }
        }
        return undefined;
    }
    ts.firstDefined = firstDefined;
    function firstDefinedIterator(iter, callback) {
        while (true) {
            var iterResult = iter.next();
            if (iterResult.done) {
                return undefined;
            }
            var result = callback(iterResult.value);
            if (result !== undefined) {
                return result;
            }
        }
    }
    ts.firstDefinedIterator = firstDefinedIterator;
    function zipWith(arrayA, arrayB, callback) {
        var result = [];
        ts.Debug.assertEqual(arrayA.length, arrayB.length);
        for (var i = 0; i < arrayA.length; i++) {
            result.push(callback(arrayA[i], arrayB[i], i));
        }
        return result;
    }
    ts.zipWith = zipWith;
    function zipToIterator(arrayA, arrayB) {
        ts.Debug.assertEqual(arrayA.length, arrayB.length);
        var i = 0;
        return {
            next: function () {
                if (i === arrayA.length) {
                    return { value: undefined, done: true };
                }
                i++;
                return { value: [arrayA[i - 1], arrayB[i - 1]], done: false };
            }
        };
    }
    ts.zipToIterator = zipToIterator;
    function zipToMap(keys, values) {
        ts.Debug.assert(keys.length === values.length);
        var map = createMap();
        for (var i = 0; i < keys.length; ++i) {
            map.set(keys[i], values[i]);
        }
        return map;
    }
    ts.zipToMap = zipToMap;
    /**
     * Iterates through `array` by index and performs the callback on each element of array until the callback
     * returns a falsey value, then returns false.
     * If no such value is found, the callback is applied to each element of array and `true` is returned.
     */
    function every(array, callback) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                if (!callback(array[i], i)) {
                    return false;
                }
            }
        }
        return true;
    }
    ts.every = every;
    function find(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            var value = array[i];
            if (predicate(value, i)) {
                return value;
            }
        }
        return undefined;
    }
    ts.find = find;
    function findLast(array, predicate) {
        for (var i = array.length - 1; i >= 0; i--) {
            var value = array[i];
            if (predicate(value, i)) {
                return value;
            }
        }
        return undefined;
    }
    ts.findLast = findLast;
    /** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */
    function findIndex(array, predicate, startIndex) {
        for (var i = startIndex || 0; i < array.length; i++) {
            if (predicate(array[i], i)) {
                return i;
            }
        }
        return -1;
    }
    ts.findIndex = findIndex;
    function findLastIndex(array, predicate, startIndex) {
        for (var i = startIndex === undefined ? array.length - 1 : startIndex; i >= 0; i--) {
            if (predicate(array[i], i)) {
                return i;
            }
        }
        return -1;
    }
    ts.findLastIndex = findLastIndex;
    /**
     * Returns the first truthy result of `callback`, or else fails.
     * This is like `forEach`, but never returns undefined.
     */
    function findMap(array, callback) {
        for (var i = 0; i < array.length; i++) {
            var result = callback(array[i], i);
            if (result) {
                return result;
            }
        }
        return ts.Debug.fail();
    }
    ts.findMap = findMap;
    function contains(array, value, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (array) {
            for (var _i = 0, array_1 = array; _i < array_1.length; _i++) {
                var v = array_1[_i];
                if (equalityComparer(v, value)) {
                    return true;
                }
            }
        }
        return false;
    }
    ts.contains = contains;
    function arraysEqual(a, b, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        return a.length === b.length && a.every(function (x, i) { return equalityComparer(x, b[i]); });
    }
    ts.arraysEqual = arraysEqual;
    function indexOfAnyCharCode(text, charCodes, start) {
        for (var i = start || 0; i < text.length; i++) {
            if (contains(charCodes, text.charCodeAt(i))) {
                return i;
            }
        }
        return -1;
    }
    ts.indexOfAnyCharCode = indexOfAnyCharCode;
    function countWhere(array, predicate) {
        var count = 0;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = array[i];
                if (predicate(v, i)) {
                    count++;
                }
            }
        }
        return count;
    }
    ts.countWhere = countWhere;
    function filter(array, f) {
        if (array) {
            var len = array.length;
            var i = 0;
            while (i < len && f(array[i]))
                i++;
            if (i < len) {
                var result = array.slice(0, i);
                i++;
                while (i < len) {
                    var item = array[i];
                    if (f(item)) {
                        result.push(item);
                    }
                    i++;
                }
                return result;
            }
        }
        return array;
    }
    ts.filter = filter;
    function filterMutate(array, f) {
        var outIndex = 0;
        for (var i = 0; i < array.length; i++) {
            if (f(array[i], i, array)) {
                array[outIndex] = array[i];
                outIndex++;
            }
        }
        array.length = outIndex;
    }
    ts.filterMutate = filterMutate;
    function clear(array) {
        array.length = 0;
    }
    ts.clear = clear;
    function map(array, f) {
        var result;
        if (array) {
            result = [];
            for (var i = 0; i < array.length; i++) {
                result.push(f(array[i], i));
            }
        }
        return result;
    }
    ts.map = map;
    function mapIterator(iter, mapFn) {
        return {
            next: function () {
                var iterRes = iter.next();
                return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false };
            }
        };
    }
    ts.mapIterator = mapIterator;
    function sameMap(array, f) {
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var item = array[i];
                var mapped = f(item, i);
                if (item !== mapped) {
                    var result = array.slice(0, i);
                    result.push(mapped);
                    for (i++; i < array.length; i++) {
                        result.push(f(array[i], i));
                    }
                    return result;
                }
            }
        }
        return array;
    }
    ts.sameMap = sameMap;
    /**
     * Flattens an array containing a mix of array or non-array elements.
     *
     * @param array The array to flatten.
     */
    function flatten(array) {
        var result = [];
        for (var _i = 0, array_2 = array; _i < array_2.length; _i++) {
            var v = array_2[_i];
            if (v) {
                if (isArray(v)) {
                    addRange(result, v);
                }
                else {
                    result.push(v);
                }
            }
        }
        return result;
    }
    ts.flatten = flatten;
    /**
     * Maps an array. If the mapped value is an array, it is spread into the result.
     *
     * @param array The array to map.
     * @param mapfn The callback used to map the result into one or more values.
     */
    function flatMap(array, mapfn) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = mapfn(array[i], i);
                if (v) {
                    if (isArray(v)) {
                        result = addRange(result, v);
                    }
                    else {
                        result = append(result, v);
                    }
                }
            }
        }
        return result || ts.emptyArray;
    }
    ts.flatMap = flatMap;
    function flatMapToMutable(array, mapfn) {
        var result = [];
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = mapfn(array[i], i);
                if (v) {
                    if (isArray(v)) {
                        addRange(result, v);
                    }
                    else {
                        result.push(v);
                    }
                }
            }
        }
        return result;
    }
    ts.flatMapToMutable = flatMapToMutable;
    function flatMapIterator(iter, mapfn) {
        var first = iter.next();
        if (first.done) {
            return ts.emptyIterator;
        }
        var currentIter = getIterator(first.value);
        return {
            next: function () {
                while (true) {
                    var currentRes = currentIter.next();
                    if (!currentRes.done) {
                        return currentRes;
                    }
                    var iterRes = iter.next();
                    if (iterRes.done) {
                        return iterRes;
                    }
                    currentIter = getIterator(iterRes.value);
                }
            },
        };
        function getIterator(x) {
            var res = mapfn(x);
            return res === undefined ? ts.emptyIterator : isArray(res) ? arrayIterator(res) : res;
        }
    }
    ts.flatMapIterator = flatMapIterator;
    function sameFlatMap(array, mapfn) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var item = array[i];
                var mapped = mapfn(item, i);
                if (result || item !== mapped || isArray(mapped)) {
                    if (!result) {
                        result = array.slice(0, i);
                    }
                    if (isArray(mapped)) {
                        addRange(result, mapped);
                    }
                    else {
                        result.push(mapped);
                    }
                }
            }
        }
        return result || array;
    }
    ts.sameFlatMap = sameFlatMap;
    function mapAllOrFail(array, mapFn) {
        var result = [];
        for (var i = 0; i < array.length; i++) {
            var mapped = mapFn(array[i], i);
            if (mapped === undefined) {
                return undefined;
            }
            result.push(mapped);
        }
        return result;
    }
    ts.mapAllOrFail = mapAllOrFail;
    function mapDefined(array, mapFn) {
        var result = [];
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var mapped = mapFn(array[i], i);
                if (mapped !== undefined) {
                    result.push(mapped);
                }
            }
        }
        return result;
    }
    ts.mapDefined = mapDefined;
    function mapDefinedIterator(iter, mapFn) {
        return {
            next: function () {
                while (true) {
                    var res = iter.next();
                    if (res.done) {
                        return res;
                    }
                    var value = mapFn(res.value);
                    if (value !== undefined) {
                        return { value: value, done: false };
                    }
                }
            }
        };
    }
    ts.mapDefinedIterator = mapDefinedIterator;
    function mapDefinedMap(map, mapValue, mapKey) {
        if (mapKey === void 0) { mapKey = identity; }
        var result = createMap();
        map.forEach(function (value, key) {
            var mapped = mapValue(value, key);
            if (mapped !== undefined) {
                result.set(mapKey(key), mapped);
            }
        });
        return result;
    }
    ts.mapDefinedMap = mapDefinedMap;
    ts.emptyIterator = { next: function () { return ({ value: undefined, done: true }); } };
    function singleIterator(value) {
        var done = false;
        return {
            next: function () {
                var wasDone = done;
                done = true;
                return wasDone ? { value: undefined, done: true } : { value: value, done: false };
            }
        };
    }
    ts.singleIterator = singleIterator;
    function spanMap(array, keyfn, mapfn) {
        var result;
        if (array) {
            result = [];
            var len = array.length;
            var previousKey = void 0;
            var key = void 0;
            var start = 0;
            var pos = 0;
            while (start < len) {
                while (pos < len) {
                    var value = array[pos];
                    key = keyfn(value, pos);
                    if (pos === 0) {
                        previousKey = key;
                    }
                    else if (key !== previousKey) {
                        break;
                    }
                    pos++;
                }
                if (start < pos) {
                    var v = mapfn(array.slice(start, pos), previousKey, start, pos);
                    if (v) {
                        result.push(v);
                    }
                    start = pos;
                }
                previousKey = key;
                pos++;
            }
        }
        return result;
    }
    ts.spanMap = spanMap;
    function mapEntries(map, f) {
        if (!map) {
            return undefined;
        }
        var result = createMap();
        map.forEach(function (value, key) {
            var _a = f(key, value), newKey = _a[0], newValue = _a[1];
            result.set(newKey, newValue);
        });
        return result;
    }
    ts.mapEntries = mapEntries;
    function some(array, predicate) {
        if (array) {
            if (predicate) {
                for (var _i = 0, array_3 = array; _i < array_3.length; _i++) {
                    var v = array_3[_i];
                    if (predicate(v)) {
                        return true;
                    }
                }
            }
            else {
                return array.length > 0;
            }
        }
        return false;
    }
    ts.some = some;
    /** Calls the callback with (start, afterEnd) index pairs for each range where 'pred' is true. */
    function getRangesWhere(arr, pred, cb) {
        var start;
        for (var i = 0; i < arr.length; i++) {
            if (pred(arr[i])) {
                start = start === undefined ? i : start;
            }
            else {
                if (start !== undefined) {
                    cb(start, i);
                    start = undefined;
                }
            }
        }
        if (start !== undefined)
            cb(start, arr.length);
    }
    ts.getRangesWhere = getRangesWhere;
    function concatenate(array1, array2) {
        if (!some(array2))
            return array1;
        if (!some(array1))
            return array2;
        return __spreadArrays(array1, array2);
    }
    ts.concatenate = concatenate;
    function selectIndex(_, i) {
        return i;
    }
    function indicesOf(array) {
        return array.map(selectIndex);
    }
    ts.indicesOf = indicesOf;
    function deduplicateRelational(array, equalityComparer, comparer) {
        // Perform a stable sort of the array. This ensures the first entry in a list of
        // duplicates remains the first entry in the result.
        var indices = indicesOf(array);
        stableSortIndices(array, indices, comparer);
        var last = array[indices[0]];
        var deduplicated = [indices[0]];
        for (var i = 1; i < indices.length; i++) {
            var index = indices[i];
            var item = array[index];
            if (!equalityComparer(last, item)) {
                deduplicated.push(index);
                last = item;
            }
        }
        // restore original order
        deduplicated.sort();
        return deduplicated.map(function (i) { return array[i]; });
    }
    function deduplicateEquality(array, equalityComparer) {
        var result = [];
        for (var _i = 0, array_4 = array; _i < array_4.length; _i++) {
            var item = array_4[_i];
            pushIfUnique(result, item, equalityComparer);
        }
        return result;
    }
    /**
     * Deduplicates an unsorted array.
     * @param equalityComparer An `EqualityComparer` used to determine if two values are duplicates.
     * @param comparer An optional `Comparer` used to sort entries before comparison, though the
     * result will remain in the original order in `array`.
     */
    function deduplicate(array, equalityComparer, comparer) {
        return array.length === 0 ? [] :
            array.length === 1 ? array.slice() :
                comparer ? deduplicateRelational(array, equalityComparer, comparer) :
                    deduplicateEquality(array, equalityComparer);
    }
    ts.deduplicate = deduplicate;
    /**
     * Deduplicates an array that has already been sorted.
     */
    function deduplicateSorted(array, comparer) {
        if (array.length === 0)
            return ts.emptyArray;
        var last = array[0];
        var deduplicated = [last];
        for (var i = 1; i < array.length; i++) {
            var next = array[i];
            switch (comparer(next, last)) {
                // equality comparison
                case true:
                // relational comparison
                // falls through
                case 0 /* EqualTo */:
                    continue;
                case -1 /* LessThan */:
                    // If `array` is sorted, `next` should **never** be less than `last`.
                    return ts.Debug.fail("Array is unsorted.");
            }
            deduplicated.push(last = next);
        }
        return deduplicated;
    }
    function insertSorted(array, insert, compare) {
        if (array.length === 0) {
            array.push(insert);
            return;
        }
        var insertIndex = binarySearch(array, insert, identity, compare);
        if (insertIndex < 0) {
            array.splice(~insertIndex, 0, insert);
        }
    }
    ts.insertSorted = insertSorted;
    function sortAndDeduplicate(array, comparer, equalityComparer) {
        return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive);
    }
    ts.sortAndDeduplicate = sortAndDeduplicate;
    function arrayIsEqualTo(array1, array2, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (!array1 || !array2) {
            return array1 === array2;
        }
        if (array1.length !== array2.length) {
            return false;
        }
        for (var i = 0; i < array1.length; i++) {
            if (!equalityComparer(array1[i], array2[i], i)) {
                return false;
            }
        }
        return true;
    }
    ts.arrayIsEqualTo = arrayIsEqualTo;
    function compact(array) {
        var result;
        if (array) {
            for (var i = 0; i < array.length; i++) {
                var v = array[i];
                if (result || !v) {
                    if (!result) {
                        result = array.slice(0, i);
                    }
                    if (v) {
                        result.push(v);
                    }
                }
            }
        }
        return result || array;
    }
    ts.compact = compact;
    /**
     * Gets the relative complement of `arrayA` with respect to `arrayB`, returning the elements that
     * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted
     * based on the provided comparer.
     */
    function relativeComplement(arrayA, arrayB, comparer) {
        if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0)
            return arrayB;
        var result = [];
        loopB: for (var offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) {
            if (offsetB > 0) {
                // Ensure `arrayB` is properly sorted.
                ts.Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), 0 /* EqualTo */);
            }
            loopA: for (var startA = offsetA; offsetA < arrayA.length; offsetA++) {
                if (offsetA > startA) {
                    // Ensure `arrayA` is properly sorted. We only need to perform this check if
                    // `offsetA` has changed since we entered the loop.
                    ts.Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), 0 /* EqualTo */);
                }
                switch (comparer(arrayB[offsetB], arrayA[offsetA])) {
                    case -1 /* LessThan */:
                        // If B is less than A, B does not exist in arrayA. Add B to the result and
                        // move to the next element in arrayB without changing the current position
                        // in arrayA.
                        result.push(arrayB[offsetB]);
                        continue loopB;
                    case 0 /* EqualTo */:
                        // If B is equal to A, B exists in arrayA. Move to the next element in
                        // arrayB without adding B to the result or changing the current position
                        // in arrayA.
                        continue loopB;
                    case 1 /* GreaterThan */:
                        // If B is greater than A, we need to keep looking for B in arrayA. Move to
                        // the next element in arrayA and recheck.
                        continue loopA;
                }
            }
        }
        return result;
    }
    ts.relativeComplement = relativeComplement;
    function sum(array, prop) {
        var result = 0;
        for (var _i = 0, array_5 = array; _i < array_5.length; _i++) {
            var v = array_5[_i];
            result += v[prop];
        }
        return result;
    }
    ts.sum = sum;
    function append(to, value) {
        if (value === undefined)
            return to;
        if (to === undefined)
            return [value];
        to.push(value);
        return to;
    }
    ts.append = append;
    function combine(xs, ys) {
        if (xs === undefined)
            return ys;
        if (ys === undefined)
            return xs;
        if (isArray(xs))
            return isArray(ys) ? concatenate(xs, ys) : append(xs, ys);
        if (isArray(ys))
            return append(ys, xs);
        return [xs, ys];
    }
    ts.combine = combine;
    /**
     * Gets the actual offset into an array for a relative offset. Negative offsets indicate a
     * position offset from the end of the array.
     */
    function toOffset(array, offset) {
        return offset < 0 ? array.length + offset : offset;
    }
    function addRange(to, from, start, end) {
        if (from === undefined || from.length === 0)
            return to;
        if (to === undefined)
            return from.slice(start, end);
        start = start === undefined ? 0 : toOffset(from, start);
        end = end === undefined ? from.length : toOffset(from, end);
        for (var i = start; i < end && i < from.length; i++) {
            if (from[i] !== undefined) {
                to.push(from[i]);
            }
        }
        return to;
    }
    ts.addRange = addRange;
    /**
     * @return Whether the value was added.
     */
    function pushIfUnique(array, toAdd, equalityComparer) {
        if (contains(array, toAdd, equalityComparer)) {
            return false;
        }
        else {
            array.push(toAdd);
            return true;
        }
    }
    ts.pushIfUnique = pushIfUnique;
    /**
     * Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array.
     */
    function appendIfUnique(array, toAdd, equalityComparer) {
        if (array) {
            pushIfUnique(array, toAdd, equalityComparer);
            return array;
        }
        else {
            return [toAdd];
        }
    }
    ts.appendIfUnique = appendIfUnique;
    function stableSortIndices(array, indices, comparer) {
        // sort indices by value then position
        indices.sort(function (x, y) { return comparer(array[x], array[y]) || compareValues(x, y); });
    }
    /**
     * Returns a new sorted array.
     */
    function sort(array, comparer) {
        return (array.length === 0 ? array : array.slice().sort(comparer));
    }
    ts.sort = sort;
    function arrayIterator(array) {
        var i = 0;
        return { next: function () {
                if (i === array.length) {
                    return { value: undefined, done: true };
                }
                else {
                    i++;
                    return { value: array[i - 1], done: false };
                }
            } };
    }
    ts.arrayIterator = arrayIterator;
    function arrayReverseIterator(array) {
        var i = array.length;
        return {
            next: function () {
                if (i === 0) {
                    return { value: undefined, done: true };
                }
                else {
                    i--;
                    return { value: array[i], done: false };
                }
            }
        };
    }
    ts.arrayReverseIterator = arrayReverseIterator;
    /**
     * Stable sort of an array. Elements equal to each other maintain their relative position in the array.
     */
    function stableSort(array, comparer) {
        var indices = indicesOf(array);
        stableSortIndices(array, indices, comparer);
        return indices.map(function (i) { return array[i]; });
    }
    ts.stableSort = stableSort;
    function rangeEquals(array1, array2, pos, end) {
        while (pos < end) {
            if (array1[pos] !== array2[pos]) {
                return false;
            }
            pos++;
        }
        return true;
    }
    ts.rangeEquals = rangeEquals;
    /**
     * Returns the element at a specific offset in an array if non-empty, `undefined` otherwise.
     * A negative offset indicates the element should be retrieved from the end of the array.
     */
    function elementAt(array, offset) {
        if (array) {
            offset = toOffset(array, offset);
            if (offset < array.length) {
                return array[offset];
            }
        }
        return undefined;
    }
    ts.elementAt = elementAt;
    /**
     * Returns the first element of an array if non-empty, `undefined` otherwise.
     */
    function firstOrUndefined(array) {
        return array.length === 0 ? undefined : array[0];
    }
    ts.firstOrUndefined = firstOrUndefined;
    function first(array) {
        ts.Debug.assert(array.length !== 0);
        return array[0];
    }
    ts.first = first;
    /**
     * Returns the last element of an array if non-empty, `undefined` otherwise.
     */
    function lastOrUndefined(array) {
        return array.length === 0 ? undefined : array[array.length - 1];
    }
    ts.lastOrUndefined = lastOrUndefined;
    function last(array) {
        ts.Debug.assert(array.length !== 0);
        return array[array.length - 1];
    }
    ts.last = last;
    /**
     * Returns the only element of an array if it contains only one element, `undefined` otherwise.
     */
    function singleOrUndefined(array) {
        return array && array.length === 1
            ? array[0]
            : undefined;
    }
    ts.singleOrUndefined = singleOrUndefined;
    function singleOrMany(array) {
        return array && array.length === 1
            ? array[0]
            : array;
    }
    ts.singleOrMany = singleOrMany;
    function replaceElement(array, index, value) {
        var result = array.slice(0);
        result[index] = value;
        return result;
    }
    ts.replaceElement = replaceElement;
    /**
     * Performs a binary search, finding the index at which `value` occurs in `array`.
     * If no such index is found, returns the 2's-complement of first index at which
     * `array[index]` exceeds `value`.
     * @param array A sorted array whose first element must be no larger than number
     * @param value The value to be searched for in the array.
     * @param keySelector A callback used to select the search key from `value` and each element of
     * `array`.
     * @param keyComparer A callback used to compare two keys in a sorted array.
     * @param offset An offset into `array` at which to start the search.
     */
    function binarySearch(array, value, keySelector, keyComparer, offset) {
        return binarySearchKey(array, keySelector(value), keySelector, keyComparer, offset);
    }
    ts.binarySearch = binarySearch;
    /**
     * Performs a binary search, finding the index at which an object with `key` occurs in `array`.
     * If no such index is found, returns the 2's-complement of first index at which
     * `array[index]` exceeds `key`.
     * @param array A sorted array whose first element must be no larger than number
     * @param key The key to be searched for in the array.
     * @param keySelector A callback used to select the search key from each element of `array`.
     * @param keyComparer A callback used to compare two keys in a sorted array.
     * @param offset An offset into `array` at which to start the search.
     */
    function binarySearchKey(array, key, keySelector, keyComparer, offset) {
        if (!some(array)) {
            return -1;
        }
        var low = offset || 0;
        var high = array.length - 1;
        while (low <= high) {
            var middle = low + ((high - low) >> 1);
            var midKey = keySelector(array[middle]);
            switch (keyComparer(midKey, key)) {
                case -1 /* LessThan */:
                    low = middle + 1;
                    break;
                case 0 /* EqualTo */:
                    return middle;
                case 1 /* GreaterThan */:
                    high = middle - 1;
                    break;
            }
        }
        return ~low;
    }
    ts.binarySearchKey = binarySearchKey;
    function reduceLeft(array, f, initial, start, count) {
        if (array && array.length > 0) {
            var size = array.length;
            if (size > 0) {
                var pos = start === undefined || start < 0 ? 0 : start;
                var end = count === undefined || pos + count > size - 1 ? size - 1 : pos + count;
                var result = void 0;
                if (arguments.length <= 2) {
                    result = array[pos];
                    pos++;
                }
                else {
                    result = initial;
                }
                while (pos <= end) {
                    result = f(result, array[pos], pos);
                    pos++;
                }
                return result;
            }
        }
        return initial;
    }
    ts.reduceLeft = reduceLeft;
    var hasOwnProperty = Object.prototype.hasOwnProperty;
    /**
     * Indicates whether a map-like contains an own property with the specified key.
     *
     * @param map A map-like.
     * @param key A property key.
     */
    function hasProperty(map, key) {
        return hasOwnProperty.call(map, key);
    }
    ts.hasProperty = hasProperty;
    /**
     * Gets the value of an owned property in a map-like.
     *
     * @param map A map-like.
     * @param key A property key.
     */
    function getProperty(map, key) {
        return hasOwnProperty.call(map, key) ? map[key] : undefined;
    }
    ts.getProperty = getProperty;
    /**
     * Gets the owned, enumerable property keys of a map-like.
     */
    function getOwnKeys(map) {
        var keys = [];
        for (var key in map) {
            if (hasOwnProperty.call(map, key)) {
                keys.push(key);
            }
        }
        return keys;
    }
    ts.getOwnKeys = getOwnKeys;
    function getAllKeys(obj) {
        var result = [];
        do {
            var names = Object.getOwnPropertyNames(obj);
            for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
                var name = names_1[_i];
                pushIfUnique(result, name);
            }
        } while (obj = Object.getPrototypeOf(obj));
        return result;
    }
    ts.getAllKeys = getAllKeys;
    function getOwnValues(sparseArray) {
        var values = [];
        for (var key in sparseArray) {
            if (hasOwnProperty.call(sparseArray, key)) {
                values.push(sparseArray[key]);
            }
        }
        return values;
    }
    ts.getOwnValues = getOwnValues;
    function arrayFrom(iterator, map) {
        var result = [];
        for (var iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
            result.push(map ? map(iterResult.value) : iterResult.value);
        }
        return result;
    }
    ts.arrayFrom = arrayFrom;
    function assign(t) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
            var arg = args_1[_a];
            if (arg === undefined)
                continue;
            for (var p in arg) {
                if (hasProperty(arg, p)) {
                    t[p] = arg[p];
                }
            }
        }
        return t;
    }
    ts.assign = assign;
    /**
     * Performs a shallow equality comparison of the contents of two map-likes.
     *
     * @param left A map-like whose properties should be compared.
     * @param right A map-like whose properties should be compared.
     */
    function equalOwnProperties(left, right, equalityComparer) {
        if (equalityComparer === void 0) { equalityComparer = equateValues; }
        if (left === right)
            return true;
        if (!left || !right)
            return false;
        for (var key in left) {
            if (hasOwnProperty.call(left, key)) {
                if (!hasOwnProperty.call(right, key))
                    return false;
                if (!equalityComparer(left[key], right[key]))
                    return false;
            }
        }
        for (var key in right) {
            if (hasOwnProperty.call(right, key)) {
                if (!hasOwnProperty.call(left, key))
                    return false;
            }
        }
        return true;
    }
    ts.equalOwnProperties = equalOwnProperties;
    function arrayToMap(array, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = createMap();
        for (var _i = 0, array_6 = array; _i < array_6.length; _i++) {
            var value = array_6[_i];
            var key = makeKey(value);
            if (key !== undefined)
                result.set(key, makeValue(value));
        }
        return result;
    }
    ts.arrayToMap = arrayToMap;
    function arrayToNumericMap(array, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = [];
        for (var _i = 0, array_7 = array; _i < array_7.length; _i++) {
            var value = array_7[_i];
            result[makeKey(value)] = makeValue(value);
        }
        return result;
    }
    ts.arrayToNumericMap = arrayToNumericMap;
    function arrayToMultiMap(values, makeKey, makeValue) {
        if (makeValue === void 0) { makeValue = identity; }
        var result = createMultiMap();
        for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
            var value = values_1[_i];
            result.add(makeKey(value), makeValue(value));
        }
        return result;
    }
    ts.arrayToMultiMap = arrayToMultiMap;
    function group(values, getGroupId, resultSelector) {
        if (resultSelector === void 0) { resultSelector = identity; }
        return arrayFrom(arrayToMultiMap(values, getGroupId).values(), resultSelector);
    }
    ts.group = group;
    function clone(object) {
        var result = {};
        for (var id in object) {
            if (hasOwnProperty.call(object, id)) {
                result[id] = object[id];
            }
        }
        return result;
    }
    ts.clone = clone;
    /**
     * Creates a new object by adding the own properties of `second`, then the own properties of `first`.
     *
     * NOTE: This means that if a property exists in both `first` and `second`, the property in `first` will be chosen.
     */
    function extend(first, second) {
        var result = {};
        for (var id in second) {
            if (hasOwnProperty.call(second, id)) {
                result[id] = second[id];
            }
        }
        for (var id in first) {
            if (hasOwnProperty.call(first, id)) {
                result[id] = first[id];
            }
        }
        return result;
    }
    ts.extend = extend;
    function copyProperties(first, second) {
        for (var id in second) {
            if (hasOwnProperty.call(second, id)) {
                first[id] = second[id];
            }
        }
    }
    ts.copyProperties = copyProperties;
    function maybeBind(obj, fn) {
        return fn ? fn.bind(obj) : undefined;
    }
    ts.maybeBind = maybeBind;
    function mapMap(map, f) {
        var result = createMap();
        map.forEach(function (t, key) { return result.set.apply(result, (f(t, key))); });
        return result;
    }
    ts.mapMap = mapMap;
    function createMultiMap() {
        var map = createMap();
        map.add = multiMapAdd;
        map.remove = multiMapRemove;
        return map;
    }
    ts.createMultiMap = createMultiMap;
    function multiMapAdd(key, value) {
        var values = this.get(key);
        if (values) {
            values.push(value);
        }
        else {
            this.set(key, values = [value]);
        }
        return values;
    }
    function multiMapRemove(key, value) {
        var values = this.get(key);
        if (values) {
            unorderedRemoveItem(values, value);
            if (!values.length) {
                this.delete(key);
            }
        }
    }
    function createUnderscoreEscapedMultiMap() {
        return createMultiMap();
    }
    ts.createUnderscoreEscapedMultiMap = createUnderscoreEscapedMultiMap;
    /**
     * Tests whether a value is an array.
     */
    function isArray(value) {
        return Array.isArray ? Array.isArray(value) : value instanceof Array;
    }
    ts.isArray = isArray;
    function toArray(value) {
        return isArray(value) ? value : [value];
    }
    ts.toArray = toArray;
    /**
     * Tests whether a value is string
     */
    function isString(text) {
        return typeof text === "string";
    }
    ts.isString = isString;
    function isNumber(x) {
        return typeof x === "number";
    }
    ts.isNumber = isNumber;
    function tryCast(value, test) {
        return value !== undefined && test(value) ? value : undefined;
    }
    ts.tryCast = tryCast;
    function cast(value, test) {
        if (value !== undefined && test(value))
            return value;
        return ts.Debug.fail("Invalid cast. The supplied value " + value + " did not pass the test '" + ts.Debug.getFunctionName(test) + "'.");
    }
    ts.cast = cast;
    /** Does nothing. */
    function noop(_) { }
    ts.noop = noop;
    /** Do nothing and return false */
    function returnFalse() { return false; }
    ts.returnFalse = returnFalse;
    /** Do nothing and return true */
    function returnTrue() { return true; }
    ts.returnTrue = returnTrue;
    /** Do nothing and return undefined */
    function returnUndefined() { return undefined; }
    ts.returnUndefined = returnUndefined;
    /** Returns its argument. */
    function identity(x) { return x; }
    ts.identity = identity;
    /** Returns lower case string */
    function toLowerCase(x) { return x.toLowerCase(); }
    ts.toLowerCase = toLowerCase;
    // We convert the file names to lower case as key for file name on case insensitive file system
    // While doing so we need to handle special characters (eg \u0130) to ensure that we dont convert
    // it to lower case, fileName with its lowercase form can exist along side it.
    // Handle special characters and make those case sensitive instead
    //
    // |-#--|-Unicode--|-Char code-|-Desc-------------------------------------------------------------------|
    // | 1. | i        | 105       | Ascii i                                                                |
    // | 2. | I        | 73        | Ascii I                                                                |
    // |-------- Special characters ------------------------------------------------------------------------|
    // | 3. | \u0130   | 304       | Uppper case I with dot above                                           |
    // | 4. | i,\u0307 | 105,775   | i, followed by 775: Lower case of (3rd item)                           |
    // | 5. | I,\u0307 | 73,775    | I, followed by 775: Upper case of (4th item), lower case is (4th item) |
    // | 6. | \u0131   | 305       | Lower case i without dot, upper case is I (2nd item)                   |
    // | 7. | \u00DF   | 223       | Lower case sharp s                                                     |
    //
    // Because item 3 is special where in its lowercase character has its own
    // upper case form we cant convert its case.
    // Rest special characters are either already in lower case format or
    // they have corresponding upper case character so they dont need special handling
    //
    // But to avoid having to do string building for most common cases, also ignore
    // a-z, 0-9, \u0131, \u00DF, \, /, ., : and space
    var fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_\. ]+/g;
    /**
     * Case insensitive file systems have descripencies in how they handle some characters (eg. turkish Upper case I with dot on top - \u0130)
     * This function is used in places where we want to make file name as a key on these systems
     * It is possible on mac to be able to refer to file name with I with dot on top as a fileName with its lower case form
     * But on windows we cannot. Windows can have fileName with I with dot on top next to its lower case and they can not each be referred with the lowercase forms
     * Technically we would want this function to be platform sepcific as well but
     * our api has till now only taken caseSensitive as the only input and just for some characters we dont want to update API and ensure all customers use those api
     * We could use upper case and we would still need to deal with the descripencies but
     * we want to continue using lower case since in most cases filenames are lowercasewe and wont need any case changes and avoid having to store another string for the key
     * So for this function purpose, we go ahead and assume character I with dot on top it as case sensitive since its very unlikely to use lower case form of that special character
     */
    function toFileNameLowerCase(x) {
        return fileNameLowerCaseRegExp.test(x) ?
            x.replace(fileNameLowerCaseRegExp, toLowerCase) :
            x;
    }
    ts.toFileNameLowerCase = toFileNameLowerCase;
    /** Throws an error because a function is not implemented. */
    function notImplemented() {
        throw new Error("Not implemented");
    }
    ts.notImplemented = notImplemented;
    function memoize(callback) {
        var value;
        return function () {
            if (callback) {
                value = callback();
                callback = undefined;
            }
            return value;
        };
    }
    ts.memoize = memoize;
    function compose(a, b, c, d, e) {
        if (!!e) {
            var args_2 = [];
            for (var i = 0; i < arguments.length; i++) {
                args_2[i] = arguments[i];
            }
            return function (t) { return reduceLeft(args_2, function (u, f) { return f(u); }, t); };
        }
        else if (d) {
            return function (t) { return d(c(b(a(t)))); };
        }
        else if (c) {
            return function (t) { return c(b(a(t))); };
        }
        else if (b) {
            return function (t) { return b(a(t)); };
        }
        else if (a) {
            return function (t) { return a(t); };
        }
        else {
            return function (t) { return t; };
        }
    }
    ts.compose = compose;
    var AssertionLevel;
    (function (AssertionLevel) {
        AssertionLevel[AssertionLevel["None"] = 0] = "None";
        AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal";
        AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive";
        AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive";
    })(AssertionLevel = ts.AssertionLevel || (ts.AssertionLevel = {}));
    function equateValues(a, b) {
        return a === b;
    }
    ts.equateValues = equateValues;
    /**
     * Compare the equality of two strings using a case-sensitive ordinal comparison.
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point after applying `toUpperCase` to each string. We always map both
     * strings to their upper-case form as some unicode characters do not properly round-trip to
     * lowercase (such as `ẞ` (German sharp capital s)).
     */
    function equateStringsCaseInsensitive(a, b) {
        return a === b
            || a !== undefined
                && b !== undefined
                && a.toUpperCase() === b.toUpperCase();
    }
    ts.equateStringsCaseInsensitive = equateStringsCaseInsensitive;
    /**
     * Compare the equality of two strings using a case-sensitive ordinal comparison.
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the
     * integer value of each code-point.
     */
    function equateStringsCaseSensitive(a, b) {
        return equateValues(a, b);
    }
    ts.equateStringsCaseSensitive = equateStringsCaseSensitive;
    function compareComparableValues(a, b) {
        return a === b ? 0 /* EqualTo */ :
            a === undefined ? -1 /* LessThan */ :
                b === undefined ? 1 /* GreaterThan */ :
                    a < b ? -1 /* LessThan */ :
                        1 /* GreaterThan */;
    }
    /**
     * Compare two numeric values for their order relative to each other.
     * To compare strings, use any of the `compareStrings` functions.
     */
    function compareValues(a, b) {
        return compareComparableValues(a, b);
    }
    ts.compareValues = compareValues;
    /**
     * Compare two TextSpans, first by `start`, then by `length`.
     */
    function compareTextSpans(a, b) {
        return compareValues(a === null || a === void 0 ? void 0 : a.start, b === null || b === void 0 ? void 0 : b.start) || compareValues(a === null || a === void 0 ? void 0 : a.length, b === null || b === void 0 ? void 0 : b.length);
    }
    ts.compareTextSpans = compareTextSpans;
    function min(a, b, compare) {
        return compare(a, b) === -1 /* LessThan */ ? a : b;
    }
    ts.min = min;
    /**
     * Compare two strings using a case-insensitive ordinal comparison.
     *
     * Ordinal comparisons are based on the difference between the unicode code points of both
     * strings. Characters with multiple unicode representations are considered unequal. Ordinal
     * comparisons provide predictable ordering, but place "a" after "B".
     *
     * Case-insensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point after applying `toUpperCase` to each string. We always map both
     * strings to their upper-case form as some unicode characters do not properly round-trip to
     * lowercase (such as `áºž` (German sharp capital s)).
     */
    function compareStringsCaseInsensitive(a, b) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        a = a.toUpperCase();
        b = b.toUpperCase();
        return a < b ? -1 /* LessThan */ : a > b ? 1 /* GreaterThan */ : 0 /* EqualTo */;
    }
    ts.compareStringsCaseInsensitive = compareStringsCaseInsensitive;
    /**
     * Compare two strings using a case-sensitive ordinal comparison.
     *
     * Ordinal comparisons are based on the difference between the unicode code points of both
     * strings. Characters with multiple unicode representations are considered unequal. Ordinal
     * comparisons provide predictable ordering, but place "a" after "B".
     *
     * Case-sensitive comparisons compare both strings one code-point at a time using the integer
     * value of each code-point.
     */
    function compareStringsCaseSensitive(a, b) {
        return compareComparableValues(a, b);
    }
    ts.compareStringsCaseSensitive = compareStringsCaseSensitive;
    function getStringComparer(ignoreCase) {
        return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive;
    }
    ts.getStringComparer = getStringComparer;
    /**
     * Creates a string comparer for use with string collation in the UI.
     */
    var createUIStringComparer = (function () {
        var defaultComparer;
        var enUSComparer;
        var stringComparerFactory = getStringComparerFactory();
        return createStringComparer;
        function compareWithCallback(a, b, comparer) {
            if (a === b)
                return 0 /* EqualTo */;
            if (a === undefined)
                return -1 /* LessThan */;
            if (b === undefined)
                return 1 /* GreaterThan */;
            var value = comparer(a, b);
            return value < 0 ? -1 /* LessThan */ : value > 0 ? 1 /* GreaterThan */ : 0 /* EqualTo */;
        }
        function createIntlCollatorStringComparer(locale) {
            // Intl.Collator.prototype.compare is bound to the collator. See NOTE in
            // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare
            var comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: "variant" }).compare;
            return function (a, b) { return compareWithCallback(a, b, comparer); };
        }
        function createLocaleCompareStringComparer(locale) {
            // if the locale is not the default locale (`undefined`), use the fallback comparer.
            if (locale !== undefined)
                return createFallbackStringComparer();
            return function (a, b) { return compareWithCallback(a, b, compareStrings); };
            function compareStrings(a, b) {
                return a.localeCompare(b);
            }
        }
        function createFallbackStringComparer() {
            // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b".
            // We first sort case insensitively.  So "Aaa" will come before "baa".
            // Then we sort case sensitively, so "aaa" will come before "Aaa".
            //
            // For case insensitive comparisons we always map both strings to their
            // upper-case form as some unicode characters do not properly round-trip to
            // lowercase (such as `áºž` (German sharp capital s)).
            return function (a, b) { return compareWithCallback(a, b, compareDictionaryOrder); };
            function compareDictionaryOrder(a, b) {
                return compareStrings(a.toUpperCase(), b.toUpperCase()) || compareStrings(a, b);
            }
            function compareStrings(a, b) {
                return a < b ? -1 /* LessThan */ : a > b ? 1 /* GreaterThan */ : 0 /* EqualTo */;
            }
        }
        function getStringComparerFactory() {
            // If the host supports Intl, we use it for comparisons using the default locale.
            if (typeof Intl === "object" && typeof Intl.Collator === "function") {
                return createIntlCollatorStringComparer;
            }
            // If the host does not support Intl, we fall back to localeCompare.
            // localeCompare in Node v0.10 is just an ordinal comparison, so don't use it.
            if (typeof String.prototype.localeCompare === "function" &&
                typeof String.prototype.toLocaleUpperCase === "function" &&
                "a".localeCompare("B") < 0) {
                return createLocaleCompareStringComparer;
            }
            // Otherwise, fall back to ordinal comparison:
            return createFallbackStringComparer;
        }
        function createStringComparer(locale) {
            // Hold onto common string comparers. This avoids constantly reallocating comparers during
            // tests.
            if (locale === undefined) {
                return defaultComparer || (defaultComparer = stringComparerFactory(locale));
            }
            else if (locale === "en-US") {
                return enUSComparer || (enUSComparer = stringComparerFactory(locale));
            }
            else {
                return stringComparerFactory(locale);
            }
        }
    })();
    var uiComparerCaseSensitive;
    var uiLocale;
    function getUILocale() {
        return uiLocale;
    }
    ts.getUILocale = getUILocale;
    function setUILocale(value) {
        if (uiLocale !== value) {
            uiLocale = value;
            uiComparerCaseSensitive = undefined;
        }
    }
    ts.setUILocale = setUILocale;
    /**
     * Compare two strings in a using the case-sensitive sort behavior of the UI locale.
     *
     * Ordering is not predictable between different host locales, but is best for displaying
     * ordered data for UI presentation. Characters with multiple unicode representations may
     * be considered equal.
     *
     * Case-sensitive comparisons compare strings that differ in base characters, or
     * accents/diacritic marks, or case as unequal.
     */
    function compareStringsCaseSensitiveUI(a, b) {
        var comparer = uiComparerCaseSensitive || (uiComparerCaseSensitive = createUIStringComparer(uiLocale));
        return comparer(a, b);
    }
    ts.compareStringsCaseSensitiveUI = compareStringsCaseSensitiveUI;
    function compareProperties(a, b, key, comparer) {
        return a === b ? 0 /* EqualTo */ :
            a === undefined ? -1 /* LessThan */ :
                b === undefined ? 1 /* GreaterThan */ :
                    comparer(a[key], b[key]);
    }
    ts.compareProperties = compareProperties;
    /** True is greater than false. */
    function compareBooleans(a, b) {
        return compareValues(a ? 1 : 0, b ? 1 : 0);
    }
    ts.compareBooleans = compareBooleans;
    /**
     * Given a name and a list of names that are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
     * Names less than length 3 only check for case-insensitive equality, not Levenshtein distance.
     *
     * If there is a candidate that's the same except for case, return that.
     * If there is a candidate that's within one edit of the name, return that.
     * Otherwise, return the candidate with the smallest Levenshtein distance,
     *    except for candidates:
     *      * With no name
     *      * Whose length differs from the target name by more than 0.34 of the length of the name.
     *      * Whose levenshtein distance is more than 0.4 of the length of the name
     *        (0.4 allows 1 substitution/transposition for every 5 characters,
     *         and 1 insertion/deletion at 3 characters)
     */
    function getSpellingSuggestion(name, candidates, getName) {
        var maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34));
        var bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result isn't better than this, don't bother.
        var bestCandidate;
        var justCheckExactMatches = false;
        var nameLowerCase = name.toLowerCase();
        for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
            var candidate = candidates_1[_i];
            var candidateName = getName(candidate);
            if (candidateName !== undefined && Math.abs(candidateName.length - nameLowerCase.length) <= maximumLengthDifference) {
                var candidateNameLowerCase = candidateName.toLowerCase();
                if (candidateNameLowerCase === nameLowerCase) {
                    if (candidateName === name) {
                        continue;
                    }
                    return candidate;
                }
                if (justCheckExactMatches) {
                    continue;
                }
                if (candidateName.length < 3) {
                    // Don't bother, user would have noticed a 2-character name having an extra character
                    continue;
                }
                // Only care about a result better than the best so far.
                var distance = levenshteinWithMax(nameLowerCase, candidateNameLowerCase, bestDistance - 1);
                if (distance === undefined) {
                    continue;
                }
                if (distance < 3) {
                    justCheckExactMatches = true;
                    bestCandidate = candidate;
                }
                else {
                    ts.Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined
                    bestDistance = distance;
                    bestCandidate = candidate;
                }
            }
        }
        return bestCandidate;
    }
    ts.getSpellingSuggestion = getSpellingSuggestion;
    function levenshteinWithMax(s1, s2, max) {
        var previous = new Array(s2.length + 1);
        var current = new Array(s2.length + 1);
        /** Represents any value > max. We don't care about the particular value. */
        var big = max + 1;
        for (var i = 0; i <= s2.length; i++) {
            previous[i] = i;
        }
        for (var i = 1; i <= s1.length; i++) {
            var c1 = s1.charCodeAt(i - 1);
            var minJ = i > max ? i - max : 1;
            var maxJ = s2.length > max + i ? max + i : s2.length;
            current[0] = i;
            /** Smallest value of the matrix in the ith column. */
            var colMin = i;
            for (var j = 1; j < minJ; j++) {
                current[j] = big;
            }
            for (var j = minJ; j <= maxJ; j++) {
                var dist = c1 === s2.charCodeAt(j - 1)
                    ? previous[j - 1]
                    : Math.min(/*delete*/ previous[j] + 1, /*insert*/ current[j - 1] + 1, /*substitute*/ previous[j - 1] + 2);
                current[j] = dist;
                colMin = Math.min(colMin, dist);
            }
            for (var j = maxJ + 1; j <= s2.length; j++) {
                current[j] = big;
            }
            if (colMin > max) {
                // Give up -- everything in this column is > max and it can't get better in future columns.
                return undefined;
            }
            var temp = previous;
            previous = current;
            current = temp;
        }
        var res = previous[s2.length];
        return res > max ? undefined : res;
    }
    function endsWith(str, suffix) {
        var expectedPos = str.length - suffix.length;
        return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
    }
    ts.endsWith = endsWith;
    function removeSuffix(str, suffix) {
        return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : str;
    }
    ts.removeSuffix = removeSuffix;
    function tryRemoveSuffix(str, suffix) {
        return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : undefined;
    }
    ts.tryRemoveSuffix = tryRemoveSuffix;
    function stringContains(str, substring) {
        return str.indexOf(substring) !== -1;
    }
    ts.stringContains = stringContains;
    /**
     * Takes a string like "jquery-min.4.2.3" and returns "jquery"
     */
    function removeMinAndVersionNumbers(fileName) {
        // Match a "." or "-" followed by a version number or 'min' at the end of the name
        var trailingMinOrVersion = /[.-]((min)|(\d+(\.\d+)*))$/;
        // The "min" or version may both be present, in either order, so try applying the above twice.
        return fileName.replace(trailingMinOrVersion, "").replace(trailingMinOrVersion, "");
    }
    ts.removeMinAndVersionNumbers = removeMinAndVersionNumbers;
    /** Remove an item from an array, moving everything to its right one space left. */
    function orderedRemoveItem(array, item) {
        for (var i = 0; i < array.length; i++) {
            if (array[i] === item) {
                orderedRemoveItemAt(array, i);
                return true;
            }
        }
        return false;
    }
    ts.orderedRemoveItem = orderedRemoveItem;
    /** Remove an item by index from an array, moving everything to its right one space left. */
    function orderedRemoveItemAt(array, index) {
        // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
        for (var i = index; i < array.length - 1; i++) {
            array[i] = array[i + 1];
        }
        array.pop();
    }
    ts.orderedRemoveItemAt = orderedRemoveItemAt;
    function unorderedRemoveItemAt(array, index) {
        // Fill in the "hole" left at `index`.
        array[index] = array[array.length - 1];
        array.pop();
    }
    ts.unorderedRemoveItemAt = unorderedRemoveItemAt;
    /** Remove the *first* occurrence of `item` from the array. */
    function unorderedRemoveItem(array, item) {
        return unorderedRemoveFirstItemWhere(array, function (element) { return element === item; });
    }
    ts.unorderedRemoveItem = unorderedRemoveItem;
    /** Remove the *first* element satisfying `predicate`. */
    function unorderedRemoveFirstItemWhere(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i])) {
                unorderedRemoveItemAt(array, i);
                return true;
            }
        }
        return false;
    }
    function createGetCanonicalFileName(useCaseSensitiveFileNames) {
        return useCaseSensitiveFileNames ? identity : toFileNameLowerCase;
    }
    ts.createGetCanonicalFileName = createGetCanonicalFileName;
    function patternText(_a) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return prefix + "*" + suffix;
    }
    ts.patternText = patternText;
    /**
     * Given that candidate matches pattern, returns the text matching the '*'.
     * E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar"
     */
    function matchedText(pattern, candidate) {
        ts.Debug.assert(isPatternMatch(pattern, candidate));
        return candidate.substring(pattern.prefix.length, candidate.length - pattern.suffix.length);
    }
    ts.matchedText = matchedText;
    /** Return the object corresponding to the best pattern to match `candidate`. */
    function findBestPatternMatch(values, getPattern, candidate) {
        var matchedValue;
        // use length of prefix as betterness criteria
        var longestMatchPrefixLength = -1;
        for (var _i = 0, values_2 = values; _i < values_2.length; _i++) {
            var v = values_2[_i];
            var pattern = getPattern(v);
            if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) {
                longestMatchPrefixLength = pattern.prefix.length;
                matchedValue = v;
            }
        }
        return matchedValue;
    }
    ts.findBestPatternMatch = findBestPatternMatch;
    function startsWith(str, prefix) {
        return str.lastIndexOf(prefix, 0) === 0;
    }
    ts.startsWith = startsWith;
    function removePrefix(str, prefix) {
        return startsWith(str, prefix) ? str.substr(prefix.length) : str;
    }
    ts.removePrefix = removePrefix;
    function tryRemovePrefix(str, prefix, getCanonicalFileName) {
        if (getCanonicalFileName === void 0) { getCanonicalFileName = identity; }
        return startsWith(getCanonicalFileName(str), getCanonicalFileName(prefix)) ? str.substring(prefix.length) : undefined;
    }
    ts.tryRemovePrefix = tryRemovePrefix;
    function isPatternMatch(_a, candidate) {
        var prefix = _a.prefix, suffix = _a.suffix;
        return candidate.length >= prefix.length + suffix.length &&
            startsWith(candidate, prefix) &&
            endsWith(candidate, suffix);
    }
    function and(f, g) {
        return function (arg) { return f(arg) && g(arg); };
    }
    ts.and = and;
    function or() {
        var fs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            fs[_i] = arguments[_i];
        }
        return function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            for (var _a = 0, fs_1 = fs; _a < fs_1.length; _a++) {
                var f = fs_1[_a];
                if (f.apply(void 0, args)) {
                    return true;
                }
            }
            return false;
        };
    }
    ts.or = or;
    function not(fn) {
        return function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            return !fn.apply(void 0, args);
        };
    }
    ts.not = not;
    function assertType(_) { }
    ts.assertType = assertType;
    function singleElementArray(t) {
        return t === undefined ? undefined : [t];
    }
    ts.singleElementArray = singleElementArray;
    function enumerateInsertsAndDeletes(newItems, oldItems, comparer, inserted, deleted, unchanged) {
        unchanged = unchanged || noop;
        var newIndex = 0;
        var oldIndex = 0;
        var newLen = newItems.length;
        var oldLen = oldItems.length;
        while (newIndex < newLen && oldIndex < oldLen) {
            var newItem = newItems[newIndex];
            var oldItem = oldItems[oldIndex];
            var compareResult = comparer(newItem, oldItem);
            if (compareResult === -1 /* LessThan */) {
                inserted(newItem);
                newIndex++;
            }
            else if (compareResult === 1 /* GreaterThan */) {
                deleted(oldItem);
                oldIndex++;
            }
            else {
                unchanged(oldItem, newItem);
                newIndex++;
                oldIndex++;
            }
        }
        while (newIndex < newLen) {
            inserted(newItems[newIndex++]);
        }
        while (oldIndex < oldLen) {
            deleted(oldItems[oldIndex++]);
        }
    }
    ts.enumerateInsertsAndDeletes = enumerateInsertsAndDeletes;
    function fill(length, cb) {
        var result = Array(length);
        for (var i = 0; i < length; i++) {
            result[i] = cb(i);
        }
        return result;
    }
    ts.fill = fill;
    function cartesianProduct(arrays) {
        var result = [];
        cartesianProductWorker(arrays, result, /*outer*/ undefined, 0);
        return result;
    }
    ts.cartesianProduct = cartesianProduct;
    function cartesianProductWorker(arrays, result, outer, index) {
        for (var _i = 0, _a = arrays[index]; _i < _a.length; _i++) {
            var element = _a[_i];
            var inner = void 0;
            if (outer) {
                inner = outer.slice();
                inner.push(element);
            }
            else {
                inner = [element];
            }
            if (index === arrays.length - 1) {
                result.push(inner);
            }
            else {
                cartesianProductWorker(arrays, result, inner, index + 1);
            }
        }
    }
    function padLeft(s, length) {
        while (s.length < length) {
            s = " " + s;
        }
        return s;
    }
    ts.padLeft = padLeft;
    function padRight(s, length) {
        while (s.length < length) {
            s = s + " ";
        }
        return s;
    }
    ts.padRight = padRight;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var Debug;
    (function (Debug) {
        var currentAssertionLevel = 0 /* None */;
        // eslint-disable-next-line prefer-const
        Debug.isDebugging = false;
        var assertionCache = {};
        function getAssertionLevel() {
            return currentAssertionLevel;
        }
        Debug.getAssertionLevel = getAssertionLevel;
        function setAssertionLevel(level) {
            var prevAssertionLevel = currentAssertionLevel;
            currentAssertionLevel = level;
            if (level > prevAssertionLevel) {
                // restore assertion functions for the current assertion level (see `shouldAssertFunction`).
                for (var _i = 0, _a = ts.getOwnKeys(assertionCache); _i < _a.length; _i++) {
                    var key = _a[_i];
                    var cachedFunc = assertionCache[key];
                    if (cachedFunc !== undefined && Debug[key] !== cachedFunc.assertion && level >= cachedFunc.level) {
                        Debug[key] = cachedFunc;
                        assertionCache[key] = undefined;
                    }
                }
            }
        }
        Debug.setAssertionLevel = setAssertionLevel;
        function shouldAssert(level) {
            return currentAssertionLevel >= level;
        }
        Debug.shouldAssert = shouldAssert;
        /**
         * Tests whether an assertion function should be executed. If it shouldn't, it is cached and replaced with `ts.noop`.
         * Replaced assertion functions are restored when `Debug.setAssertionLevel` is set to a high enough level.
         * @param level The minimum assertion level required.
         * @param name The name of the current assertion function.
         */
        function shouldAssertFunction(level, name) {
            if (!shouldAssert(level)) {
                assertionCache[name] = { level: level, assertion: Debug[name] };
                Debug[name] = ts.noop;
                return false;
            }
            return true;
        }
        function fail(message, stackCrawlMark) {
            debugger;
            var e = new Error(message ? "Debug Failure. " + message : "Debug Failure.");
            if (Error.captureStackTrace) {
                Error.captureStackTrace(e, stackCrawlMark || fail);
            }
            throw e;
        }
        Debug.fail = fail;
        function failBadSyntaxKind(node, message, stackCrawlMark) {
            return fail((message || "Unexpected node.") + "\r\nNode " + formatSyntaxKind(node.kind) + " was unexpected.", stackCrawlMark || failBadSyntaxKind);
        }
        Debug.failBadSyntaxKind = failBadSyntaxKind;
        function assert(expression, message, verboseDebugInfo, stackCrawlMark) {
            if (!expression) {
                message = message ? "False expression: " + message : "False expression.";
                if (verboseDebugInfo) {
                    message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo());
                }
                fail(message, stackCrawlMark || assert);
            }
        }
        Debug.assert = assert;
        function assertEqual(a, b, msg, msg2, stackCrawlMark) {
            if (a !== b) {
                var message = msg ? msg2 ? msg + " " + msg2 : msg : "";
                fail("Expected " + a + " === " + b + ". " + message, stackCrawlMark || assertEqual);
            }
        }
        Debug.assertEqual = assertEqual;
        function assertLessThan(a, b, msg, stackCrawlMark) {
            if (a >= b) {
                fail("Expected " + a + " < " + b + ". " + (msg || ""), stackCrawlMark || assertLessThan);
            }
        }
        Debug.assertLessThan = assertLessThan;
        function assertLessThanOrEqual(a, b, stackCrawlMark) {
            if (a > b) {
                fail("Expected " + a + " <= " + b, stackCrawlMark || assertLessThanOrEqual);
            }
        }
        Debug.assertLessThanOrEqual = assertLessThanOrEqual;
        function assertGreaterThanOrEqual(a, b, stackCrawlMark) {
            if (a < b) {
                fail("Expected " + a + " >= " + b, stackCrawlMark || assertGreaterThanOrEqual);
            }
        }
        Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual;
        function assertIsDefined(value, message, stackCrawlMark) {
            // eslint-disable-next-line no-null/no-null
            if (value === undefined || value === null) {
                fail(message, stackCrawlMark || assertIsDefined);
            }
        }
        Debug.assertIsDefined = assertIsDefined;
        function checkDefined(value, message, stackCrawlMark) {
            assertIsDefined(value, message, stackCrawlMark || checkDefined);
            return value;
        }
        Debug.checkDefined = checkDefined;
        /**
         * @deprecated Use `checkDefined` to check whether a value is defined inline. Use `assertIsDefined` to check whether
         * a value is defined at the statement level.
         */
        Debug.assertDefined = checkDefined;
        function assertEachIsDefined(value, message, stackCrawlMark) {
            for (var _i = 0, value_1 = value; _i < value_1.length; _i++) {
                var v = value_1[_i];
                assertIsDefined(v, message, stackCrawlMark || assertEachIsDefined);
            }
        }
        Debug.assertEachIsDefined = assertEachIsDefined;
        function checkEachDefined(value, message, stackCrawlMark) {
            assertEachIsDefined(value, message, stackCrawlMark || checkEachDefined);
            return value;
        }
        Debug.checkEachDefined = checkEachDefined;
        /**
         * @deprecated Use `checkEachDefined` to check whether the elements of an array are defined inline. Use `assertEachIsDefined` to check whether
         * the elements of an array are defined at the statement level.
         */
        Debug.assertEachDefined = checkEachDefined;
        function assertNever(member, message, stackCrawlMark) {
            if (message === void 0) { message = "Illegal value:"; }
            var detail = typeof member === "object" && ts.hasProperty(member, "kind") && ts.hasProperty(member, "pos") && formatSyntaxKind ? "SyntaxKind: " + formatSyntaxKind(member.kind) : JSON.stringify(member);
            return fail(message + " " + detail, stackCrawlMark || assertNever);
        }
        Debug.assertNever = assertNever;
        function assertEachNode(nodes, test, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertEachNode")) {
                assert(test === undefined || ts.every(nodes, test), message || "Unexpected node.", function () { return "Node array did not pass test '" + getFunctionName(test) + "'."; }, stackCrawlMark || assertEachNode);
            }
        }
        Debug.assertEachNode = assertEachNode;
        function assertNode(node, test, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertNode")) {
                assert(node !== undefined && (test === undefined || test(node)), message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " did not pass test '" + getFunctionName(test) + "'."; }, stackCrawlMark || assertNode);
            }
        }
        Debug.assertNode = assertNode;
        function assertNotNode(node, test, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertNotNode")) {
                assert(node === undefined || test === undefined || !test(node), message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " should not have passed test '" + getFunctionName(test) + "'."; }, stackCrawlMark || assertNotNode);
            }
        }
        Debug.assertNotNode = assertNotNode;
        function assertOptionalNode(node, test, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertOptionalNode")) {
                assert(test === undefined || node === undefined || test(node), message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " did not pass test '" + getFunctionName(test) + "'."; }, stackCrawlMark || assertOptionalNode);
            }
        }
        Debug.assertOptionalNode = assertOptionalNode;
        function assertOptionalToken(node, kind, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertOptionalToken")) {
                assert(kind === undefined || node === undefined || node.kind === kind, message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " was not a '" + formatSyntaxKind(kind) + "' token."; }, stackCrawlMark || assertOptionalToken);
            }
        }
        Debug.assertOptionalToken = assertOptionalToken;
        function assertMissingNode(node, message, stackCrawlMark) {
            if (shouldAssertFunction(1 /* Normal */, "assertMissingNode")) {
                assert(node === undefined, message || "Unexpected node.", function () { return "Node " + formatSyntaxKind(node.kind) + " was unexpected'."; }, stackCrawlMark || assertMissingNode);
            }
        }
        Debug.assertMissingNode = assertMissingNode;
        function getFunctionName(func) {
            if (typeof func !== "function") {
                return "";
            }
            else if (func.hasOwnProperty("name")) {
                return func.name;
            }
            else {
                var text = Function.prototype.toString.call(func);
                var match = /^function\s+([\w\$]+)\s*\(/.exec(text);
                return match ? match[1] : "";
            }
        }
        Debug.getFunctionName = getFunctionName;
        function formatSymbol(symbol) {
            return "{ name: " + ts.unescapeLeadingUnderscores(symbol.escapedName) + "; flags: " + formatSymbolFlags(symbol.flags) + "; declarations: " + ts.map(symbol.declarations, function (node) { return formatSyntaxKind(node.kind); }) + " }";
        }
        Debug.formatSymbol = formatSymbol;
        /**
         * Formats an enum value as a string for debugging and debug assertions.
         */
        function formatEnum(value, enumObject, isFlags) {
            if (value === void 0) { value = 0; }
            var members = getEnumMembers(enumObject);
            if (value === 0) {
                return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0";
            }
            if (isFlags) {
                var result = "";
                var remainingFlags = value;
                for (var _i = 0, members_1 = members; _i < members_1.length; _i++) {
                    var _a = members_1[_i], enumValue = _a[0], enumName = _a[1];
                    if (enumValue > value) {
                        break;
                    }
                    if (enumValue !== 0 && enumValue & value) {
                        result = "" + result + (result ? "|" : "") + enumName;
                        remainingFlags &= ~enumValue;
                    }
                }
                if (remainingFlags === 0) {
                    return result;
                }
            }
            else {
                for (var _b = 0, members_2 = members; _b < members_2.length; _b++) {
                    var _c = members_2[_b], enumValue = _c[0], enumName = _c[1];
                    if (enumValue === value) {
                        return enumName;
                    }
                }
            }
            return value.toString();
        }
        Debug.formatEnum = formatEnum;
        function getEnumMembers(enumObject) {
            var result = [];
            for (var name in enumObject) {
                var value = enumObject[name];
                if (typeof value === "number") {
                    result.push([value, name]);
                }
            }
            return ts.stableSort(result, function (x, y) { return ts.compareValues(x[0], y[0]); });
        }
        function formatSyntaxKind(kind) {
            return formatEnum(kind, ts.SyntaxKind, /*isFlags*/ false);
        }
        Debug.formatSyntaxKind = formatSyntaxKind;
        function formatNodeFlags(flags) {
            return formatEnum(flags, ts.NodeFlags, /*isFlags*/ true);
        }
        Debug.formatNodeFlags = formatNodeFlags;
        function formatModifierFlags(flags) {
            return formatEnum(flags, ts.ModifierFlags, /*isFlags*/ true);
        }
        Debug.formatModifierFlags = formatModifierFlags;
        function formatTransformFlags(flags) {
            return formatEnum(flags, ts.TransformFlags, /*isFlags*/ true);
        }
        Debug.formatTransformFlags = formatTransformFlags;
        function formatEmitFlags(flags) {
            return formatEnum(flags, ts.EmitFlags, /*isFlags*/ true);
        }
        Debug.formatEmitFlags = formatEmitFlags;
        function formatSymbolFlags(flags) {
            return formatEnum(flags, ts.SymbolFlags, /*isFlags*/ true);
        }
        Debug.formatSymbolFlags = formatSymbolFlags;
        function formatTypeFlags(flags) {
            return formatEnum(flags, ts.TypeFlags, /*isFlags*/ true);
        }
        Debug.formatTypeFlags = formatTypeFlags;
        function formatObjectFlags(flags) {
            return formatEnum(flags, ts.ObjectFlags, /*isFlags*/ true);
        }
        Debug.formatObjectFlags = formatObjectFlags;
        var isDebugInfoEnabled = false;
        var extendedDebugModule;
        function extendedDebug() {
            enableDebugInfo();
            if (!extendedDebugModule) {
                throw new Error("Debugging helpers could not be loaded.");
            }
            return extendedDebugModule;
        }
        function printControlFlowGraph(flowNode) {
            return console.log(formatControlFlowGraph(flowNode));
        }
        Debug.printControlFlowGraph = printControlFlowGraph;
        function formatControlFlowGraph(flowNode) {
            return extendedDebug().formatControlFlowGraph(flowNode);
        }
        Debug.formatControlFlowGraph = formatControlFlowGraph;
        function attachFlowNodeDebugInfo(flowNode) {
            if (isDebugInfoEnabled) {
                if (!("__debugFlowFlags" in flowNode)) { // eslint-disable-line no-in-operator
                    Object.defineProperties(flowNode, {
                        __debugFlowFlags: { get: function () { return formatEnum(this.flags, ts.FlowFlags, /*isFlags*/ true); } },
                        __debugToString: { value: function () { return formatControlFlowGraph(this); } }
                    });
                }
            }
        }
        Debug.attachFlowNodeDebugInfo = attachFlowNodeDebugInfo;
        /**
         * Injects debug information into frequently used types.
         */
        function enableDebugInfo() {
            if (isDebugInfoEnabled)
                return;
            // Add additional properties in debug mode to assist with debugging.
            Object.defineProperties(ts.objectAllocator.getSymbolConstructor().prototype, {
                __debugFlags: { get: function () { return formatSymbolFlags(this.flags); } }
            });
            Object.defineProperties(ts.objectAllocator.getTypeConstructor().prototype, {
                __debugFlags: { get: function () { return formatTypeFlags(this.flags); } },
                __debugObjectFlags: { get: function () { return this.flags & 524288 /* Object */ ? formatObjectFlags(this.objectFlags) : ""; } },
                __debugTypeToString: { value: function () { return this.checker.typeToString(this); } },
            });
            var nodeConstructors = [
                ts.objectAllocator.getNodeConstructor(),
                ts.objectAllocator.getIdentifierConstructor(),
                ts.objectAllocator.getTokenConstructor(),
                ts.objectAllocator.getSourceFileConstructor()
            ];
            for (var _i = 0, nodeConstructors_1 = nodeConstructors; _i < nodeConstructors_1.length; _i++) {
                var ctor = nodeConstructors_1[_i];
                if (!ctor.prototype.hasOwnProperty("__debugKind")) {
                    Object.defineProperties(ctor.prototype, {
                        __debugKind: { get: function () { return formatSyntaxKind(this.kind); } },
                        __debugNodeFlags: { get: function () { return formatNodeFlags(this.flags); } },
                        __debugModifierFlags: { get: function () { return formatModifierFlags(ts.getModifierFlagsNoCache(this)); } },
                        __debugTransformFlags: { get: function () { return formatTransformFlags(this.transformFlags); } },
                        __debugIsParseTreeNode: { get: function () { return ts.isParseTreeNode(this); } },
                        __debugEmitFlags: { get: function () { return formatEmitFlags(ts.getEmitFlags(this)); } },
                        __debugGetText: {
                            value: function (includeTrivia) {
                                if (ts.nodeIsSynthesized(this))
                                    return "";
                                var parseNode = ts.getParseTreeNode(this);
                                var sourceFile = parseNode && ts.getSourceFileOfNode(parseNode);
                                return sourceFile ? ts.getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
                            }
                        }
                    });
                }
            }
            // attempt to load extended debugging information
            try {
                if (ts.sys && ts.sys.require) {
                    var basePath = ts.getDirectoryPath(ts.resolvePath(ts.sys.getExecutingFilePath()));
                    var result = ts.sys.require(basePath, "./compiler-debug");
                    if (!result.error) {
                        result.module.init(ts);
                        extendedDebugModule = result.module;
                    }
                }
            }
            catch (_a) {
                // do nothing
            }
            isDebugInfoEnabled = true;
        }
        Debug.enableDebugInfo = enableDebugInfo;
    })(Debug = ts.Debug || (ts.Debug = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /** Gets a timestamp with (at least) ms resolution */
    ts.timestamp = typeof performance !== "undefined" && performance.now ? function () { return performance.now(); } : Date.now ? Date.now : function () { return +(new Date()); };
})(ts || (ts = {}));
/*@internal*/
/** Performance measurements for the compiler. */
var ts;
(function (ts) {
    var performance;
    (function (performance) {
        // NOTE: cannot use ts.noop as core.ts loads after this
        var profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : function () { };
        var enabled = false;
        var profilerStart = 0;
        var counts;
        var marks;
        var measures;
        function createTimerIf(condition, measureName, startMarkName, endMarkName) {
            return condition ? createTimer(measureName, startMarkName, endMarkName) : performance.nullTimer;
        }
        performance.createTimerIf = createTimerIf;
        function createTimer(measureName, startMarkName, endMarkName) {
            var enterCount = 0;
            return {
                enter: enter,
                exit: exit
            };
            function enter() {
                if (++enterCount === 1) {
                    mark(startMarkName);
                }
            }
            function exit() {
                if (--enterCount === 0) {
                    mark(endMarkName);
                    measure(measureName, startMarkName, endMarkName);
                }
                else if (enterCount < 0) {
                    ts.Debug.fail("enter/exit count does not match.");
                }
            }
        }
        performance.createTimer = createTimer;
        performance.nullTimer = { enter: ts.noop, exit: ts.noop };
        /**
         * Marks a performance event.
         *
         * @param markName The name of the mark.
         */
        function mark(markName) {
            if (enabled) {
                marks.set(markName, ts.timestamp());
                counts.set(markName, (counts.get(markName) || 0) + 1);
                profilerEvent(markName);
            }
        }
        performance.mark = mark;
        /**
         * Adds a performance measurement with the specified name.
         *
         * @param measureName The name of the performance measurement.
         * @param startMarkName The name of the starting mark. If not supplied, the point at which the
         *      profiler was enabled is used.
         * @param endMarkName The name of the ending mark. If not supplied, the current timestamp is
         *      used.
         */
        function measure(measureName, startMarkName, endMarkName) {
            if (enabled) {
                var end = endMarkName && marks.get(endMarkName) || ts.timestamp();
                var start = startMarkName && marks.get(startMarkName) || profilerStart;
                measures.set(measureName, (measures.get(measureName) || 0) + (end - start));
            }
        }
        performance.measure = measure;
        /**
         * Gets the number of times a marker was encountered.
         *
         * @param markName The name of the mark.
         */
        function getCount(markName) {
            return counts && counts.get(markName) || 0;
        }
        performance.getCount = getCount;
        /**
         * Gets the total duration of all measurements with the supplied name.
         *
         * @param measureName The name of the measure whose durations should be accumulated.
         */
        function getDuration(measureName) {
            return measures && measures.get(measureName) || 0;
        }
        performance.getDuration = getDuration;
        /**
         * Iterate over each measure, performing some action
         *
         * @param cb The action to perform for each measure
         */
        function forEachMeasure(cb) {
            measures.forEach(function (measure, key) {
                cb(key, measure);
            });
        }
        performance.forEachMeasure = forEachMeasure;
        /** Enables (and resets) performance measurements for the compiler. */
        function enable() {
            counts = ts.createMap();
            marks = ts.createMap();
            measures = ts.createMap();
            enabled = true;
            profilerStart = ts.timestamp();
        }
        performance.enable = enable;
        /** Disables performance measurements for the compiler. */
        function disable() {
            enabled = false;
        }
        performance.disable = disable;
    })(performance = ts.performance || (ts.performance = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var _a;
    var nullLogger = {
        logEvent: ts.noop,
        logErrEvent: ts.noop,
        logPerfEvent: ts.noop,
        logInfoEvent: ts.noop,
        logStartCommand: ts.noop,
        logStopCommand: ts.noop,
        logStartUpdateProgram: ts.noop,
        logStopUpdateProgram: ts.noop,
        logStartUpdateGraph: ts.noop,
        logStopUpdateGraph: ts.noop,
        logStartResolveModule: ts.noop,
        logStopResolveModule: ts.noop,
        logStartParseSourceFile: ts.noop,
        logStopParseSourceFile: ts.noop,
        logStartReadFile: ts.noop,
        logStopReadFile: ts.noop,
        logStartBindFile: ts.noop,
        logStopBindFile: ts.noop,
        logStartScheduledOperation: ts.noop,
        logStopScheduledOperation: ts.noop,
    };
    // Load optional module to enable Event Tracing for Windows
    // See https://github.com/microsoft/typescript-etw for more information
    var etwModule;
    try {
        var etwModulePath = (_a = process.env.TS_ETW_MODULE_PATH) !== null && _a !== void 0 ? _a : "./node_modules/@microsoft/typescript-etw";
        // require() will throw an exception if the module is not found
        // It may also return undefined if not installed properly
        etwModule = require(etwModulePath);
    }
    catch (e) {
        etwModule = undefined;
    }
    /** Performance logger that will generate ETW events if possible - check for `logEvent` member, as `etwModule` will be `{}` when browserified */
    ts.perfLogger = etwModule && etwModule.logEvent ? etwModule : nullLogger;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    // https://semver.org/#spec-item-2
    // > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative
    // > integers, and MUST NOT contain leading zeroes. X is the major version, Y is the minor
    // > version, and Z is the patch version. Each element MUST increase numerically.
    //
    // NOTE: We differ here in that we allow X and X.Y, with missing parts having the default
    // value of `0`.
    var versionRegExp = /^(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*)(?:\-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
    // https://semver.org/#spec-item-9
    // > A pre-release version MAY be denoted by appending a hyphen and a series of dot separated
    // > identifiers immediately following the patch version. Identifiers MUST comprise only ASCII
    // > alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers
    // > MUST NOT include leading zeroes.
    var prereleaseRegExp = /^(?:0|[1-9]\d*|[a-z-][a-z0-9-]*)(?:\.(?:0|[1-9]\d*|[a-z-][a-z0-9-]*))*$/i;
    // https://semver.org/#spec-item-10
    // > Build metadata MAY be denoted by appending a plus sign and a series of dot separated
    // > identifiers immediately following the patch or pre-release version. Identifiers MUST
    // > comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. Identifiers MUST NOT be empty.
    var buildRegExp = /^[a-z0-9-]+(?:\.[a-z0-9-]+)*$/i;
    // https://semver.org/#spec-item-9
    // > Numeric identifiers MUST NOT include leading zeroes.
    var numericIdentifierRegExp = /^(0|[1-9]\d*)$/;
    /**
     * Describes a precise semantic version number, https://semver.org
     */
    var Version = /** @class */ (function () {
        function Version(major, minor, patch, prerelease, build) {
            if (minor === void 0) { minor = 0; }
            if (patch === void 0) { patch = 0; }
            if (prerelease === void 0) { prerelease = ""; }
            if (build === void 0) { build = ""; }
            if (typeof major === "string") {
                var result = ts.Debug.checkDefined(tryParseComponents(major), "Invalid version");
                (major = result.major, minor = result.minor, patch = result.patch, prerelease = result.prerelease, build = result.build);
            }
            ts.Debug.assert(major >= 0, "Invalid argument: major");
            ts.Debug.assert(minor >= 0, "Invalid argument: minor");
            ts.Debug.assert(patch >= 0, "Invalid argument: patch");
            ts.Debug.assert(!prerelease || prereleaseRegExp.test(prerelease), "Invalid argument: prerelease");
            ts.Debug.assert(!build || buildRegExp.test(build), "Invalid argument: build");
            this.major = major;
            this.minor = minor;
            this.patch = patch;
            this.prerelease = prerelease ? prerelease.split(".") : ts.emptyArray;
            this.build = build ? build.split(".") : ts.emptyArray;
        }
        Version.tryParse = function (text) {
            var result = tryParseComponents(text);
            if (!result)
                return undefined;
            var major = result.major, minor = result.minor, patch = result.patch, prerelease = result.prerelease, build = result.build;
            return new Version(major, minor, patch, prerelease, build);
        };
        Version.prototype.compareTo = function (other) {
            // https://semver.org/#spec-item-11
            // > Precedence is determined by the first difference when comparing each of these
            // > identifiers from left to right as follows: Major, minor, and patch versions are
            // > always compared numerically.
            //
            // https://semver.org/#spec-item-11
            // > Precedence for two pre-release versions with the same major, minor, and patch version
            // > MUST be determined by comparing each dot separated identifier from left to right until
            // > a difference is found [...]
            //
            // https://semver.org/#spec-item-11
            // > Build metadata does not figure into precedence
            if (this === other)
                return 0 /* EqualTo */;
            if (other === undefined)
                return 1 /* GreaterThan */;
            return ts.compareValues(this.major, other.major)
                || ts.compareValues(this.minor, other.minor)
                || ts.compareValues(this.patch, other.patch)
                || comparePrerelaseIdentifiers(this.prerelease, other.prerelease);
        };
        Version.prototype.increment = function (field) {
            switch (field) {
                case "major": return new Version(this.major + 1, 0, 0);
                case "minor": return new Version(this.major, this.minor + 1, 0);
                case "patch": return new Version(this.major, this.minor, this.patch + 1);
                default: return ts.Debug.assertNever(field);
            }
        };
        Version.prototype.toString = function () {
            var result = this.major + "." + this.minor + "." + this.patch;
            if (ts.some(this.prerelease))
                result += "-" + this.prerelease.join(".");
            if (ts.some(this.build))
                result += "+" + this.build.join(".");
            return result;
        };
        Version.zero = new Version(0, 0, 0);
        return Version;
    }());
    ts.Version = Version;
    function tryParseComponents(text) {
        var match = versionRegExp.exec(text);
        if (!match)
            return undefined;
        var major = match[1], _a = match[2], minor = _a === void 0 ? "0" : _a, _b = match[3], patch = _b === void 0 ? "0" : _b, _c = match[4], prerelease = _c === void 0 ? "" : _c, _d = match[5], build = _d === void 0 ? "" : _d;
        if (prerelease && !prereleaseRegExp.test(prerelease))
            return undefined;
        if (build && !buildRegExp.test(build))
            return undefined;
        return {
            major: parseInt(major, 10),
            minor: parseInt(minor, 10),
            patch: parseInt(patch, 10),
            prerelease: prerelease,
            build: build
        };
    }
    function comparePrerelaseIdentifiers(left, right) {
        // https://semver.org/#spec-item-11
        // > When major, minor, and patch are equal, a pre-release version has lower precedence
        // > than a normal version.
        if (left === right)
            return 0 /* EqualTo */;
        if (left.length === 0)
            return right.length === 0 ? 0 /* EqualTo */ : 1 /* GreaterThan */;
        if (right.length === 0)
            return -1 /* LessThan */;
        // https://semver.org/#spec-item-11
        // > Precedence for two pre-release versions with the same major, minor, and patch version
        // > MUST be determined by comparing each dot separated identifier from left to right until
        // > a difference is found [...]
        var length = Math.min(left.length, right.length);
        for (var i = 0; i < length; i++) {
            var leftIdentifier = left[i];
            var rightIdentifier = right[i];
            if (leftIdentifier === rightIdentifier)
                continue;
            var leftIsNumeric = numericIdentifierRegExp.test(leftIdentifier);
            var rightIsNumeric = numericIdentifierRegExp.test(rightIdentifier);
            if (leftIsNumeric || rightIsNumeric) {
                // https://semver.org/#spec-item-11
                // > Numeric identifiers always have lower precedence than non-numeric identifiers.
                if (leftIsNumeric !== rightIsNumeric)
                    return leftIsNumeric ? -1 /* LessThan */ : 1 /* GreaterThan */;
                // https://semver.org/#spec-item-11
                // > identifiers consisting of only digits are compared numerically
                var result = ts.compareValues(+leftIdentifier, +rightIdentifier);
                if (result)
                    return result;
            }
            else {
                // https://semver.org/#spec-item-11
                // > identifiers with letters or hyphens are compared lexically in ASCII sort order.
                var result = ts.compareStringsCaseSensitive(leftIdentifier, rightIdentifier);
                if (result)
                    return result;
            }
        }
        // https://semver.org/#spec-item-11
        // > A larger set of pre-release fields has a higher precedence than a smaller set, if all
        // > of the preceding identifiers are equal.
        return ts.compareValues(left.length, right.length);
    }
    /**
     * Describes a semantic version range, per https://github.com/npm/node-semver#ranges
     */
    var VersionRange = /** @class */ (function () {
        function VersionRange(spec) {
            this._alternatives = spec ? ts.Debug.checkDefined(parseRange(spec), "Invalid range spec.") : ts.emptyArray;
        }
        VersionRange.tryParse = function (text) {
            var sets = parseRange(text);
            if (sets) {
                var range = new VersionRange("");
                range._alternatives = sets;
                return range;
            }
            return undefined;
        };
        VersionRange.prototype.test = function (version) {
            if (typeof version === "string")
                version = new Version(version);
            return testDisjunction(version, this._alternatives);
        };
        VersionRange.prototype.toString = function () {
            return formatDisjunction(this._alternatives);
        };
        return VersionRange;
    }());
    ts.VersionRange = VersionRange;
    // https://github.com/npm/node-semver#range-grammar
    //
    // range-set    ::= range ( logical-or range ) *
    // range        ::= hyphen | simple ( ' ' simple ) * | ''
    // logical-or   ::= ( ' ' ) * '||' ( ' ' ) *
    var logicalOrRegExp = /\s*\|\|\s*/g;
    var whitespaceRegExp = /\s+/g;
    // https://github.com/npm/node-semver#range-grammar
    //
    // partial      ::= xr ( '.' xr ( '.' xr qualifier ? )? )?
    // xr           ::= 'x' | 'X' | '*' | nr
    // nr           ::= '0' | ['1'-'9'] ( ['0'-'9'] ) *
    // qualifier    ::= ( '-' pre )? ( '+' build )?
    // pre          ::= parts
    // build        ::= parts
    // parts        ::= part ( '.' part ) *
    // part         ::= nr | [-0-9A-Za-z]+
    var partialRegExp = /^([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:\.([xX*0]|[1-9]\d*)(?:-([a-z0-9-.]+))?(?:\+([a-z0-9-.]+))?)?)?$/i;
    // https://github.com/npm/node-semver#range-grammar
    //
    // hyphen       ::= partial ' - ' partial
    var hyphenRegExp = /^\s*([a-z0-9-+.*]+)\s+-\s+([a-z0-9-+.*]+)\s*$/i;
    // https://github.com/npm/node-semver#range-grammar
    //
    // simple       ::= primitive | partial | tilde | caret
    // primitive    ::= ( '<' | '>' | '>=' | '<=' | '=' ) partial
    // tilde        ::= '~' partial
    // caret        ::= '^' partial
    var rangeRegExp = /^\s*(~|\^|<|<=|>|>=|=)?\s*([a-z0-9-+.*]+)$/i;
    function parseRange(text) {
        var alternatives = [];
        for (var _i = 0, _a = text.trim().split(logicalOrRegExp); _i < _a.length; _i++) {
            var range = _a[_i];
            if (!range)
                continue;
            var comparators = [];
            var match = hyphenRegExp.exec(range);
            if (match) {
                if (!parseHyphen(match[1], match[2], comparators))
                    return undefined;
            }
            else {
                for (var _b = 0, _c = range.split(whitespaceRegExp); _b < _c.length; _b++) {
                    var simple = _c[_b];
                    var match_1 = rangeRegExp.exec(simple);
                    if (!match_1 || !parseComparator(match_1[1], match_1[2], comparators))
                        return undefined;
                }
            }
            alternatives.push(comparators);
        }
        return alternatives;
    }
    function parsePartial(text) {
        var match = partialRegExp.exec(text);
        if (!match)
            return undefined;
        var major = match[1], _a = match[2], minor = _a === void 0 ? "*" : _a, _b = match[3], patch = _b === void 0 ? "*" : _b, prerelease = match[4], build = match[5];
        var version = new Version(isWildcard(major) ? 0 : parseInt(major, 10), isWildcard(major) || isWildcard(minor) ? 0 : parseInt(minor, 10), isWildcard(major) || isWildcard(minor) || isWildcard(patch) ? 0 : parseInt(patch, 10), prerelease, build);
        return { version: version, major: major, minor: minor, patch: patch };
    }
    function parseHyphen(left, right, comparators) {
        var leftResult = parsePartial(left);
        if (!leftResult)
            return false;
        var rightResult = parsePartial(right);
        if (!rightResult)
            return false;
        if (!isWildcard(leftResult.major)) {
            comparators.push(createComparator(">=", leftResult.version));
        }
        if (!isWildcard(rightResult.major)) {
            comparators.push(isWildcard(rightResult.minor) ? createComparator("<", rightResult.version.increment("major")) :
                isWildcard(rightResult.patch) ? createComparator("<", rightResult.version.increment("minor")) :
                    createComparator("<=", rightResult.version));
        }
        return true;
    }
    function parseComparator(operator, text, comparators) {
        var result = parsePartial(text);
        if (!result)
            return false;
        var version = result.version, major = result.major, minor = result.minor, patch = result.patch;
        if (!isWildcard(major)) {
            switch (operator) {
                case "~":
                    comparators.push(createComparator(">=", version));
                    comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" :
                        "minor")));
                    break;
                case "^":
                    comparators.push(createComparator(">=", version));
                    comparators.push(createComparator("<", version.increment(version.major > 0 || isWildcard(minor) ? "major" :
                        version.minor > 0 || isWildcard(patch) ? "minor" :
                            "patch")));
                    break;
                case "<":
                case ">=":
                    comparators.push(createComparator(operator, version));
                    break;
                case "<=":
                case ">":
                    comparators.push(isWildcard(minor) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("major")) :
                        isWildcard(patch) ? createComparator(operator === "<=" ? "<" : ">=", version.increment("minor")) :
                            createComparator(operator, version));
                    break;
                case "=":
                case undefined:
                    if (isWildcard(minor) || isWildcard(patch)) {
                        comparators.push(createComparator(">=", version));
                        comparators.push(createComparator("<", version.increment(isWildcard(minor) ? "major" : "minor")));
                    }
                    else {
                        comparators.push(createComparator("=", version));
                    }
                    break;
                default:
                    // unrecognized
                    return false;
            }
        }
        else if (operator === "<" || operator === ">") {
            comparators.push(createComparator("<", Version.zero));
        }
        return true;
    }
    function isWildcard(part) {
        return part === "*" || part === "x" || part === "X";
    }
    function createComparator(operator, operand) {
        return { operator: operator, operand: operand };
    }
    function testDisjunction(version, alternatives) {
        // an empty disjunction is treated as "*" (all versions)
        if (alternatives.length === 0)
            return true;
        for (var _i = 0, alternatives_1 = alternatives; _i < alternatives_1.length; _i++) {
            var alternative = alternatives_1[_i];
            if (testAlternative(version, alternative))
                return true;
        }
        return false;
    }
    function testAlternative(version, comparators) {
        for (var _i = 0, comparators_1 = comparators; _i < comparators_1.length; _i++) {
            var comparator = comparators_1[_i];
            if (!testComparator(version, comparator.operator, comparator.operand))
                return false;
        }
        return true;
    }
    function testComparator(version, operator, operand) {
        var cmp = version.compareTo(operand);
        switch (operator) {
            case "<": return cmp < 0;
            case "<=": return cmp <= 0;
            case ">": return cmp > 0;
            case ">=": return cmp >= 0;
            case "=": return cmp === 0;
            default: return ts.Debug.assertNever(operator);
        }
    }
    function formatDisjunction(alternatives) {
        return ts.map(alternatives, formatAlternative).join(" || ") || "*";
    }
    function formatAlternative(comparators) {
        return ts.map(comparators, formatComparator).join(" ");
    }
    function formatComparator(comparator) {
        return "" + comparator.operator + comparator.operand;
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    // token > SyntaxKind.Identifier => token is a keyword
    // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync
    var SyntaxKind;
    (function (SyntaxKind) {
        SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown";
        SyntaxKind[SyntaxKind["EndOfFileToken"] = 1] = "EndOfFileToken";
        SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia";
        SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 3] = "MultiLineCommentTrivia";
        SyntaxKind[SyntaxKind["NewLineTrivia"] = 4] = "NewLineTrivia";
        SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 5] = "WhitespaceTrivia";
        // We detect and preserve #! on the first line
        SyntaxKind[SyntaxKind["ShebangTrivia"] = 6] = "ShebangTrivia";
        // We detect and provide better error recovery when we encounter a git merge marker.  This
        // allows us to edit files with git-conflict markers in them in a much more pleasant manner.
        SyntaxKind[SyntaxKind["ConflictMarkerTrivia"] = 7] = "ConflictMarkerTrivia";
        // Literals
        SyntaxKind[SyntaxKind["NumericLiteral"] = 8] = "NumericLiteral";
        SyntaxKind[SyntaxKind["BigIntLiteral"] = 9] = "BigIntLiteral";
        SyntaxKind[SyntaxKind["StringLiteral"] = 10] = "StringLiteral";
        SyntaxKind[SyntaxKind["JsxText"] = 11] = "JsxText";
        SyntaxKind[SyntaxKind["JsxTextAllWhiteSpaces"] = 12] = "JsxTextAllWhiteSpaces";
        SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 13] = "RegularExpressionLiteral";
        SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 14] = "NoSubstitutionTemplateLiteral";
        // Pseudo-literals
        SyntaxKind[SyntaxKind["TemplateHead"] = 15] = "TemplateHead";
        SyntaxKind[SyntaxKind["TemplateMiddle"] = 16] = "TemplateMiddle";
        SyntaxKind[SyntaxKind["TemplateTail"] = 17] = "TemplateTail";
        // Punctuation
        SyntaxKind[SyntaxKind["OpenBraceToken"] = 18] = "OpenBraceToken";
        SyntaxKind[SyntaxKind["CloseBraceToken"] = 19] = "CloseBraceToken";
        SyntaxKind[SyntaxKind["OpenParenToken"] = 20] = "OpenParenToken";
        SyntaxKind[SyntaxKind["CloseParenToken"] = 21] = "CloseParenToken";
        SyntaxKind[SyntaxKind["OpenBracketToken"] = 22] = "OpenBracketToken";
        SyntaxKind[SyntaxKind["CloseBracketToken"] = 23] = "CloseBracketToken";
        SyntaxKind[SyntaxKind["DotToken"] = 24] = "DotToken";
        SyntaxKind[SyntaxKind["DotDotDotToken"] = 25] = "DotDotDotToken";
        SyntaxKind[SyntaxKind["SemicolonToken"] = 26] = "SemicolonToken";
        SyntaxKind[SyntaxKind["CommaToken"] = 27] = "CommaToken";
        SyntaxKind[SyntaxKind["QuestionDotToken"] = 28] = "QuestionDotToken";
        SyntaxKind[SyntaxKind["LessThanToken"] = 29] = "LessThanToken";
        SyntaxKind[SyntaxKind["LessThanSlashToken"] = 30] = "LessThanSlashToken";
        SyntaxKind[SyntaxKind["GreaterThanToken"] = 31] = "GreaterThanToken";
        SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 32] = "LessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 33] = "GreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 34] = "EqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 35] = "ExclamationEqualsToken";
        SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 36] = "EqualsEqualsEqualsToken";
        SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 37] = "ExclamationEqualsEqualsToken";
        SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 38] = "EqualsGreaterThanToken";
        SyntaxKind[SyntaxKind["PlusToken"] = 39] = "PlusToken";
        SyntaxKind[SyntaxKind["MinusToken"] = 40] = "MinusToken";
        SyntaxKind[SyntaxKind["AsteriskToken"] = 41] = "AsteriskToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskToken"] = 42] = "AsteriskAsteriskToken";
        SyntaxKind[SyntaxKind["SlashToken"] = 43] = "SlashToken";
        SyntaxKind[SyntaxKind["PercentToken"] = 44] = "PercentToken";
        SyntaxKind[SyntaxKind["PlusPlusToken"] = 45] = "PlusPlusToken";
        SyntaxKind[SyntaxKind["MinusMinusToken"] = 46] = "MinusMinusToken";
        SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 47] = "LessThanLessThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 48] = "GreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 49] = "GreaterThanGreaterThanGreaterThanToken";
        SyntaxKind[SyntaxKind["AmpersandToken"] = 50] = "AmpersandToken";
        SyntaxKind[SyntaxKind["BarToken"] = 51] = "BarToken";
        SyntaxKind[SyntaxKind["CaretToken"] = 52] = "CaretToken";
        SyntaxKind[SyntaxKind["ExclamationToken"] = 53] = "ExclamationToken";
        SyntaxKind[SyntaxKind["TildeToken"] = 54] = "TildeToken";
        SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 55] = "AmpersandAmpersandToken";
        SyntaxKind[SyntaxKind["BarBarToken"] = 56] = "BarBarToken";
        SyntaxKind[SyntaxKind["QuestionToken"] = 57] = "QuestionToken";
        SyntaxKind[SyntaxKind["ColonToken"] = 58] = "ColonToken";
        SyntaxKind[SyntaxKind["AtToken"] = 59] = "AtToken";
        SyntaxKind[SyntaxKind["QuestionQuestionToken"] = 60] = "QuestionQuestionToken";
        /** Only the JSDoc scanner produces BacktickToken. The normal scanner produces NoSubstitutionTemplateLiteral and related kinds. */
        SyntaxKind[SyntaxKind["BacktickToken"] = 61] = "BacktickToken";
        // Assignments
        SyntaxKind[SyntaxKind["EqualsToken"] = 62] = "EqualsToken";
        SyntaxKind[SyntaxKind["PlusEqualsToken"] = 63] = "PlusEqualsToken";
        SyntaxKind[SyntaxKind["MinusEqualsToken"] = 64] = "MinusEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 65] = "AsteriskEqualsToken";
        SyntaxKind[SyntaxKind["AsteriskAsteriskEqualsToken"] = 66] = "AsteriskAsteriskEqualsToken";
        SyntaxKind[SyntaxKind["SlashEqualsToken"] = 67] = "SlashEqualsToken";
        SyntaxKind[SyntaxKind["PercentEqualsToken"] = 68] = "PercentEqualsToken";
        SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 69] = "LessThanLessThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 70] = "GreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 71] = "GreaterThanGreaterThanGreaterThanEqualsToken";
        SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 72] = "AmpersandEqualsToken";
        SyntaxKind[SyntaxKind["BarEqualsToken"] = 73] = "BarEqualsToken";
        SyntaxKind[SyntaxKind["CaretEqualsToken"] = 74] = "CaretEqualsToken";
        // Identifiers and PrivateIdentifiers
        SyntaxKind[SyntaxKind["Identifier"] = 75] = "Identifier";
        SyntaxKind[SyntaxKind["PrivateIdentifier"] = 76] = "PrivateIdentifier";
        // Reserved words
        SyntaxKind[SyntaxKind["BreakKeyword"] = 77] = "BreakKeyword";
        SyntaxKind[SyntaxKind["CaseKeyword"] = 78] = "CaseKeyword";
        SyntaxKind[SyntaxKind["CatchKeyword"] = 79] = "CatchKeyword";
        SyntaxKind[SyntaxKind["ClassKeyword"] = 80] = "ClassKeyword";
        SyntaxKind[SyntaxKind["ConstKeyword"] = 81] = "ConstKeyword";
        SyntaxKind[SyntaxKind["ContinueKeyword"] = 82] = "ContinueKeyword";
        SyntaxKind[SyntaxKind["DebuggerKeyword"] = 83] = "DebuggerKeyword";
        SyntaxKind[SyntaxKind["DefaultKeyword"] = 84] = "DefaultKeyword";
        SyntaxKind[SyntaxKind["DeleteKeyword"] = 85] = "DeleteKeyword";
        SyntaxKind[SyntaxKind["DoKeyword"] = 86] = "DoKeyword";
        SyntaxKind[SyntaxKind["ElseKeyword"] = 87] = "ElseKeyword";
        SyntaxKind[SyntaxKind["EnumKeyword"] = 88] = "EnumKeyword";
        SyntaxKind[SyntaxKind["ExportKeyword"] = 89] = "ExportKeyword";
        SyntaxKind[SyntaxKind["ExtendsKeyword"] = 90] = "ExtendsKeyword";
        SyntaxKind[SyntaxKind["FalseKeyword"] = 91] = "FalseKeyword";
        SyntaxKind[SyntaxKind["FinallyKeyword"] = 92] = "FinallyKeyword";
        SyntaxKind[SyntaxKind["ForKeyword"] = 93] = "ForKeyword";
        SyntaxKind[SyntaxKind["FunctionKeyword"] = 94] = "FunctionKeyword";
        SyntaxKind[SyntaxKind["IfKeyword"] = 95] = "IfKeyword";
        SyntaxKind[SyntaxKind["ImportKeyword"] = 96] = "ImportKeyword";
        SyntaxKind[SyntaxKind["InKeyword"] = 97] = "InKeyword";
        SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 98] = "InstanceOfKeyword";
        SyntaxKind[SyntaxKind["NewKeyword"] = 99] = "NewKeyword";
        SyntaxKind[SyntaxKind["NullKeyword"] = 100] = "NullKeyword";
        SyntaxKind[SyntaxKind["ReturnKeyword"] = 101] = "ReturnKeyword";
        SyntaxKind[SyntaxKind["SuperKeyword"] = 102] = "SuperKeyword";
        SyntaxKind[SyntaxKind["SwitchKeyword"] = 103] = "SwitchKeyword";
        SyntaxKind[SyntaxKind["ThisKeyword"] = 104] = "ThisKeyword";
        SyntaxKind[SyntaxKind["ThrowKeyword"] = 105] = "ThrowKeyword";
        SyntaxKind[SyntaxKind["TrueKeyword"] = 106] = "TrueKeyword";
        SyntaxKind[SyntaxKind["TryKeyword"] = 107] = "TryKeyword";
        SyntaxKind[SyntaxKind["TypeOfKeyword"] = 108] = "TypeOfKeyword";
        SyntaxKind[SyntaxKind["VarKeyword"] = 109] = "VarKeyword";
        SyntaxKind[SyntaxKind["VoidKeyword"] = 110] = "VoidKeyword";
        SyntaxKind[SyntaxKind["WhileKeyword"] = 111] = "WhileKeyword";
        SyntaxKind[SyntaxKind["WithKeyword"] = 112] = "WithKeyword";
        // Strict mode reserved words
        SyntaxKind[SyntaxKind["ImplementsKeyword"] = 113] = "ImplementsKeyword";
        SyntaxKind[SyntaxKind["InterfaceKeyword"] = 114] = "InterfaceKeyword";
        SyntaxKind[SyntaxKind["LetKeyword"] = 115] = "LetKeyword";
        SyntaxKind[SyntaxKind["PackageKeyword"] = 116] = "PackageKeyword";
        SyntaxKind[SyntaxKind["PrivateKeyword"] = 117] = "PrivateKeyword";
        SyntaxKind[SyntaxKind["ProtectedKeyword"] = 118] = "ProtectedKeyword";
        SyntaxKind[SyntaxKind["PublicKeyword"] = 119] = "PublicKeyword";
        SyntaxKind[SyntaxKind["StaticKeyword"] = 120] = "StaticKeyword";
        SyntaxKind[SyntaxKind["YieldKeyword"] = 121] = "YieldKeyword";
        // Contextual keywords
        SyntaxKind[SyntaxKind["AbstractKeyword"] = 122] = "AbstractKeyword";
        SyntaxKind[SyntaxKind["AsKeyword"] = 123] = "AsKeyword";
        SyntaxKind[SyntaxKind["AssertsKeyword"] = 124] = "AssertsKeyword";
        SyntaxKind[SyntaxKind["AnyKeyword"] = 125] = "AnyKeyword";
        SyntaxKind[SyntaxKind["AsyncKeyword"] = 126] = "AsyncKeyword";
        SyntaxKind[SyntaxKind["AwaitKeyword"] = 127] = "AwaitKeyword";
        SyntaxKind[SyntaxKind["BooleanKeyword"] = 128] = "BooleanKeyword";
        SyntaxKind[SyntaxKind["ConstructorKeyword"] = 129] = "ConstructorKeyword";
        SyntaxKind[SyntaxKind["DeclareKeyword"] = 130] = "DeclareKeyword";
        SyntaxKind[SyntaxKind["GetKeyword"] = 131] = "GetKeyword";
        SyntaxKind[SyntaxKind["InferKeyword"] = 132] = "InferKeyword";
        SyntaxKind[SyntaxKind["IsKeyword"] = 133] = "IsKeyword";
        SyntaxKind[SyntaxKind["KeyOfKeyword"] = 134] = "KeyOfKeyword";
        SyntaxKind[SyntaxKind["ModuleKeyword"] = 135] = "ModuleKeyword";
        SyntaxKind[SyntaxKind["NamespaceKeyword"] = 136] = "NamespaceKeyword";
        SyntaxKind[SyntaxKind["NeverKeyword"] = 137] = "NeverKeyword";
        SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 138] = "ReadonlyKeyword";
        SyntaxKind[SyntaxKind["RequireKeyword"] = 139] = "RequireKeyword";
        SyntaxKind[SyntaxKind["NumberKeyword"] = 140] = "NumberKeyword";
        SyntaxKind[SyntaxKind["ObjectKeyword"] = 141] = "ObjectKeyword";
        SyntaxKind[SyntaxKind["SetKeyword"] = 142] = "SetKeyword";
        SyntaxKind[SyntaxKind["StringKeyword"] = 143] = "StringKeyword";
        SyntaxKind[SyntaxKind["SymbolKeyword"] = 144] = "SymbolKeyword";
        SyntaxKind[SyntaxKind["TypeKeyword"] = 145] = "TypeKeyword";
        SyntaxKind[SyntaxKind["UndefinedKeyword"] = 146] = "UndefinedKeyword";
        SyntaxKind[SyntaxKind["UniqueKeyword"] = 147] = "UniqueKeyword";
        SyntaxKind[SyntaxKind["UnknownKeyword"] = 148] = "UnknownKeyword";
        SyntaxKind[SyntaxKind["FromKeyword"] = 149] = "FromKeyword";
        SyntaxKind[SyntaxKind["GlobalKeyword"] = 150] = "GlobalKeyword";
        SyntaxKind[SyntaxKind["BigIntKeyword"] = 151] = "BigIntKeyword";
        SyntaxKind[SyntaxKind["OfKeyword"] = 152] = "OfKeyword";
        // Parse tree nodes
        // Names
        SyntaxKind[SyntaxKind["QualifiedName"] = 153] = "QualifiedName";
        SyntaxKind[SyntaxKind["ComputedPropertyName"] = 154] = "ComputedPropertyName";
        // Signature elements
        SyntaxKind[SyntaxKind["TypeParameter"] = 155] = "TypeParameter";
        SyntaxKind[SyntaxKind["Parameter"] = 156] = "Parameter";
        SyntaxKind[SyntaxKind["Decorator"] = 157] = "Decorator";
        // TypeMember
        SyntaxKind[SyntaxKind["PropertySignature"] = 158] = "PropertySignature";
        SyntaxKind[SyntaxKind["PropertyDeclaration"] = 159] = "PropertyDeclaration";
        SyntaxKind[SyntaxKind["MethodSignature"] = 160] = "MethodSignature";
        SyntaxKind[SyntaxKind["MethodDeclaration"] = 161] = "MethodDeclaration";
        SyntaxKind[SyntaxKind["Constructor"] = 162] = "Constructor";
        SyntaxKind[SyntaxKind["GetAccessor"] = 163] = "GetAccessor";
        SyntaxKind[SyntaxKind["SetAccessor"] = 164] = "SetAccessor";
        SyntaxKind[SyntaxKind["CallSignature"] = 165] = "CallSignature";
        SyntaxKind[SyntaxKind["ConstructSignature"] = 166] = "ConstructSignature";
        SyntaxKind[SyntaxKind["IndexSignature"] = 167] = "IndexSignature";
        // Type
        SyntaxKind[SyntaxKind["TypePredicate"] = 168] = "TypePredicate";
        SyntaxKind[SyntaxKind["TypeReference"] = 169] = "TypeReference";
        SyntaxKind[SyntaxKind["FunctionType"] = 170] = "FunctionType";
        SyntaxKind[SyntaxKind["ConstructorType"] = 171] = "ConstructorType";
        SyntaxKind[SyntaxKind["TypeQuery"] = 172] = "TypeQuery";
        SyntaxKind[SyntaxKind["TypeLiteral"] = 173] = "TypeLiteral";
        SyntaxKind[SyntaxKind["ArrayType"] = 174] = "ArrayType";
        SyntaxKind[SyntaxKind["TupleType"] = 175] = "TupleType";
        SyntaxKind[SyntaxKind["OptionalType"] = 176] = "OptionalType";
        SyntaxKind[SyntaxKind["RestType"] = 177] = "RestType";
        SyntaxKind[SyntaxKind["UnionType"] = 178] = "UnionType";
        SyntaxKind[SyntaxKind["IntersectionType"] = 179] = "IntersectionType";
        SyntaxKind[SyntaxKind["ConditionalType"] = 180] = "ConditionalType";
        SyntaxKind[SyntaxKind["InferType"] = 181] = "InferType";
        SyntaxKind[SyntaxKind["ParenthesizedType"] = 182] = "ParenthesizedType";
        SyntaxKind[SyntaxKind["ThisType"] = 183] = "ThisType";
        SyntaxKind[SyntaxKind["TypeOperator"] = 184] = "TypeOperator";
        SyntaxKind[SyntaxKind["IndexedAccessType"] = 185] = "IndexedAccessType";
        SyntaxKind[SyntaxKind["MappedType"] = 186] = "MappedType";
        SyntaxKind[SyntaxKind["LiteralType"] = 187] = "LiteralType";
        SyntaxKind[SyntaxKind["ImportType"] = 188] = "ImportType";
        // Binding patterns
        SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 189] = "ObjectBindingPattern";
        SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 190] = "ArrayBindingPattern";
        SyntaxKind[SyntaxKind["BindingElement"] = 191] = "BindingElement";
        // Expression
        SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 192] = "ArrayLiteralExpression";
        SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 193] = "ObjectLiteralExpression";
        SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 194] = "PropertyAccessExpression";
        SyntaxKind[SyntaxKind["ElementAccessExpression"] = 195] = "ElementAccessExpression";
        SyntaxKind[SyntaxKind["CallExpression"] = 196] = "CallExpression";
        SyntaxKind[SyntaxKind["NewExpression"] = 197] = "NewExpression";
        SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 198] = "TaggedTemplateExpression";
        SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 199] = "TypeAssertionExpression";
        SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 200] = "ParenthesizedExpression";
        SyntaxKind[SyntaxKind["FunctionExpression"] = 201] = "FunctionExpression";
        SyntaxKind[SyntaxKind["ArrowFunction"] = 202] = "ArrowFunction";
        SyntaxKind[SyntaxKind["DeleteExpression"] = 203] = "DeleteExpression";
        SyntaxKind[SyntaxKind["TypeOfExpression"] = 204] = "TypeOfExpression";
        SyntaxKind[SyntaxKind["VoidExpression"] = 205] = "VoidExpression";
        SyntaxKind[SyntaxKind["AwaitExpression"] = 206] = "AwaitExpression";
        SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 207] = "PrefixUnaryExpression";
        SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 208] = "PostfixUnaryExpression";
        SyntaxKind[SyntaxKind["BinaryExpression"] = 209] = "BinaryExpression";
        SyntaxKind[SyntaxKind["ConditionalExpression"] = 210] = "ConditionalExpression";
        SyntaxKind[SyntaxKind["TemplateExpression"] = 211] = "TemplateExpression";
        SyntaxKind[SyntaxKind["YieldExpression"] = 212] = "YieldExpression";
        SyntaxKind[SyntaxKind["SpreadElement"] = 213] = "SpreadElement";
        SyntaxKind[SyntaxKind["ClassExpression"] = 214] = "ClassExpression";
        SyntaxKind[SyntaxKind["OmittedExpression"] = 215] = "OmittedExpression";
        SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 216] = "ExpressionWithTypeArguments";
        SyntaxKind[SyntaxKind["AsExpression"] = 217] = "AsExpression";
        SyntaxKind[SyntaxKind["NonNullExpression"] = 218] = "NonNullExpression";
        SyntaxKind[SyntaxKind["MetaProperty"] = 219] = "MetaProperty";
        SyntaxKind[SyntaxKind["SyntheticExpression"] = 220] = "SyntheticExpression";
        // Misc
        SyntaxKind[SyntaxKind["TemplateSpan"] = 221] = "TemplateSpan";
        SyntaxKind[SyntaxKind["SemicolonClassElement"] = 222] = "SemicolonClassElement";
        // Element
        SyntaxKind[SyntaxKind["Block"] = 223] = "Block";
        SyntaxKind[SyntaxKind["EmptyStatement"] = 224] = "EmptyStatement";
        SyntaxKind[SyntaxKind["VariableStatement"] = 225] = "VariableStatement";
        SyntaxKind[SyntaxKind["ExpressionStatement"] = 226] = "ExpressionStatement";
        SyntaxKind[SyntaxKind["IfStatement"] = 227] = "IfStatement";
        SyntaxKind[SyntaxKind["DoStatement"] = 228] = "DoStatement";
        SyntaxKind[SyntaxKind["WhileStatement"] = 229] = "WhileStatement";
        SyntaxKind[SyntaxKind["ForStatement"] = 230] = "ForStatement";
        SyntaxKind[SyntaxKind["ForInStatement"] = 231] = "ForInStatement";
        SyntaxKind[SyntaxKind["ForOfStatement"] = 232] = "ForOfStatement";
        SyntaxKind[SyntaxKind["ContinueStatement"] = 233] = "ContinueStatement";
        SyntaxKind[SyntaxKind["BreakStatement"] = 234] = "BreakStatement";
        SyntaxKind[SyntaxKind["ReturnStatement"] = 235] = "ReturnStatement";
        SyntaxKind[SyntaxKind["WithStatement"] = 236] = "WithStatement";
        SyntaxKind[SyntaxKind["SwitchStatement"] = 237] = "SwitchStatement";
        SyntaxKind[SyntaxKind["LabeledStatement"] = 238] = "LabeledStatement";
        SyntaxKind[SyntaxKind["ThrowStatement"] = 239] = "ThrowStatement";
        SyntaxKind[SyntaxKind["TryStatement"] = 240] = "TryStatement";
        SyntaxKind[SyntaxKind["DebuggerStatement"] = 241] = "DebuggerStatement";
        SyntaxKind[SyntaxKind["VariableDeclaration"] = 242] = "VariableDeclaration";
        SyntaxKind[SyntaxKind["VariableDeclarationList"] = 243] = "VariableDeclarationList";
        SyntaxKind[SyntaxKind["FunctionDeclaration"] = 244] = "FunctionDeclaration";
        SyntaxKind[SyntaxKind["ClassDeclaration"] = 245] = "ClassDeclaration";
        SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 246] = "InterfaceDeclaration";
        SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 247] = "TypeAliasDeclaration";
        SyntaxKind[SyntaxKind["EnumDeclaration"] = 248] = "EnumDeclaration";
        SyntaxKind[SyntaxKind["ModuleDeclaration"] = 249] = "ModuleDeclaration";
        SyntaxKind[SyntaxKind["ModuleBlock"] = 250] = "ModuleBlock";
        SyntaxKind[SyntaxKind["CaseBlock"] = 251] = "CaseBlock";
        SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 252] = "NamespaceExportDeclaration";
        SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 253] = "ImportEqualsDeclaration";
        SyntaxKind[SyntaxKind["ImportDeclaration"] = 254] = "ImportDeclaration";
        SyntaxKind[SyntaxKind["ImportClause"] = 255] = "ImportClause";
        SyntaxKind[SyntaxKind["NamespaceImport"] = 256] = "NamespaceImport";
        SyntaxKind[SyntaxKind["NamedImports"] = 257] = "NamedImports";
        SyntaxKind[SyntaxKind["ImportSpecifier"] = 258] = "ImportSpecifier";
        SyntaxKind[SyntaxKind["ExportAssignment"] = 259] = "ExportAssignment";
        SyntaxKind[SyntaxKind["ExportDeclaration"] = 260] = "ExportDeclaration";
        SyntaxKind[SyntaxKind["NamedExports"] = 261] = "NamedExports";
        SyntaxKind[SyntaxKind["NamespaceExport"] = 262] = "NamespaceExport";
        SyntaxKind[SyntaxKind["ExportSpecifier"] = 263] = "ExportSpecifier";
        SyntaxKind[SyntaxKind["MissingDeclaration"] = 264] = "MissingDeclaration";
        // Module references
        SyntaxKind[SyntaxKind["ExternalModuleReference"] = 265] = "ExternalModuleReference";
        // JSX
        SyntaxKind[SyntaxKind["JsxElement"] = 266] = "JsxElement";
        SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 267] = "JsxSelfClosingElement";
        SyntaxKind[SyntaxKind["JsxOpeningElement"] = 268] = "JsxOpeningElement";
        SyntaxKind[SyntaxKind["JsxClosingElement"] = 269] = "JsxClosingElement";
        SyntaxKind[SyntaxKind["JsxFragment"] = 270] = "JsxFragment";
        SyntaxKind[SyntaxKind["JsxOpeningFragment"] = 271] = "JsxOpeningFragment";
        SyntaxKind[SyntaxKind["JsxClosingFragment"] = 272] = "JsxClosingFragment";
        SyntaxKind[SyntaxKind["JsxAttribute"] = 273] = "JsxAttribute";
        SyntaxKind[SyntaxKind["JsxAttributes"] = 274] = "JsxAttributes";
        SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 275] = "JsxSpreadAttribute";
        SyntaxKind[SyntaxKind["JsxExpression"] = 276] = "JsxExpression";
        // Clauses
        SyntaxKind[SyntaxKind["CaseClause"] = 277] = "CaseClause";
        SyntaxKind[SyntaxKind["DefaultClause"] = 278] = "DefaultClause";
        SyntaxKind[SyntaxKind["HeritageClause"] = 279] = "HeritageClause";
        SyntaxKind[SyntaxKind["CatchClause"] = 280] = "CatchClause";
        // Property assignments
        SyntaxKind[SyntaxKind["PropertyAssignment"] = 281] = "PropertyAssignment";
        SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 282] = "ShorthandPropertyAssignment";
        SyntaxKind[SyntaxKind["SpreadAssignment"] = 283] = "SpreadAssignment";
        // Enum
        SyntaxKind[SyntaxKind["EnumMember"] = 284] = "EnumMember";
        // Unparsed
        SyntaxKind[SyntaxKind["UnparsedPrologue"] = 285] = "UnparsedPrologue";
        SyntaxKind[SyntaxKind["UnparsedPrepend"] = 286] = "UnparsedPrepend";
        SyntaxKind[SyntaxKind["UnparsedText"] = 287] = "UnparsedText";
        SyntaxKind[SyntaxKind["UnparsedInternalText"] = 288] = "UnparsedInternalText";
        SyntaxKind[SyntaxKind["UnparsedSyntheticReference"] = 289] = "UnparsedSyntheticReference";
        // Top-level nodes
        SyntaxKind[SyntaxKind["SourceFile"] = 290] = "SourceFile";
        SyntaxKind[SyntaxKind["Bundle"] = 291] = "Bundle";
        SyntaxKind[SyntaxKind["UnparsedSource"] = 292] = "UnparsedSource";
        SyntaxKind[SyntaxKind["InputFiles"] = 293] = "InputFiles";
        // JSDoc nodes
        SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 294] = "JSDocTypeExpression";
        // The * type
        SyntaxKind[SyntaxKind["JSDocAllType"] = 295] = "JSDocAllType";
        // The ? type
        SyntaxKind[SyntaxKind["JSDocUnknownType"] = 296] = "JSDocUnknownType";
        SyntaxKind[SyntaxKind["JSDocNullableType"] = 297] = "JSDocNullableType";
        SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 298] = "JSDocNonNullableType";
        SyntaxKind[SyntaxKind["JSDocOptionalType"] = 299] = "JSDocOptionalType";
        SyntaxKind[SyntaxKind["JSDocFunctionType"] = 300] = "JSDocFunctionType";
        SyntaxKind[SyntaxKind["JSDocVariadicType"] = 301] = "JSDocVariadicType";
        // https://jsdoc.app/about-namepaths.html
        SyntaxKind[SyntaxKind["JSDocNamepathType"] = 302] = "JSDocNamepathType";
        SyntaxKind[SyntaxKind["JSDocComment"] = 303] = "JSDocComment";
        SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 304] = "JSDocTypeLiteral";
        SyntaxKind[SyntaxKind["JSDocSignature"] = 305] = "JSDocSignature";
        SyntaxKind[SyntaxKind["JSDocTag"] = 306] = "JSDocTag";
        SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 307] = "JSDocAugmentsTag";
        SyntaxKind[SyntaxKind["JSDocImplementsTag"] = 308] = "JSDocImplementsTag";
        SyntaxKind[SyntaxKind["JSDocAuthorTag"] = 309] = "JSDocAuthorTag";
        SyntaxKind[SyntaxKind["JSDocClassTag"] = 310] = "JSDocClassTag";
        SyntaxKind[SyntaxKind["JSDocPublicTag"] = 311] = "JSDocPublicTag";
        SyntaxKind[SyntaxKind["JSDocPrivateTag"] = 312] = "JSDocPrivateTag";
        SyntaxKind[SyntaxKind["JSDocProtectedTag"] = 313] = "JSDocProtectedTag";
        SyntaxKind[SyntaxKind["JSDocReadonlyTag"] = 314] = "JSDocReadonlyTag";
        SyntaxKind[SyntaxKind["JSDocCallbackTag"] = 315] = "JSDocCallbackTag";
        SyntaxKind[SyntaxKind["JSDocEnumTag"] = 316] = "JSDocEnumTag";
        SyntaxKind[SyntaxKind["JSDocParameterTag"] = 317] = "JSDocParameterTag";
        SyntaxKind[SyntaxKind["JSDocReturnTag"] = 318] = "JSDocReturnTag";
        SyntaxKind[SyntaxKind["JSDocThisTag"] = 319] = "JSDocThisTag";
        SyntaxKind[SyntaxKind["JSDocTypeTag"] = 320] = "JSDocTypeTag";
        SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 321] = "JSDocTemplateTag";
        SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 322] = "JSDocTypedefTag";
        SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 323] = "JSDocPropertyTag";
        // Synthesized list
        SyntaxKind[SyntaxKind["SyntaxList"] = 324] = "SyntaxList";
        // Transformation nodes
        SyntaxKind[SyntaxKind["NotEmittedStatement"] = 325] = "NotEmittedStatement";
        SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 326] = "PartiallyEmittedExpression";
        SyntaxKind[SyntaxKind["CommaListExpression"] = 327] = "CommaListExpression";
        SyntaxKind[SyntaxKind["MergeDeclarationMarker"] = 328] = "MergeDeclarationMarker";
        SyntaxKind[SyntaxKind["EndOfDeclarationMarker"] = 329] = "EndOfDeclarationMarker";
        SyntaxKind[SyntaxKind["SyntheticReferenceExpression"] = 330] = "SyntheticReferenceExpression";
        // Enum value count
        SyntaxKind[SyntaxKind["Count"] = 331] = "Count";
        // Markers
        SyntaxKind[SyntaxKind["FirstAssignment"] = 62] = "FirstAssignment";
        SyntaxKind[SyntaxKind["LastAssignment"] = 74] = "LastAssignment";
        SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 63] = "FirstCompoundAssignment";
        SyntaxKind[SyntaxKind["LastCompoundAssignment"] = 74] = "LastCompoundAssignment";
        SyntaxKind[SyntaxKind["FirstReservedWord"] = 77] = "FirstReservedWord";
        SyntaxKind[SyntaxKind["LastReservedWord"] = 112] = "LastReservedWord";
        SyntaxKind[SyntaxKind["FirstKeyword"] = 77] = "FirstKeyword";
        SyntaxKind[SyntaxKind["LastKeyword"] = 152] = "LastKeyword";
        SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 113] = "FirstFutureReservedWord";
        SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 121] = "LastFutureReservedWord";
        SyntaxKind[SyntaxKind["FirstTypeNode"] = 168] = "FirstTypeNode";
        SyntaxKind[SyntaxKind["LastTypeNode"] = 188] = "LastTypeNode";
        SyntaxKind[SyntaxKind["FirstPunctuation"] = 18] = "FirstPunctuation";
        SyntaxKind[SyntaxKind["LastPunctuation"] = 74] = "LastPunctuation";
        SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken";
        SyntaxKind[SyntaxKind["LastToken"] = 152] = "LastToken";
        SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken";
        SyntaxKind[SyntaxKind["LastTriviaToken"] = 7] = "LastTriviaToken";
        SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken";
        SyntaxKind[SyntaxKind["LastLiteralToken"] = 14] = "LastLiteralToken";
        SyntaxKind[SyntaxKind["FirstTemplateToken"] = 14] = "FirstTemplateToken";
        SyntaxKind[SyntaxKind["LastTemplateToken"] = 17] = "LastTemplateToken";
        SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 29] = "FirstBinaryOperator";
        SyntaxKind[SyntaxKind["LastBinaryOperator"] = 74] = "LastBinaryOperator";
        SyntaxKind[SyntaxKind["FirstStatement"] = 225] = "FirstStatement";
        SyntaxKind[SyntaxKind["LastStatement"] = 241] = "LastStatement";
        SyntaxKind[SyntaxKind["FirstNode"] = 153] = "FirstNode";
        SyntaxKind[SyntaxKind["FirstJSDocNode"] = 294] = "FirstJSDocNode";
        SyntaxKind[SyntaxKind["LastJSDocNode"] = 323] = "LastJSDocNode";
        SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 306] = "FirstJSDocTagNode";
        SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 323] = "LastJSDocTagNode";
        /* @internal */ SyntaxKind[SyntaxKind["FirstContextualKeyword"] = 122] = "FirstContextualKeyword";
        /* @internal */ SyntaxKind[SyntaxKind["LastContextualKeyword"] = 152] = "LastContextualKeyword";
    })(SyntaxKind = ts.SyntaxKind || (ts.SyntaxKind = {}));
    var NodeFlags;
    (function (NodeFlags) {
        NodeFlags[NodeFlags["None"] = 0] = "None";
        NodeFlags[NodeFlags["Let"] = 1] = "Let";
        NodeFlags[NodeFlags["Const"] = 2] = "Const";
        NodeFlags[NodeFlags["NestedNamespace"] = 4] = "NestedNamespace";
        NodeFlags[NodeFlags["Synthesized"] = 8] = "Synthesized";
        NodeFlags[NodeFlags["Namespace"] = 16] = "Namespace";
        NodeFlags[NodeFlags["OptionalChain"] = 32] = "OptionalChain";
        NodeFlags[NodeFlags["ExportContext"] = 64] = "ExportContext";
        NodeFlags[NodeFlags["ContainsThis"] = 128] = "ContainsThis";
        NodeFlags[NodeFlags["HasImplicitReturn"] = 256] = "HasImplicitReturn";
        NodeFlags[NodeFlags["HasExplicitReturn"] = 512] = "HasExplicitReturn";
        NodeFlags[NodeFlags["GlobalAugmentation"] = 1024] = "GlobalAugmentation";
        NodeFlags[NodeFlags["HasAsyncFunctions"] = 2048] = "HasAsyncFunctions";
        NodeFlags[NodeFlags["DisallowInContext"] = 4096] = "DisallowInContext";
        NodeFlags[NodeFlags["YieldContext"] = 8192] = "YieldContext";
        NodeFlags[NodeFlags["DecoratorContext"] = 16384] = "DecoratorContext";
        NodeFlags[NodeFlags["AwaitContext"] = 32768] = "AwaitContext";
        NodeFlags[NodeFlags["ThisNodeHasError"] = 65536] = "ThisNodeHasError";
        NodeFlags[NodeFlags["JavaScriptFile"] = 131072] = "JavaScriptFile";
        NodeFlags[NodeFlags["ThisNodeOrAnySubNodesHasError"] = 262144] = "ThisNodeOrAnySubNodesHasError";
        NodeFlags[NodeFlags["HasAggregatedChildData"] = 524288] = "HasAggregatedChildData";
        // These flags will be set when the parser encounters a dynamic import expression or 'import.meta' to avoid
        // walking the tree if the flags are not set. However, these flags are just a approximation
        // (hence why it's named "PossiblyContainsDynamicImport") because once set, the flags never get cleared.
        // During editing, if a dynamic import is removed, incremental parsing will *NOT* clear this flag.
        // This means that the tree will always be traversed during module resolution, or when looking for external module indicators.
        // However, the removal operation should not occur often and in the case of the
        // removal, it is likely that users will add the import anyway.
        // The advantage of this approach is its simplicity. For the case of batch compilation,
        // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
        /* @internal */ NodeFlags[NodeFlags["PossiblyContainsDynamicImport"] = 1048576] = "PossiblyContainsDynamicImport";
        /* @internal */ NodeFlags[NodeFlags["PossiblyContainsImportMeta"] = 2097152] = "PossiblyContainsImportMeta";
        NodeFlags[NodeFlags["JSDoc"] = 4194304] = "JSDoc";
        /* @internal */ NodeFlags[NodeFlags["Ambient"] = 8388608] = "Ambient";
        /* @internal */ NodeFlags[NodeFlags["InWithStatement"] = 16777216] = "InWithStatement";
        NodeFlags[NodeFlags["JsonFile"] = 33554432] = "JsonFile";
        /* @internal */ NodeFlags[NodeFlags["TypeCached"] = 67108864] = "TypeCached";
        NodeFlags[NodeFlags["BlockScoped"] = 3] = "BlockScoped";
        NodeFlags[NodeFlags["ReachabilityCheckFlags"] = 768] = "ReachabilityCheckFlags";
        NodeFlags[NodeFlags["ReachabilityAndEmitFlags"] = 2816] = "ReachabilityAndEmitFlags";
        // Parsing context flags
        NodeFlags[NodeFlags["ContextFlags"] = 25358336] = "ContextFlags";
        // Exclude these flags when parsing a Type
        NodeFlags[NodeFlags["TypeExcludesFlags"] = 40960] = "TypeExcludesFlags";
        // Represents all flags that are potentially set once and
        // never cleared on SourceFiles which get re-used in between incremental parses.
        // See the comment above on `PossiblyContainsDynamicImport` and `PossiblyContainsImportMeta`.
        /* @internal */ NodeFlags[NodeFlags["PermanentlySetIncrementalFlags"] = 3145728] = "PermanentlySetIncrementalFlags";
    })(NodeFlags = ts.NodeFlags || (ts.NodeFlags = {}));
    var ModifierFlags;
    (function (ModifierFlags) {
        ModifierFlags[ModifierFlags["None"] = 0] = "None";
        ModifierFlags[ModifierFlags["Export"] = 1] = "Export";
        ModifierFlags[ModifierFlags["Ambient"] = 2] = "Ambient";
        ModifierFlags[ModifierFlags["Public"] = 4] = "Public";
        ModifierFlags[ModifierFlags["Private"] = 8] = "Private";
        ModifierFlags[ModifierFlags["Protected"] = 16] = "Protected";
        ModifierFlags[ModifierFlags["Static"] = 32] = "Static";
        ModifierFlags[ModifierFlags["Readonly"] = 64] = "Readonly";
        ModifierFlags[ModifierFlags["Abstract"] = 128] = "Abstract";
        ModifierFlags[ModifierFlags["Async"] = 256] = "Async";
        ModifierFlags[ModifierFlags["Default"] = 512] = "Default";
        ModifierFlags[ModifierFlags["Const"] = 2048] = "Const";
        ModifierFlags[ModifierFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
        ModifierFlags[ModifierFlags["AccessibilityModifier"] = 28] = "AccessibilityModifier";
        // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
        ModifierFlags[ModifierFlags["ParameterPropertyModifier"] = 92] = "ParameterPropertyModifier";
        ModifierFlags[ModifierFlags["NonPublicAccessibilityModifier"] = 24] = "NonPublicAccessibilityModifier";
        ModifierFlags[ModifierFlags["TypeScriptModifier"] = 2270] = "TypeScriptModifier";
        ModifierFlags[ModifierFlags["ExportDefault"] = 513] = "ExportDefault";
        ModifierFlags[ModifierFlags["All"] = 3071] = "All";
    })(ModifierFlags = ts.ModifierFlags || (ts.ModifierFlags = {}));
    var JsxFlags;
    (function (JsxFlags) {
        JsxFlags[JsxFlags["None"] = 0] = "None";
        /** An element from a named property of the JSX.IntrinsicElements interface */
        JsxFlags[JsxFlags["IntrinsicNamedElement"] = 1] = "IntrinsicNamedElement";
        /** An element inferred from the string index signature of the JSX.IntrinsicElements interface */
        JsxFlags[JsxFlags["IntrinsicIndexedElement"] = 2] = "IntrinsicIndexedElement";
        JsxFlags[JsxFlags["IntrinsicElement"] = 3] = "IntrinsicElement";
    })(JsxFlags = ts.JsxFlags || (ts.JsxFlags = {}));
    /* @internal */
    var RelationComparisonResult;
    (function (RelationComparisonResult) {
        RelationComparisonResult[RelationComparisonResult["Succeeded"] = 1] = "Succeeded";
        RelationComparisonResult[RelationComparisonResult["Failed"] = 2] = "Failed";
        RelationComparisonResult[RelationComparisonResult["Reported"] = 4] = "Reported";
        RelationComparisonResult[RelationComparisonResult["ReportsUnmeasurable"] = 8] = "ReportsUnmeasurable";
        RelationComparisonResult[RelationComparisonResult["ReportsUnreliable"] = 16] = "ReportsUnreliable";
        RelationComparisonResult[RelationComparisonResult["ReportsMask"] = 24] = "ReportsMask";
    })(RelationComparisonResult = ts.RelationComparisonResult || (ts.RelationComparisonResult = {}));
    /*@internal*/
    var GeneratedIdentifierFlags;
    (function (GeneratedIdentifierFlags) {
        // Kinds
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["None"] = 0] = "None";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Auto"] = 1] = "Auto";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Loop"] = 2] = "Loop";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Unique"] = 3] = "Unique";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Node"] = 4] = "Node";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["KindMask"] = 7] = "KindMask";
        // Flags
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["ReservedInNestedScopes"] = 8] = "ReservedInNestedScopes";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["Optimistic"] = 16] = "Optimistic";
        GeneratedIdentifierFlags[GeneratedIdentifierFlags["FileLevel"] = 32] = "FileLevel";
    })(GeneratedIdentifierFlags = ts.GeneratedIdentifierFlags || (ts.GeneratedIdentifierFlags = {}));
    var TokenFlags;
    (function (TokenFlags) {
        TokenFlags[TokenFlags["None"] = 0] = "None";
        /* @internal */
        TokenFlags[TokenFlags["PrecedingLineBreak"] = 1] = "PrecedingLineBreak";
        /* @internal */
        TokenFlags[TokenFlags["PrecedingJSDocComment"] = 2] = "PrecedingJSDocComment";
        /* @internal */
        TokenFlags[TokenFlags["Unterminated"] = 4] = "Unterminated";
        /* @internal */
        TokenFlags[TokenFlags["ExtendedUnicodeEscape"] = 8] = "ExtendedUnicodeEscape";
        TokenFlags[TokenFlags["Scientific"] = 16] = "Scientific";
        TokenFlags[TokenFlags["Octal"] = 32] = "Octal";
        TokenFlags[TokenFlags["HexSpecifier"] = 64] = "HexSpecifier";
        TokenFlags[TokenFlags["BinarySpecifier"] = 128] = "BinarySpecifier";
        TokenFlags[TokenFlags["OctalSpecifier"] = 256] = "OctalSpecifier";
        /* @internal */
        TokenFlags[TokenFlags["ContainsSeparator"] = 512] = "ContainsSeparator";
        /* @internal */
        TokenFlags[TokenFlags["UnicodeEscape"] = 1024] = "UnicodeEscape";
        /* @internal */
        TokenFlags[TokenFlags["ContainsInvalidEscape"] = 2048] = "ContainsInvalidEscape";
        /* @internal */
        TokenFlags[TokenFlags["BinaryOrOctalSpecifier"] = 384] = "BinaryOrOctalSpecifier";
        /* @internal */
        TokenFlags[TokenFlags["NumericLiteralFlags"] = 1008] = "NumericLiteralFlags";
    })(TokenFlags = ts.TokenFlags || (ts.TokenFlags = {}));
    // NOTE: Ensure this is up-to-date with src/debug/debug.ts
    var FlowFlags;
    (function (FlowFlags) {
        FlowFlags[FlowFlags["Unreachable"] = 1] = "Unreachable";
        FlowFlags[FlowFlags["Start"] = 2] = "Start";
        FlowFlags[FlowFlags["BranchLabel"] = 4] = "BranchLabel";
        FlowFlags[FlowFlags["LoopLabel"] = 8] = "LoopLabel";
        FlowFlags[FlowFlags["Assignment"] = 16] = "Assignment";
        FlowFlags[FlowFlags["TrueCondition"] = 32] = "TrueCondition";
        FlowFlags[FlowFlags["FalseCondition"] = 64] = "FalseCondition";
        FlowFlags[FlowFlags["SwitchClause"] = 128] = "SwitchClause";
        FlowFlags[FlowFlags["ArrayMutation"] = 256] = "ArrayMutation";
        FlowFlags[FlowFlags["Call"] = 512] = "Call";
        FlowFlags[FlowFlags["ReduceLabel"] = 1024] = "ReduceLabel";
        FlowFlags[FlowFlags["Referenced"] = 2048] = "Referenced";
        FlowFlags[FlowFlags["Shared"] = 4096] = "Shared";
        FlowFlags[FlowFlags["Label"] = 12] = "Label";
        FlowFlags[FlowFlags["Condition"] = 96] = "Condition";
    })(FlowFlags = ts.FlowFlags || (ts.FlowFlags = {}));
    /* @internal */
    var CommentDirectiveType;
    (function (CommentDirectiveType) {
        CommentDirectiveType[CommentDirectiveType["ExpectError"] = 0] = "ExpectError";
        CommentDirectiveType[CommentDirectiveType["Ignore"] = 1] = "Ignore";
    })(CommentDirectiveType = ts.CommentDirectiveType || (ts.CommentDirectiveType = {}));
    var OperationCanceledException = /** @class */ (function () {
        function OperationCanceledException() {
        }
        return OperationCanceledException;
    }());
    ts.OperationCanceledException = OperationCanceledException;
    /*@internal*/
    var RefFileKind;
    (function (RefFileKind) {
        RefFileKind[RefFileKind["Import"] = 0] = "Import";
        RefFileKind[RefFileKind["ReferenceFile"] = 1] = "ReferenceFile";
        RefFileKind[RefFileKind["TypeReferenceDirective"] = 2] = "TypeReferenceDirective";
    })(RefFileKind = ts.RefFileKind || (ts.RefFileKind = {}));
    /* @internal */
    var StructureIsReused;
    (function (StructureIsReused) {
        StructureIsReused[StructureIsReused["Not"] = 0] = "Not";
        StructureIsReused[StructureIsReused["SafeModules"] = 1] = "SafeModules";
        StructureIsReused[StructureIsReused["Completely"] = 2] = "Completely";
    })(StructureIsReused = ts.StructureIsReused || (ts.StructureIsReused = {}));
    /** Return code used by getEmitOutput function to indicate status of the function */
    var ExitStatus;
    (function (ExitStatus) {
        // Compiler ran successfully.  Either this was a simple do-nothing compilation (for example,
        // when -version or -help was provided, or this was a normal compilation, no diagnostics
        // were produced, and all outputs were generated successfully.
        ExitStatus[ExitStatus["Success"] = 0] = "Success";
        // Diagnostics were produced and because of them no code was generated.
        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsSkipped"] = 1] = "DiagnosticsPresent_OutputsSkipped";
        // Diagnostics were produced and outputs were generated in spite of them.
        ExitStatus[ExitStatus["DiagnosticsPresent_OutputsGenerated"] = 2] = "DiagnosticsPresent_OutputsGenerated";
        // When build skipped because passed in project is invalid
        ExitStatus[ExitStatus["InvalidProject_OutputsSkipped"] = 3] = "InvalidProject_OutputsSkipped";
        // When build is skipped because project references form cycle
        ExitStatus[ExitStatus["ProjectReferenceCycle_OutputsSkipped"] = 4] = "ProjectReferenceCycle_OutputsSkipped";
        /** @deprecated Use ProjectReferenceCycle_OutputsSkipped instead. */
        ExitStatus[ExitStatus["ProjectReferenceCycle_OutputsSkupped"] = 4] = "ProjectReferenceCycle_OutputsSkupped";
    })(ExitStatus = ts.ExitStatus || (ts.ExitStatus = {}));
    /* @internal */
    var UnionReduction;
    (function (UnionReduction) {
        UnionReduction[UnionReduction["None"] = 0] = "None";
        UnionReduction[UnionReduction["Literal"] = 1] = "Literal";
        UnionReduction[UnionReduction["Subtype"] = 2] = "Subtype";
    })(UnionReduction = ts.UnionReduction || (ts.UnionReduction = {}));
    /* @internal */
    var ContextFlags;
    (function (ContextFlags) {
        ContextFlags[ContextFlags["None"] = 0] = "None";
        ContextFlags[ContextFlags["Signature"] = 1] = "Signature";
        ContextFlags[ContextFlags["NoConstraints"] = 2] = "NoConstraints";
        ContextFlags[ContextFlags["Completions"] = 4] = "Completions";
    })(ContextFlags = ts.ContextFlags || (ts.ContextFlags = {}));
    // NOTE: If modifying this enum, must modify `TypeFormatFlags` too!
    var NodeBuilderFlags;
    (function (NodeBuilderFlags) {
        NodeBuilderFlags[NodeBuilderFlags["None"] = 0] = "None";
        // Options
        NodeBuilderFlags[NodeBuilderFlags["NoTruncation"] = 1] = "NoTruncation";
        NodeBuilderFlags[NodeBuilderFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType";
        NodeBuilderFlags[NodeBuilderFlags["GenerateNamesForShadowedTypeParams"] = 4] = "GenerateNamesForShadowedTypeParams";
        NodeBuilderFlags[NodeBuilderFlags["UseStructuralFallback"] = 8] = "UseStructuralFallback";
        NodeBuilderFlags[NodeBuilderFlags["ForbidIndexedAccessSymbolReferences"] = 16] = "ForbidIndexedAccessSymbolReferences";
        NodeBuilderFlags[NodeBuilderFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
        NodeBuilderFlags[NodeBuilderFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType";
        NodeBuilderFlags[NodeBuilderFlags["UseOnlyExternalAliasing"] = 128] = "UseOnlyExternalAliasing";
        NodeBuilderFlags[NodeBuilderFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType";
        NodeBuilderFlags[NodeBuilderFlags["WriteTypeParametersInQualifiedName"] = 512] = "WriteTypeParametersInQualifiedName";
        NodeBuilderFlags[NodeBuilderFlags["MultilineObjectLiterals"] = 1024] = "MultilineObjectLiterals";
        NodeBuilderFlags[NodeBuilderFlags["WriteClassExpressionAsTypeLiteral"] = 2048] = "WriteClassExpressionAsTypeLiteral";
        NodeBuilderFlags[NodeBuilderFlags["UseTypeOfFunction"] = 4096] = "UseTypeOfFunction";
        NodeBuilderFlags[NodeBuilderFlags["OmitParameterModifiers"] = 8192] = "OmitParameterModifiers";
        NodeBuilderFlags[NodeBuilderFlags["UseAliasDefinedOutsideCurrentScope"] = 16384] = "UseAliasDefinedOutsideCurrentScope";
        NodeBuilderFlags[NodeBuilderFlags["UseSingleQuotesForStringLiteralType"] = 268435456] = "UseSingleQuotesForStringLiteralType";
        NodeBuilderFlags[NodeBuilderFlags["NoTypeReduction"] = 536870912] = "NoTypeReduction";
        // Error handling
        NodeBuilderFlags[NodeBuilderFlags["AllowThisInObjectLiteral"] = 32768] = "AllowThisInObjectLiteral";
        NodeBuilderFlags[NodeBuilderFlags["AllowQualifedNameInPlaceOfIdentifier"] = 65536] = "AllowQualifedNameInPlaceOfIdentifier";
        NodeBuilderFlags[NodeBuilderFlags["AllowAnonymousIdentifier"] = 131072] = "AllowAnonymousIdentifier";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyUnionOrIntersection"] = 262144] = "AllowEmptyUnionOrIntersection";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyTuple"] = 524288] = "AllowEmptyTuple";
        NodeBuilderFlags[NodeBuilderFlags["AllowUniqueESSymbolType"] = 1048576] = "AllowUniqueESSymbolType";
        NodeBuilderFlags[NodeBuilderFlags["AllowEmptyIndexInfoType"] = 2097152] = "AllowEmptyIndexInfoType";
        // Errors (cont.)
        NodeBuilderFlags[NodeBuilderFlags["AllowNodeModulesRelativePaths"] = 67108864] = "AllowNodeModulesRelativePaths";
        /* @internal */ NodeBuilderFlags[NodeBuilderFlags["DoNotIncludeSymbolChain"] = 134217728] = "DoNotIncludeSymbolChain";
        NodeBuilderFlags[NodeBuilderFlags["IgnoreErrors"] = 70221824] = "IgnoreErrors";
        // State
        NodeBuilderFlags[NodeBuilderFlags["InObjectTypeLiteral"] = 4194304] = "InObjectTypeLiteral";
        NodeBuilderFlags[NodeBuilderFlags["InTypeAlias"] = 8388608] = "InTypeAlias";
        NodeBuilderFlags[NodeBuilderFlags["InInitialEntityName"] = 16777216] = "InInitialEntityName";
        NodeBuilderFlags[NodeBuilderFlags["InReverseMappedType"] = 33554432] = "InReverseMappedType";
    })(NodeBuilderFlags = ts.NodeBuilderFlags || (ts.NodeBuilderFlags = {}));
    // Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment
    var TypeFormatFlags;
    (function (TypeFormatFlags) {
        TypeFormatFlags[TypeFormatFlags["None"] = 0] = "None";
        TypeFormatFlags[TypeFormatFlags["NoTruncation"] = 1] = "NoTruncation";
        TypeFormatFlags[TypeFormatFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType";
        // hole because there's a hole in node builder flags
        TypeFormatFlags[TypeFormatFlags["UseStructuralFallback"] = 8] = "UseStructuralFallback";
        // hole because there's a hole in node builder flags
        TypeFormatFlags[TypeFormatFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature";
        TypeFormatFlags[TypeFormatFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType";
        // hole because `UseOnlyExternalAliasing` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` instead
        TypeFormatFlags[TypeFormatFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType";
        // hole because `WriteTypeParametersInQualifiedName` is here in node builder flags, but functions which take old flags use `SymbolFormatFlags` for this instead
        TypeFormatFlags[TypeFormatFlags["MultilineObjectLiterals"] = 1024] = "MultilineObjectLiterals";
        TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 2048] = "WriteClassExpressionAsTypeLiteral";
        TypeFormatFlags[TypeFormatFlags["UseTypeOfFunction"] = 4096] = "UseTypeOfFunction";
        TypeFormatFlags[TypeFormatFlags["OmitParameterModifiers"] = 8192] = "OmitParameterModifiers";
        TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 16384] = "UseAliasDefinedOutsideCurrentScope";
        TypeFormatFlags[TypeFormatFlags["UseSingleQuotesForStringLiteralType"] = 268435456] = "UseSingleQuotesForStringLiteralType";
        TypeFormatFlags[TypeFormatFlags["NoTypeReduction"] = 536870912] = "NoTypeReduction";
        // Error Handling
        TypeFormatFlags[TypeFormatFlags["AllowUniqueESSymbolType"] = 1048576] = "AllowUniqueESSymbolType";
        // TypeFormatFlags exclusive
        TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 131072] = "AddUndefined";
        TypeFormatFlags[TypeFormatFlags["WriteArrowStyleSignature"] = 262144] = "WriteArrowStyleSignature";
        // State
        TypeFormatFlags[TypeFormatFlags["InArrayType"] = 524288] = "InArrayType";
        TypeFormatFlags[TypeFormatFlags["InElementType"] = 2097152] = "InElementType";
        TypeFormatFlags[TypeFormatFlags["InFirstTypeArgument"] = 4194304] = "InFirstTypeArgument";
        TypeFormatFlags[TypeFormatFlags["InTypeAlias"] = 8388608] = "InTypeAlias";
        /** @deprecated */ TypeFormatFlags[TypeFormatFlags["WriteOwnNameForAnyLike"] = 0] = "WriteOwnNameForAnyLike";
        TypeFormatFlags[TypeFormatFlags["NodeBuilderFlagsMask"] = 814775659] = "NodeBuilderFlagsMask";
    })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {}));
    var SymbolFormatFlags;
    (function (SymbolFormatFlags) {
        SymbolFormatFlags[SymbolFormatFlags["None"] = 0] = "None";
        // Write symbols's type argument if it is instantiated symbol
        // eg. class C<T> { p: T }   <-- Show p as C<T>.p here
        //     var a: C<number>;
        //     var p = a.p; <--- Here p is property of C<number> so show it as C<number>.p instead of just C.p
        SymbolFormatFlags[SymbolFormatFlags["WriteTypeParametersOrArguments"] = 1] = "WriteTypeParametersOrArguments";
        // Use only external alias information to get the symbol name in the given context
        // eg.  module m { export class c { } } import x = m.c;
        // When this flag is specified m.c will be used to refer to the class instead of alias symbol x
        SymbolFormatFlags[SymbolFormatFlags["UseOnlyExternalAliasing"] = 2] = "UseOnlyExternalAliasing";
        // Build symbol name using any nodes needed, instead of just components of an entity name
        SymbolFormatFlags[SymbolFormatFlags["AllowAnyNodeKind"] = 4] = "AllowAnyNodeKind";
        // Prefer aliases which are not directly visible
        SymbolFormatFlags[SymbolFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 8] = "UseAliasDefinedOutsideCurrentScope";
        // Skip building an accessible symbol chain
        /* @internal */ SymbolFormatFlags[SymbolFormatFlags["DoNotIncludeSymbolChain"] = 16] = "DoNotIncludeSymbolChain";
    })(SymbolFormatFlags = ts.SymbolFormatFlags || (ts.SymbolFormatFlags = {}));
    /* @internal */
    var SymbolAccessibility;
    (function (SymbolAccessibility) {
        SymbolAccessibility[SymbolAccessibility["Accessible"] = 0] = "Accessible";
        SymbolAccessibility[SymbolAccessibility["NotAccessible"] = 1] = "NotAccessible";
        SymbolAccessibility[SymbolAccessibility["CannotBeNamed"] = 2] = "CannotBeNamed";
    })(SymbolAccessibility = ts.SymbolAccessibility || (ts.SymbolAccessibility = {}));
    /* @internal */
    var SyntheticSymbolKind;
    (function (SyntheticSymbolKind) {
        SyntheticSymbolKind[SyntheticSymbolKind["UnionOrIntersection"] = 0] = "UnionOrIntersection";
        SyntheticSymbolKind[SyntheticSymbolKind["Spread"] = 1] = "Spread";
    })(SyntheticSymbolKind = ts.SyntheticSymbolKind || (ts.SyntheticSymbolKind = {}));
    var TypePredicateKind;
    (function (TypePredicateKind) {
        TypePredicateKind[TypePredicateKind["This"] = 0] = "This";
        TypePredicateKind[TypePredicateKind["Identifier"] = 1] = "Identifier";
        TypePredicateKind[TypePredicateKind["AssertsThis"] = 2] = "AssertsThis";
        TypePredicateKind[TypePredicateKind["AssertsIdentifier"] = 3] = "AssertsIdentifier";
    })(TypePredicateKind = ts.TypePredicateKind || (ts.TypePredicateKind = {}));
    /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */
    /* @internal */
    var TypeReferenceSerializationKind;
    (function (TypeReferenceSerializationKind) {
        // The TypeReferenceNode could not be resolved.
        // The type name should be emitted using a safe fallback.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Unknown"] = 0] = "Unknown";
        // The TypeReferenceNode resolves to a type with a constructor
        // function that can be reached at runtime (e.g. a `class`
        // declaration or a `var` declaration for the static side
        // of a type, such as the global `Promise` type in lib.d.ts).
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithConstructSignatureAndValue"] = 1] = "TypeWithConstructSignatureAndValue";
        // The TypeReferenceNode resolves to a Void-like, Nullable, or Never type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["VoidNullableOrNeverType"] = 2] = "VoidNullableOrNeverType";
        // The TypeReferenceNode resolves to a Number-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["NumberLikeType"] = 3] = "NumberLikeType";
        // The TypeReferenceNode resolves to a BigInt-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["BigIntLikeType"] = 4] = "BigIntLikeType";
        // The TypeReferenceNode resolves to a String-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["StringLikeType"] = 5] = "StringLikeType";
        // The TypeReferenceNode resolves to a Boolean-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["BooleanType"] = 6] = "BooleanType";
        // The TypeReferenceNode resolves to an Array-like type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ArrayLikeType"] = 7] = "ArrayLikeType";
        // The TypeReferenceNode resolves to the ESSymbol type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ESSymbolType"] = 8] = "ESSymbolType";
        // The TypeReferenceNode resolved to the global Promise constructor symbol.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["Promise"] = 9] = "Promise";
        // The TypeReferenceNode resolves to a Function type or a type with call signatures.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithCallSignature"] = 10] = "TypeWithCallSignature";
        // The TypeReferenceNode resolves to any other type.
        TypeReferenceSerializationKind[TypeReferenceSerializationKind["ObjectType"] = 11] = "ObjectType";
    })(TypeReferenceSerializationKind = ts.TypeReferenceSerializationKind || (ts.TypeReferenceSerializationKind = {}));
    var SymbolFlags;
    (function (SymbolFlags) {
        SymbolFlags[SymbolFlags["None"] = 0] = "None";
        SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable";
        SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable";
        SymbolFlags[SymbolFlags["Property"] = 4] = "Property";
        SymbolFlags[SymbolFlags["EnumMember"] = 8] = "EnumMember";
        SymbolFlags[SymbolFlags["Function"] = 16] = "Function";
        SymbolFlags[SymbolFlags["Class"] = 32] = "Class";
        SymbolFlags[SymbolFlags["Interface"] = 64] = "Interface";
        SymbolFlags[SymbolFlags["ConstEnum"] = 128] = "ConstEnum";
        SymbolFlags[SymbolFlags["RegularEnum"] = 256] = "RegularEnum";
        SymbolFlags[SymbolFlags["ValueModule"] = 512] = "ValueModule";
        SymbolFlags[SymbolFlags["NamespaceModule"] = 1024] = "NamespaceModule";
        SymbolFlags[SymbolFlags["TypeLiteral"] = 2048] = "TypeLiteral";
        SymbolFlags[SymbolFlags["ObjectLiteral"] = 4096] = "ObjectLiteral";
        SymbolFlags[SymbolFlags["Method"] = 8192] = "Method";
        SymbolFlags[SymbolFlags["Constructor"] = 16384] = "Constructor";
        SymbolFlags[SymbolFlags["GetAccessor"] = 32768] = "GetAccessor";
        SymbolFlags[SymbolFlags["SetAccessor"] = 65536] = "SetAccessor";
        SymbolFlags[SymbolFlags["Signature"] = 131072] = "Signature";
        SymbolFlags[SymbolFlags["TypeParameter"] = 262144] = "TypeParameter";
        SymbolFlags[SymbolFlags["TypeAlias"] = 524288] = "TypeAlias";
        SymbolFlags[SymbolFlags["ExportValue"] = 1048576] = "ExportValue";
        SymbolFlags[SymbolFlags["Alias"] = 2097152] = "Alias";
        SymbolFlags[SymbolFlags["Prototype"] = 4194304] = "Prototype";
        SymbolFlags[SymbolFlags["ExportStar"] = 8388608] = "ExportStar";
        SymbolFlags[SymbolFlags["Optional"] = 16777216] = "Optional";
        SymbolFlags[SymbolFlags["Transient"] = 33554432] = "Transient";
        SymbolFlags[SymbolFlags["Assignment"] = 67108864] = "Assignment";
        SymbolFlags[SymbolFlags["ModuleExports"] = 134217728] = "ModuleExports";
        /* @internal */
        SymbolFlags[SymbolFlags["All"] = 67108863] = "All";
        SymbolFlags[SymbolFlags["Enum"] = 384] = "Enum";
        SymbolFlags[SymbolFlags["Variable"] = 3] = "Variable";
        SymbolFlags[SymbolFlags["Value"] = 111551] = "Value";
        SymbolFlags[SymbolFlags["Type"] = 788968] = "Type";
        SymbolFlags[SymbolFlags["Namespace"] = 1920] = "Namespace";
        SymbolFlags[SymbolFlags["Module"] = 1536] = "Module";
        SymbolFlags[SymbolFlags["Accessor"] = 98304] = "Accessor";
        // Variables can be redeclared, but can not redeclare a block-scoped declaration with the
        // same name, or any other value that is not a variable, e.g. ValueModule or Class
        SymbolFlags[SymbolFlags["FunctionScopedVariableExcludes"] = 111550] = "FunctionScopedVariableExcludes";
        // Block-scoped declarations are not allowed to be re-declared
        // they can not merge with anything in the value space
        SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 111551] = "BlockScopedVariableExcludes";
        SymbolFlags[SymbolFlags["ParameterExcludes"] = 111551] = "ParameterExcludes";
        SymbolFlags[SymbolFlags["PropertyExcludes"] = 0] = "PropertyExcludes";
        SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 900095] = "EnumMemberExcludes";
        SymbolFlags[SymbolFlags["FunctionExcludes"] = 110991] = "FunctionExcludes";
        SymbolFlags[SymbolFlags["ClassExcludes"] = 899503] = "ClassExcludes";
        SymbolFlags[SymbolFlags["InterfaceExcludes"] = 788872] = "InterfaceExcludes";
        SymbolFlags[SymbolFlags["RegularEnumExcludes"] = 899327] = "RegularEnumExcludes";
        SymbolFlags[SymbolFlags["ConstEnumExcludes"] = 899967] = "ConstEnumExcludes";
        SymbolFlags[SymbolFlags["ValueModuleExcludes"] = 110735] = "ValueModuleExcludes";
        SymbolFlags[SymbolFlags["NamespaceModuleExcludes"] = 0] = "NamespaceModuleExcludes";
        SymbolFlags[SymbolFlags["MethodExcludes"] = 103359] = "MethodExcludes";
        SymbolFlags[SymbolFlags["GetAccessorExcludes"] = 46015] = "GetAccessorExcludes";
        SymbolFlags[SymbolFlags["SetAccessorExcludes"] = 78783] = "SetAccessorExcludes";
        SymbolFlags[SymbolFlags["TypeParameterExcludes"] = 526824] = "TypeParameterExcludes";
        SymbolFlags[SymbolFlags["TypeAliasExcludes"] = 788968] = "TypeAliasExcludes";
        SymbolFlags[SymbolFlags["AliasExcludes"] = 2097152] = "AliasExcludes";
        SymbolFlags[SymbolFlags["ModuleMember"] = 2623475] = "ModuleMember";
        SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal";
        SymbolFlags[SymbolFlags["BlockScoped"] = 418] = "BlockScoped";
        SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor";
        SymbolFlags[SymbolFlags["ClassMember"] = 106500] = "ClassMember";
        /* @internal */
        SymbolFlags[SymbolFlags["ExportSupportsDefaultModifier"] = 112] = "ExportSupportsDefaultModifier";
        /* @internal */
        SymbolFlags[SymbolFlags["ExportDoesNotSupportDefaultModifier"] = -113] = "ExportDoesNotSupportDefaultModifier";
        /* @internal */
        // The set of things we consider semantically classifiable.  Used to speed up the LS during
        // classification.
        SymbolFlags[SymbolFlags["Classifiable"] = 2885600] = "Classifiable";
        /* @internal */
        SymbolFlags[SymbolFlags["LateBindingContainer"] = 6256] = "LateBindingContainer";
    })(SymbolFlags = ts.SymbolFlags || (ts.SymbolFlags = {}));
    /* @internal */
    var EnumKind;
    (function (EnumKind) {
        EnumKind[EnumKind["Numeric"] = 0] = "Numeric";
        EnumKind[EnumKind["Literal"] = 1] = "Literal"; // Literal enum (each member has a TypeFlags.EnumLiteral type)
    })(EnumKind = ts.EnumKind || (ts.EnumKind = {}));
    /* @internal */
    var CheckFlags;
    (function (CheckFlags) {
        CheckFlags[CheckFlags["Instantiated"] = 1] = "Instantiated";
        CheckFlags[CheckFlags["SyntheticProperty"] = 2] = "SyntheticProperty";
        CheckFlags[CheckFlags["SyntheticMethod"] = 4] = "SyntheticMethod";
        CheckFlags[CheckFlags["Readonly"] = 8] = "Readonly";
        CheckFlags[CheckFlags["ReadPartial"] = 16] = "ReadPartial";
        CheckFlags[CheckFlags["WritePartial"] = 32] = "WritePartial";
        CheckFlags[CheckFlags["HasNonUniformType"] = 64] = "HasNonUniformType";
        CheckFlags[CheckFlags["HasLiteralType"] = 128] = "HasLiteralType";
        CheckFlags[CheckFlags["ContainsPublic"] = 256] = "ContainsPublic";
        CheckFlags[CheckFlags["ContainsProtected"] = 512] = "ContainsProtected";
        CheckFlags[CheckFlags["ContainsPrivate"] = 1024] = "ContainsPrivate";
        CheckFlags[CheckFlags["ContainsStatic"] = 2048] = "ContainsStatic";
        CheckFlags[CheckFlags["Late"] = 4096] = "Late";
        CheckFlags[CheckFlags["ReverseMapped"] = 8192] = "ReverseMapped";
        CheckFlags[CheckFlags["OptionalParameter"] = 16384] = "OptionalParameter";
        CheckFlags[CheckFlags["RestParameter"] = 32768] = "RestParameter";
        CheckFlags[CheckFlags["DeferredType"] = 65536] = "DeferredType";
        CheckFlags[CheckFlags["HasNeverType"] = 131072] = "HasNeverType";
        CheckFlags[CheckFlags["Mapped"] = 262144] = "Mapped";
        CheckFlags[CheckFlags["StripOptional"] = 524288] = "StripOptional";
        CheckFlags[CheckFlags["Synthetic"] = 6] = "Synthetic";
        CheckFlags[CheckFlags["Discriminant"] = 192] = "Discriminant";
        CheckFlags[CheckFlags["Partial"] = 48] = "Partial";
    })(CheckFlags = ts.CheckFlags || (ts.CheckFlags = {}));
    var InternalSymbolName;
    (function (InternalSymbolName) {
        InternalSymbolName["Call"] = "__call";
        InternalSymbolName["Constructor"] = "__constructor";
        InternalSymbolName["New"] = "__new";
        InternalSymbolName["Index"] = "__index";
        InternalSymbolName["ExportStar"] = "__export";
        InternalSymbolName["Global"] = "__global";
        InternalSymbolName["Missing"] = "__missing";
        InternalSymbolName["Type"] = "__type";
        InternalSymbolName["Object"] = "__object";
        InternalSymbolName["JSXAttributes"] = "__jsxAttributes";
        InternalSymbolName["Class"] = "__class";
        InternalSymbolName["Function"] = "__function";
        InternalSymbolName["Computed"] = "__computed";
        InternalSymbolName["Resolving"] = "__resolving__";
        InternalSymbolName["ExportEquals"] = "export=";
        InternalSymbolName["Default"] = "default";
        InternalSymbolName["This"] = "this";
    })(InternalSymbolName = ts.InternalSymbolName || (ts.InternalSymbolName = {}));
    /* @internal */
    var NodeCheckFlags;
    (function (NodeCheckFlags) {
        NodeCheckFlags[NodeCheckFlags["TypeChecked"] = 1] = "TypeChecked";
        NodeCheckFlags[NodeCheckFlags["LexicalThis"] = 2] = "LexicalThis";
        NodeCheckFlags[NodeCheckFlags["CaptureThis"] = 4] = "CaptureThis";
        NodeCheckFlags[NodeCheckFlags["CaptureNewTarget"] = 8] = "CaptureNewTarget";
        NodeCheckFlags[NodeCheckFlags["SuperInstance"] = 256] = "SuperInstance";
        NodeCheckFlags[NodeCheckFlags["SuperStatic"] = 512] = "SuperStatic";
        NodeCheckFlags[NodeCheckFlags["ContextChecked"] = 1024] = "ContextChecked";
        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuper"] = 2048] = "AsyncMethodWithSuper";
        NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuperBinding"] = 4096] = "AsyncMethodWithSuperBinding";
        NodeCheckFlags[NodeCheckFlags["CaptureArguments"] = 8192] = "CaptureArguments";
        NodeCheckFlags[NodeCheckFlags["EnumValuesComputed"] = 16384] = "EnumValuesComputed";
        NodeCheckFlags[NodeCheckFlags["LexicalModuleMergesWithClass"] = 32768] = "LexicalModuleMergesWithClass";
        NodeCheckFlags[NodeCheckFlags["LoopWithCapturedBlockScopedBinding"] = 65536] = "LoopWithCapturedBlockScopedBinding";
        NodeCheckFlags[NodeCheckFlags["ContainsCapturedBlockScopeBinding"] = 131072] = "ContainsCapturedBlockScopeBinding";
        NodeCheckFlags[NodeCheckFlags["CapturedBlockScopedBinding"] = 262144] = "CapturedBlockScopedBinding";
        NodeCheckFlags[NodeCheckFlags["BlockScopedBindingInLoop"] = 524288] = "BlockScopedBindingInLoop";
        NodeCheckFlags[NodeCheckFlags["ClassWithBodyScopedClassBinding"] = 1048576] = "ClassWithBodyScopedClassBinding";
        NodeCheckFlags[NodeCheckFlags["BodyScopedClassBinding"] = 2097152] = "BodyScopedClassBinding";
        NodeCheckFlags[NodeCheckFlags["NeedsLoopOutParameter"] = 4194304] = "NeedsLoopOutParameter";
        NodeCheckFlags[NodeCheckFlags["AssignmentsMarked"] = 8388608] = "AssignmentsMarked";
        NodeCheckFlags[NodeCheckFlags["ClassWithConstructorReference"] = 16777216] = "ClassWithConstructorReference";
        NodeCheckFlags[NodeCheckFlags["ConstructorReferenceInClass"] = 33554432] = "ConstructorReferenceInClass";
        NodeCheckFlags[NodeCheckFlags["ContainsClassWithPrivateIdentifiers"] = 67108864] = "ContainsClassWithPrivateIdentifiers";
    })(NodeCheckFlags = ts.NodeCheckFlags || (ts.NodeCheckFlags = {}));
    var TypeFlags;
    (function (TypeFlags) {
        TypeFlags[TypeFlags["Any"] = 1] = "Any";
        TypeFlags[TypeFlags["Unknown"] = 2] = "Unknown";
        TypeFlags[TypeFlags["String"] = 4] = "String";
        TypeFlags[TypeFlags["Number"] = 8] = "Number";
        TypeFlags[TypeFlags["Boolean"] = 16] = "Boolean";
        TypeFlags[TypeFlags["Enum"] = 32] = "Enum";
        TypeFlags[TypeFlags["BigInt"] = 64] = "BigInt";
        TypeFlags[TypeFlags["StringLiteral"] = 128] = "StringLiteral";
        TypeFlags[TypeFlags["NumberLiteral"] = 256] = "NumberLiteral";
        TypeFlags[TypeFlags["BooleanLiteral"] = 512] = "BooleanLiteral";
        TypeFlags[TypeFlags["EnumLiteral"] = 1024] = "EnumLiteral";
        TypeFlags[TypeFlags["BigIntLiteral"] = 2048] = "BigIntLiteral";
        TypeFlags[TypeFlags["ESSymbol"] = 4096] = "ESSymbol";
        TypeFlags[TypeFlags["UniqueESSymbol"] = 8192] = "UniqueESSymbol";
        TypeFlags[TypeFlags["Void"] = 16384] = "Void";
        TypeFlags[TypeFlags["Undefined"] = 32768] = "Undefined";
        TypeFlags[TypeFlags["Null"] = 65536] = "Null";
        TypeFlags[TypeFlags["Never"] = 131072] = "Never";
        TypeFlags[TypeFlags["TypeParameter"] = 262144] = "TypeParameter";
        TypeFlags[TypeFlags["Object"] = 524288] = "Object";
        TypeFlags[TypeFlags["Union"] = 1048576] = "Union";
        TypeFlags[TypeFlags["Intersection"] = 2097152] = "Intersection";
        TypeFlags[TypeFlags["Index"] = 4194304] = "Index";
        TypeFlags[TypeFlags["IndexedAccess"] = 8388608] = "IndexedAccess";
        TypeFlags[TypeFlags["Conditional"] = 16777216] = "Conditional";
        TypeFlags[TypeFlags["Substitution"] = 33554432] = "Substitution";
        TypeFlags[TypeFlags["NonPrimitive"] = 67108864] = "NonPrimitive";
        /* @internal */
        TypeFlags[TypeFlags["AnyOrUnknown"] = 3] = "AnyOrUnknown";
        /* @internal */
        TypeFlags[TypeFlags["Nullable"] = 98304] = "Nullable";
        TypeFlags[TypeFlags["Literal"] = 2944] = "Literal";
        TypeFlags[TypeFlags["Unit"] = 109440] = "Unit";
        TypeFlags[TypeFlags["StringOrNumberLiteral"] = 384] = "StringOrNumberLiteral";
        /* @internal */
        TypeFlags[TypeFlags["StringOrNumberLiteralOrUnique"] = 8576] = "StringOrNumberLiteralOrUnique";
        /* @internal */
        TypeFlags[TypeFlags["DefinitelyFalsy"] = 117632] = "DefinitelyFalsy";
        TypeFlags[TypeFlags["PossiblyFalsy"] = 117724] = "PossiblyFalsy";
        /* @internal */
        TypeFlags[TypeFlags["Intrinsic"] = 67359327] = "Intrinsic";
        /* @internal */
        TypeFlags[TypeFlags["Primitive"] = 131068] = "Primitive";
        TypeFlags[TypeFlags["StringLike"] = 132] = "StringLike";
        TypeFlags[TypeFlags["NumberLike"] = 296] = "NumberLike";
        TypeFlags[TypeFlags["BigIntLike"] = 2112] = "BigIntLike";
        TypeFlags[TypeFlags["BooleanLike"] = 528] = "BooleanLike";
        TypeFlags[TypeFlags["EnumLike"] = 1056] = "EnumLike";
        TypeFlags[TypeFlags["ESSymbolLike"] = 12288] = "ESSymbolLike";
        TypeFlags[TypeFlags["VoidLike"] = 49152] = "VoidLike";
        /* @internal */
        TypeFlags[TypeFlags["DisjointDomains"] = 67238908] = "DisjointDomains";
        TypeFlags[TypeFlags["UnionOrIntersection"] = 3145728] = "UnionOrIntersection";
        TypeFlags[TypeFlags["StructuredType"] = 3670016] = "StructuredType";
        TypeFlags[TypeFlags["TypeVariable"] = 8650752] = "TypeVariable";
        TypeFlags[TypeFlags["InstantiableNonPrimitive"] = 58982400] = "InstantiableNonPrimitive";
        TypeFlags[TypeFlags["InstantiablePrimitive"] = 4194304] = "InstantiablePrimitive";
        TypeFlags[TypeFlags["Instantiable"] = 63176704] = "Instantiable";
        TypeFlags[TypeFlags["StructuredOrInstantiable"] = 66846720] = "StructuredOrInstantiable";
        /* @internal */
        TypeFlags[TypeFlags["ObjectFlagsType"] = 3899393] = "ObjectFlagsType";
        /* @internal */
        TypeFlags[TypeFlags["Simplifiable"] = 25165824] = "Simplifiable";
        /* @internal */
        TypeFlags[TypeFlags["Substructure"] = 66584576] = "Substructure";
        // 'Narrowable' types are types where narrowing actually narrows.
        // This *should* be every type other than null, undefined, void, and never
        TypeFlags[TypeFlags["Narrowable"] = 133970943] = "Narrowable";
        TypeFlags[TypeFlags["NotUnionOrUnit"] = 67637251] = "NotUnionOrUnit";
        /* @internal */
        TypeFlags[TypeFlags["NotPrimitiveUnion"] = 66994211] = "NotPrimitiveUnion";
        // The following flags are aggregated during union and intersection type construction
        /* @internal */
        TypeFlags[TypeFlags["IncludesMask"] = 71041023] = "IncludesMask";
        // The following flags are used for different purposes during union and intersection type construction
        /* @internal */
        TypeFlags[TypeFlags["IncludesStructuredOrInstantiable"] = 262144] = "IncludesStructuredOrInstantiable";
        /* @internal */
        TypeFlags[TypeFlags["IncludesNonWideningType"] = 4194304] = "IncludesNonWideningType";
        /* @internal */
        TypeFlags[TypeFlags["IncludesWildcard"] = 8388608] = "IncludesWildcard";
        /* @internal */
        TypeFlags[TypeFlags["IncludesEmptyObject"] = 16777216] = "IncludesEmptyObject";
    })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {}));
    var ObjectFlags;
    (function (ObjectFlags) {
        ObjectFlags[ObjectFlags["Class"] = 1] = "Class";
        ObjectFlags[ObjectFlags["Interface"] = 2] = "Interface";
        ObjectFlags[ObjectFlags["Reference"] = 4] = "Reference";
        ObjectFlags[ObjectFlags["Tuple"] = 8] = "Tuple";
        ObjectFlags[ObjectFlags["Anonymous"] = 16] = "Anonymous";
        ObjectFlags[ObjectFlags["Mapped"] = 32] = "Mapped";
        ObjectFlags[ObjectFlags["Instantiated"] = 64] = "Instantiated";
        ObjectFlags[ObjectFlags["ObjectLiteral"] = 128] = "ObjectLiteral";
        ObjectFlags[ObjectFlags["EvolvingArray"] = 256] = "EvolvingArray";
        ObjectFlags[ObjectFlags["ObjectLiteralPatternWithComputedProperties"] = 512] = "ObjectLiteralPatternWithComputedProperties";
        ObjectFlags[ObjectFlags["ContainsSpread"] = 1024] = "ContainsSpread";
        ObjectFlags[ObjectFlags["ReverseMapped"] = 2048] = "ReverseMapped";
        ObjectFlags[ObjectFlags["JsxAttributes"] = 4096] = "JsxAttributes";
        ObjectFlags[ObjectFlags["MarkerType"] = 8192] = "MarkerType";
        ObjectFlags[ObjectFlags["JSLiteral"] = 16384] = "JSLiteral";
        ObjectFlags[ObjectFlags["FreshLiteral"] = 32768] = "FreshLiteral";
        ObjectFlags[ObjectFlags["ArrayLiteral"] = 65536] = "ArrayLiteral";
        ObjectFlags[ObjectFlags["ObjectRestType"] = 131072] = "ObjectRestType";
        /* @internal */
        ObjectFlags[ObjectFlags["PrimitiveUnion"] = 262144] = "PrimitiveUnion";
        /* @internal */
        ObjectFlags[ObjectFlags["ContainsWideningType"] = 524288] = "ContainsWideningType";
        /* @internal */
        ObjectFlags[ObjectFlags["ContainsObjectOrArrayLiteral"] = 1048576] = "ContainsObjectOrArrayLiteral";
        /* @internal */
        ObjectFlags[ObjectFlags["NonInferrableType"] = 2097152] = "NonInferrableType";
        /* @internal */
        ObjectFlags[ObjectFlags["IsGenericObjectTypeComputed"] = 4194304] = "IsGenericObjectTypeComputed";
        /* @internal */
        ObjectFlags[ObjectFlags["IsGenericObjectType"] = 8388608] = "IsGenericObjectType";
        /* @internal */
        ObjectFlags[ObjectFlags["IsGenericIndexTypeComputed"] = 16777216] = "IsGenericIndexTypeComputed";
        /* @internal */
        ObjectFlags[ObjectFlags["IsGenericIndexType"] = 33554432] = "IsGenericIndexType";
        /* @internal */
        ObjectFlags[ObjectFlags["CouldContainTypeVariablesComputed"] = 67108864] = "CouldContainTypeVariablesComputed";
        /* @internal */
        ObjectFlags[ObjectFlags["CouldContainTypeVariables"] = 134217728] = "CouldContainTypeVariables";
        /* @internal */
        ObjectFlags[ObjectFlags["ContainsIntersections"] = 268435456] = "ContainsIntersections";
        /* @internal */
        ObjectFlags[ObjectFlags["IsNeverIntersectionComputed"] = 268435456] = "IsNeverIntersectionComputed";
        /* @internal */
        ObjectFlags[ObjectFlags["IsNeverIntersection"] = 536870912] = "IsNeverIntersection";
        ObjectFlags[ObjectFlags["ClassOrInterface"] = 3] = "ClassOrInterface";
        /* @internal */
        ObjectFlags[ObjectFlags["RequiresWidening"] = 1572864] = "RequiresWidening";
        /* @internal */
        ObjectFlags[ObjectFlags["PropagatingFlags"] = 3670016] = "PropagatingFlags";
    })(ObjectFlags = ts.ObjectFlags || (ts.ObjectFlags = {}));
    /* @internal */
    var VarianceFlags;
    (function (VarianceFlags) {
        VarianceFlags[VarianceFlags["Invariant"] = 0] = "Invariant";
        VarianceFlags[VarianceFlags["Covariant"] = 1] = "Covariant";
        VarianceFlags[VarianceFlags["Contravariant"] = 2] = "Contravariant";
        VarianceFlags[VarianceFlags["Bivariant"] = 3] = "Bivariant";
        VarianceFlags[VarianceFlags["Independent"] = 4] = "Independent";
        VarianceFlags[VarianceFlags["VarianceMask"] = 7] = "VarianceMask";
        VarianceFlags[VarianceFlags["Unmeasurable"] = 8] = "Unmeasurable";
        VarianceFlags[VarianceFlags["Unreliable"] = 16] = "Unreliable";
        VarianceFlags[VarianceFlags["AllowsStructuralFallback"] = 24] = "AllowsStructuralFallback";
    })(VarianceFlags = ts.VarianceFlags || (ts.VarianceFlags = {}));
    /* @internal */
    var JsxReferenceKind;
    (function (JsxReferenceKind) {
        JsxReferenceKind[JsxReferenceKind["Component"] = 0] = "Component";
        JsxReferenceKind[JsxReferenceKind["Function"] = 1] = "Function";
        JsxReferenceKind[JsxReferenceKind["Mixed"] = 2] = "Mixed";
    })(JsxReferenceKind = ts.JsxReferenceKind || (ts.JsxReferenceKind = {}));
    var SignatureKind;
    (function (SignatureKind) {
        SignatureKind[SignatureKind["Call"] = 0] = "Call";
        SignatureKind[SignatureKind["Construct"] = 1] = "Construct";
    })(SignatureKind = ts.SignatureKind || (ts.SignatureKind = {}));
    /* @internal */
    var SignatureFlags;
    (function (SignatureFlags) {
        SignatureFlags[SignatureFlags["None"] = 0] = "None";
        SignatureFlags[SignatureFlags["HasRestParameter"] = 1] = "HasRestParameter";
        SignatureFlags[SignatureFlags["HasLiteralTypes"] = 2] = "HasLiteralTypes";
        SignatureFlags[SignatureFlags["IsInnerCallChain"] = 4] = "IsInnerCallChain";
        SignatureFlags[SignatureFlags["IsOuterCallChain"] = 8] = "IsOuterCallChain";
        SignatureFlags[SignatureFlags["IsUntypedSignatureInJSFile"] = 16] = "IsUntypedSignatureInJSFile";
        // We do not propagate `IsInnerCallChain` to instantiated signatures, as that would result in us
        // attempting to add `| undefined` on each recursive call to `getReturnTypeOfSignature` when
        // instantiating the return type.
        SignatureFlags[SignatureFlags["PropagatingFlags"] = 3] = "PropagatingFlags";
        SignatureFlags[SignatureFlags["CallChainFlags"] = 12] = "CallChainFlags";
    })(SignatureFlags = ts.SignatureFlags || (ts.SignatureFlags = {}));
    var IndexKind;
    (function (IndexKind) {
        IndexKind[IndexKind["String"] = 0] = "String";
        IndexKind[IndexKind["Number"] = 1] = "Number";
    })(IndexKind = ts.IndexKind || (ts.IndexKind = {}));
    /* @internal */
    var TypeMapKind;
    (function (TypeMapKind) {
        TypeMapKind[TypeMapKind["Simple"] = 0] = "Simple";
        TypeMapKind[TypeMapKind["Array"] = 1] = "Array";
        TypeMapKind[TypeMapKind["Function"] = 2] = "Function";
        TypeMapKind[TypeMapKind["Composite"] = 3] = "Composite";
        TypeMapKind[TypeMapKind["Merged"] = 4] = "Merged";
    })(TypeMapKind = ts.TypeMapKind || (ts.TypeMapKind = {}));
    var InferencePriority;
    (function (InferencePriority) {
        InferencePriority[InferencePriority["NakedTypeVariable"] = 1] = "NakedTypeVariable";
        InferencePriority[InferencePriority["HomomorphicMappedType"] = 2] = "HomomorphicMappedType";
        InferencePriority[InferencePriority["PartialHomomorphicMappedType"] = 4] = "PartialHomomorphicMappedType";
        InferencePriority[InferencePriority["MappedTypeConstraint"] = 8] = "MappedTypeConstraint";
        InferencePriority[InferencePriority["ContravariantConditional"] = 16] = "ContravariantConditional";
        InferencePriority[InferencePriority["ReturnType"] = 32] = "ReturnType";
        InferencePriority[InferencePriority["LiteralKeyof"] = 64] = "LiteralKeyof";
        InferencePriority[InferencePriority["NoConstraints"] = 128] = "NoConstraints";
        InferencePriority[InferencePriority["AlwaysStrict"] = 256] = "AlwaysStrict";
        InferencePriority[InferencePriority["MaxValue"] = 512] = "MaxValue";
        InferencePriority[InferencePriority["PriorityImpliesCombination"] = 104] = "PriorityImpliesCombination";
        InferencePriority[InferencePriority["Circularity"] = -1] = "Circularity";
    })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {}));
    /* @internal */
    var InferenceFlags;
    (function (InferenceFlags) {
        InferenceFlags[InferenceFlags["None"] = 0] = "None";
        InferenceFlags[InferenceFlags["NoDefault"] = 1] = "NoDefault";
        InferenceFlags[InferenceFlags["AnyDefault"] = 2] = "AnyDefault";
        InferenceFlags[InferenceFlags["SkippedGenericFunction"] = 4] = "SkippedGenericFunction";
    })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {}));
    /**
     * Ternary values are defined such that
     * x & y is False if either x or y is False.
     * x & y is Maybe if either x or y is Maybe, but neither x or y is False.
     * x & y is True if both x and y are True.
     * x | y is False if both x and y are False.
     * x | y is Maybe if either x or y is Maybe, but neither x or y is True.
     * x | y is True if either x or y is True.
     */
    /* @internal */
    var Ternary;
    (function (Ternary) {
        Ternary[Ternary["False"] = 0] = "False";
        Ternary[Ternary["Maybe"] = 1] = "Maybe";
        Ternary[Ternary["True"] = -1] = "True";
    })(Ternary = ts.Ternary || (ts.Ternary = {}));
    /* @internal */
    var AssignmentDeclarationKind;
    (function (AssignmentDeclarationKind) {
        AssignmentDeclarationKind[AssignmentDeclarationKind["None"] = 0] = "None";
        /// exports.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ExportsProperty"] = 1] = "ExportsProperty";
        /// module.exports = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ModuleExports"] = 2] = "ModuleExports";
        /// className.prototype.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["PrototypeProperty"] = 3] = "PrototypeProperty";
        /// this.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["ThisProperty"] = 4] = "ThisProperty";
        // F.name = expr
        AssignmentDeclarationKind[AssignmentDeclarationKind["Property"] = 5] = "Property";
        // F.prototype = { ... }
        AssignmentDeclarationKind[AssignmentDeclarationKind["Prototype"] = 6] = "Prototype";
        // Object.defineProperty(x, 'name', { value: any, writable?: boolean (false by default) });
        // Object.defineProperty(x, 'name', { get: Function, set: Function });
        // Object.defineProperty(x, 'name', { get: Function });
        // Object.defineProperty(x, 'name', { set: Function });
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePropertyValue"] = 7] = "ObjectDefinePropertyValue";
        // Object.defineProperty(exports || module.exports, 'name', ...);
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePropertyExports"] = 8] = "ObjectDefinePropertyExports";
        // Object.defineProperty(Foo.prototype, 'name', ...);
        AssignmentDeclarationKind[AssignmentDeclarationKind["ObjectDefinePrototypeProperty"] = 9] = "ObjectDefinePrototypeProperty";
    })(AssignmentDeclarationKind = ts.AssignmentDeclarationKind || (ts.AssignmentDeclarationKind = {}));
    var DiagnosticCategory;
    (function (DiagnosticCategory) {
        DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning";
        DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error";
        DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion";
        DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message";
    })(DiagnosticCategory = ts.DiagnosticCategory || (ts.DiagnosticCategory = {}));
    /* @internal */
    function diagnosticCategoryName(d, lowerCase) {
        if (lowerCase === void 0) { lowerCase = true; }
        var name = DiagnosticCategory[d.category];
        return lowerCase ? name.toLowerCase() : name;
    }
    ts.diagnosticCategoryName = diagnosticCategoryName;
    var ModuleResolutionKind;
    (function (ModuleResolutionKind) {
        ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic";
        ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs";
    })(ModuleResolutionKind = ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {}));
    var WatchFileKind;
    (function (WatchFileKind) {
        WatchFileKind[WatchFileKind["FixedPollingInterval"] = 0] = "FixedPollingInterval";
        WatchFileKind[WatchFileKind["PriorityPollingInterval"] = 1] = "PriorityPollingInterval";
        WatchFileKind[WatchFileKind["DynamicPriorityPolling"] = 2] = "DynamicPriorityPolling";
        WatchFileKind[WatchFileKind["UseFsEvents"] = 3] = "UseFsEvents";
        WatchFileKind[WatchFileKind["UseFsEventsOnParentDirectory"] = 4] = "UseFsEventsOnParentDirectory";
    })(WatchFileKind = ts.WatchFileKind || (ts.WatchFileKind = {}));
    var WatchDirectoryKind;
    (function (WatchDirectoryKind) {
        WatchDirectoryKind[WatchDirectoryKind["UseFsEvents"] = 0] = "UseFsEvents";
        WatchDirectoryKind[WatchDirectoryKind["FixedPollingInterval"] = 1] = "FixedPollingInterval";
        WatchDirectoryKind[WatchDirectoryKind["DynamicPriorityPolling"] = 2] = "DynamicPriorityPolling";
    })(WatchDirectoryKind = ts.WatchDirectoryKind || (ts.WatchDirectoryKind = {}));
    var PollingWatchKind;
    (function (PollingWatchKind) {
        PollingWatchKind[PollingWatchKind["FixedInterval"] = 0] = "FixedInterval";
        PollingWatchKind[PollingWatchKind["PriorityInterval"] = 1] = "PriorityInterval";
        PollingWatchKind[PollingWatchKind["DynamicPriority"] = 2] = "DynamicPriority";
    })(PollingWatchKind = ts.PollingWatchKind || (ts.PollingWatchKind = {}));
    var ModuleKind;
    (function (ModuleKind) {
        ModuleKind[ModuleKind["None"] = 0] = "None";
        ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS";
        ModuleKind[ModuleKind["AMD"] = 2] = "AMD";
        ModuleKind[ModuleKind["UMD"] = 3] = "UMD";
        ModuleKind[ModuleKind["System"] = 4] = "System";
        // NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind.
        //       Non-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES
        //       module kind).
        ModuleKind[ModuleKind["ES2015"] = 5] = "ES2015";
        ModuleKind[ModuleKind["ES2020"] = 6] = "ES2020";
        ModuleKind[ModuleKind["ESNext"] = 99] = "ESNext";
    })(ModuleKind = ts.ModuleKind || (ts.ModuleKind = {}));
    var JsxEmit;
    (function (JsxEmit) {
        JsxEmit[JsxEmit["None"] = 0] = "None";
        JsxEmit[JsxEmit["Preserve"] = 1] = "Preserve";
        JsxEmit[JsxEmit["React"] = 2] = "React";
        JsxEmit[JsxEmit["ReactNative"] = 3] = "ReactNative";
    })(JsxEmit = ts.JsxEmit || (ts.JsxEmit = {}));
    var ImportsNotUsedAsValues;
    (function (ImportsNotUsedAsValues) {
        ImportsNotUsedAsValues[ImportsNotUsedAsValues["Remove"] = 0] = "Remove";
        ImportsNotUsedAsValues[ImportsNotUsedAsValues["Preserve"] = 1] = "Preserve";
        ImportsNotUsedAsValues[ImportsNotUsedAsValues["Error"] = 2] = "Error";
    })(ImportsNotUsedAsValues = ts.ImportsNotUsedAsValues || (ts.ImportsNotUsedAsValues = {}));
    var NewLineKind;
    (function (NewLineKind) {
        NewLineKind[NewLineKind["CarriageReturnLineFeed"] = 0] = "CarriageReturnLineFeed";
        NewLineKind[NewLineKind["LineFeed"] = 1] = "LineFeed";
    })(NewLineKind = ts.NewLineKind || (ts.NewLineKind = {}));
    var ScriptKind;
    (function (ScriptKind) {
        ScriptKind[ScriptKind["Unknown"] = 0] = "Unknown";
        ScriptKind[ScriptKind["JS"] = 1] = "JS";
        ScriptKind[ScriptKind["JSX"] = 2] = "JSX";
        ScriptKind[ScriptKind["TS"] = 3] = "TS";
        ScriptKind[ScriptKind["TSX"] = 4] = "TSX";
        ScriptKind[ScriptKind["External"] = 5] = "External";
        ScriptKind[ScriptKind["JSON"] = 6] = "JSON";
        /**
         * Used on extensions that doesn't define the ScriptKind but the content defines it.
         * Deferred extensions are going to be included in all project contexts.
         */
        ScriptKind[ScriptKind["Deferred"] = 7] = "Deferred";
    })(ScriptKind = ts.ScriptKind || (ts.ScriptKind = {}));
    var ScriptTarget;
    (function (ScriptTarget) {
        ScriptTarget[ScriptTarget["ES3"] = 0] = "ES3";
        ScriptTarget[ScriptTarget["ES5"] = 1] = "ES5";
        ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015";
        ScriptTarget[ScriptTarget["ES2016"] = 3] = "ES2016";
        ScriptTarget[ScriptTarget["ES2017"] = 4] = "ES2017";
        ScriptTarget[ScriptTarget["ES2018"] = 5] = "ES2018";
        ScriptTarget[ScriptTarget["ES2019"] = 6] = "ES2019";
        ScriptTarget[ScriptTarget["ES2020"] = 7] = "ES2020";
        ScriptTarget[ScriptTarget["ESNext"] = 99] = "ESNext";
        ScriptTarget[ScriptTarget["JSON"] = 100] = "JSON";
        ScriptTarget[ScriptTarget["Latest"] = 99] = "Latest";
    })(ScriptTarget = ts.ScriptTarget || (ts.ScriptTarget = {}));
    var LanguageVariant;
    (function (LanguageVariant) {
        LanguageVariant[LanguageVariant["Standard"] = 0] = "Standard";
        LanguageVariant[LanguageVariant["JSX"] = 1] = "JSX";
    })(LanguageVariant = ts.LanguageVariant || (ts.LanguageVariant = {}));
    var WatchDirectoryFlags;
    (function (WatchDirectoryFlags) {
        WatchDirectoryFlags[WatchDirectoryFlags["None"] = 0] = "None";
        WatchDirectoryFlags[WatchDirectoryFlags["Recursive"] = 1] = "Recursive";
    })(WatchDirectoryFlags = ts.WatchDirectoryFlags || (ts.WatchDirectoryFlags = {}));
    /* @internal */
    var CharacterCodes;
    (function (CharacterCodes) {
        CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter";
        CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter";
        CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed";
        CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn";
        CharacterCodes[CharacterCodes["lineSeparator"] = 8232] = "lineSeparator";
        CharacterCodes[CharacterCodes["paragraphSeparator"] = 8233] = "paragraphSeparator";
        CharacterCodes[CharacterCodes["nextLine"] = 133] = "nextLine";
        // Unicode 3.0 space characters
        CharacterCodes[CharacterCodes["space"] = 32] = "space";
        CharacterCodes[CharacterCodes["nonBreakingSpace"] = 160] = "nonBreakingSpace";
        CharacterCodes[CharacterCodes["enQuad"] = 8192] = "enQuad";
        CharacterCodes[CharacterCodes["emQuad"] = 8193] = "emQuad";
        CharacterCodes[CharacterCodes["enSpace"] = 8194] = "enSpace";
        CharacterCodes[CharacterCodes["emSpace"] = 8195] = "emSpace";
        CharacterCodes[CharacterCodes["threePerEmSpace"] = 8196] = "threePerEmSpace";
        CharacterCodes[CharacterCodes["fourPerEmSpace"] = 8197] = "fourPerEmSpace";
        CharacterCodes[CharacterCodes["sixPerEmSpace"] = 8198] = "sixPerEmSpace";
        CharacterCodes[CharacterCodes["figureSpace"] = 8199] = "figureSpace";
        CharacterCodes[CharacterCodes["punctuationSpace"] = 8200] = "punctuationSpace";
        CharacterCodes[CharacterCodes["thinSpace"] = 8201] = "thinSpace";
        CharacterCodes[CharacterCodes["hairSpace"] = 8202] = "hairSpace";
        CharacterCodes[CharacterCodes["zeroWidthSpace"] = 8203] = "zeroWidthSpace";
        CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 8239] = "narrowNoBreakSpace";
        CharacterCodes[CharacterCodes["ideographicSpace"] = 12288] = "ideographicSpace";
        CharacterCodes[CharacterCodes["mathematicalSpace"] = 8287] = "mathematicalSpace";
        CharacterCodes[CharacterCodes["ogham"] = 5760] = "ogham";
        CharacterCodes[CharacterCodes["_"] = 95] = "_";
        CharacterCodes[CharacterCodes["$"] = 36] = "$";
        CharacterCodes[CharacterCodes["_0"] = 48] = "_0";
        CharacterCodes[CharacterCodes["_1"] = 49] = "_1";
        CharacterCodes[CharacterCodes["_2"] = 50] = "_2";
        CharacterCodes[CharacterCodes["_3"] = 51] = "_3";
        CharacterCodes[CharacterCodes["_4"] = 52] = "_4";
        CharacterCodes[CharacterCodes["_5"] = 53] = "_5";
        CharacterCodes[CharacterCodes["_6"] = 54] = "_6";
        CharacterCodes[CharacterCodes["_7"] = 55] = "_7";
        CharacterCodes[CharacterCodes["_8"] = 56] = "_8";
        CharacterCodes[CharacterCodes["_9"] = 57] = "_9";
        CharacterCodes[CharacterCodes["a"] = 97] = "a";
        CharacterCodes[CharacterCodes["b"] = 98] = "b";
        CharacterCodes[CharacterCodes["c"] = 99] = "c";
        CharacterCodes[CharacterCodes["d"] = 100] = "d";
        CharacterCodes[CharacterCodes["e"] = 101] = "e";
        CharacterCodes[CharacterCodes["f"] = 102] = "f";
        CharacterCodes[CharacterCodes["g"] = 103] = "g";
        CharacterCodes[CharacterCodes["h"] = 104] = "h";
        CharacterCodes[CharacterCodes["i"] = 105] = "i";
        CharacterCodes[CharacterCodes["j"] = 106] = "j";
        CharacterCodes[CharacterCodes["k"] = 107] = "k";
        CharacterCodes[CharacterCodes["l"] = 108] = "l";
        CharacterCodes[CharacterCodes["m"] = 109] = "m";
        CharacterCodes[CharacterCodes["n"] = 110] = "n";
        CharacterCodes[CharacterCodes["o"] = 111] = "o";
        CharacterCodes[CharacterCodes["p"] = 112] = "p";
        CharacterCodes[CharacterCodes["q"] = 113] = "q";
        CharacterCodes[CharacterCodes["r"] = 114] = "r";
        CharacterCodes[CharacterCodes["s"] = 115] = "s";
        CharacterCodes[CharacterCodes["t"] = 116] = "t";
        CharacterCodes[CharacterCodes["u"] = 117] = "u";
        CharacterCodes[CharacterCodes["v"] = 118] = "v";
        CharacterCodes[CharacterCodes["w"] = 119] = "w";
        CharacterCodes[CharacterCodes["x"] = 120] = "x";
        CharacterCodes[CharacterCodes["y"] = 121] = "y";
        CharacterCodes[CharacterCodes["z"] = 122] = "z";
        CharacterCodes[CharacterCodes["A"] = 65] = "A";
        CharacterCodes[CharacterCodes["B"] = 66] = "B";
        CharacterCodes[CharacterCodes["C"] = 67] = "C";
        CharacterCodes[CharacterCodes["D"] = 68] = "D";
        CharacterCodes[CharacterCodes["E"] = 69] = "E";
        CharacterCodes[CharacterCodes["F"] = 70] = "F";
        CharacterCodes[CharacterCodes["G"] = 71] = "G";
        CharacterCodes[CharacterCodes["H"] = 72] = "H";
        CharacterCodes[CharacterCodes["I"] = 73] = "I";
        CharacterCodes[CharacterCodes["J"] = 74] = "J";
        CharacterCodes[CharacterCodes["K"] = 75] = "K";
        CharacterCodes[CharacterCodes["L"] = 76] = "L";
        CharacterCodes[CharacterCodes["M"] = 77] = "M";
        CharacterCodes[CharacterCodes["N"] = 78] = "N";
        CharacterCodes[CharacterCodes["O"] = 79] = "O";
        CharacterCodes[CharacterCodes["P"] = 80] = "P";
        CharacterCodes[CharacterCodes["Q"] = 81] = "Q";
        CharacterCodes[CharacterCodes["R"] = 82] = "R";
        CharacterCodes[CharacterCodes["S"] = 83] = "S";
        CharacterCodes[CharacterCodes["T"] = 84] = "T";
        CharacterCodes[CharacterCodes["U"] = 85] = "U";
        CharacterCodes[CharacterCodes["V"] = 86] = "V";
        CharacterCodes[CharacterCodes["W"] = 87] = "W";
        CharacterCodes[CharacterCodes["X"] = 88] = "X";
        CharacterCodes[CharacterCodes["Y"] = 89] = "Y";
        CharacterCodes[CharacterCodes["Z"] = 90] = "Z";
        CharacterCodes[CharacterCodes["ampersand"] = 38] = "ampersand";
        CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk";
        CharacterCodes[CharacterCodes["at"] = 64] = "at";
        CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash";
        CharacterCodes[CharacterCodes["backtick"] = 96] = "backtick";
        CharacterCodes[CharacterCodes["bar"] = 124] = "bar";
        CharacterCodes[CharacterCodes["caret"] = 94] = "caret";
        CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace";
        CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket";
        CharacterCodes[CharacterCodes["closeParen"] = 41] = "closeParen";
        CharacterCodes[CharacterCodes["colon"] = 58] = "colon";
        CharacterCodes[CharacterCodes["comma"] = 44] = "comma";
        CharacterCodes[CharacterCodes["dot"] = 46] = "dot";
        CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote";
        CharacterCodes[CharacterCodes["equals"] = 61] = "equals";
        CharacterCodes[CharacterCodes["exclamation"] = 33] = "exclamation";
        CharacterCodes[CharacterCodes["greaterThan"] = 62] = "greaterThan";
        CharacterCodes[CharacterCodes["hash"] = 35] = "hash";
        CharacterCodes[CharacterCodes["lessThan"] = 60] = "lessThan";
        CharacterCodes[CharacterCodes["minus"] = 45] = "minus";
        CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace";
        CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket";
        CharacterCodes[CharacterCodes["openParen"] = 40] = "openParen";
        CharacterCodes[CharacterCodes["percent"] = 37] = "percent";
        CharacterCodes[CharacterCodes["plus"] = 43] = "plus";
        CharacterCodes[CharacterCodes["question"] = 63] = "question";
        CharacterCodes[CharacterCodes["semicolon"] = 59] = "semicolon";
        CharacterCodes[CharacterCodes["singleQuote"] = 39] = "singleQuote";
        CharacterCodes[CharacterCodes["slash"] = 47] = "slash";
        CharacterCodes[CharacterCodes["tilde"] = 126] = "tilde";
        CharacterCodes[CharacterCodes["backspace"] = 8] = "backspace";
        CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed";
        CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark";
        CharacterCodes[CharacterCodes["tab"] = 9] = "tab";
        CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab";
    })(CharacterCodes = ts.CharacterCodes || (ts.CharacterCodes = {}));
    var Extension;
    (function (Extension) {
        Extension["Ts"] = ".ts";
        Extension["Tsx"] = ".tsx";
        Extension["Dts"] = ".d.ts";
        Extension["Js"] = ".js";
        Extension["Jsx"] = ".jsx";
        Extension["Json"] = ".json";
        Extension["TsBuildInfo"] = ".tsbuildinfo";
    })(Extension = ts.Extension || (ts.Extension = {}));
    /* @internal */
    var TransformFlags;
    (function (TransformFlags) {
        TransformFlags[TransformFlags["None"] = 0] = "None";
        // Facts
        // - Flags used to indicate that a node or subtree contains syntax that requires transformation.
        TransformFlags[TransformFlags["ContainsTypeScript"] = 1] = "ContainsTypeScript";
        TransformFlags[TransformFlags["ContainsJsx"] = 2] = "ContainsJsx";
        TransformFlags[TransformFlags["ContainsESNext"] = 4] = "ContainsESNext";
        TransformFlags[TransformFlags["ContainsES2020"] = 8] = "ContainsES2020";
        TransformFlags[TransformFlags["ContainsES2019"] = 16] = "ContainsES2019";
        TransformFlags[TransformFlags["ContainsES2018"] = 32] = "ContainsES2018";
        TransformFlags[TransformFlags["ContainsES2017"] = 64] = "ContainsES2017";
        TransformFlags[TransformFlags["ContainsES2016"] = 128] = "ContainsES2016";
        TransformFlags[TransformFlags["ContainsES2015"] = 256] = "ContainsES2015";
        TransformFlags[TransformFlags["ContainsGenerator"] = 512] = "ContainsGenerator";
        TransformFlags[TransformFlags["ContainsDestructuringAssignment"] = 1024] = "ContainsDestructuringAssignment";
        // Markers
        // - Flags used to indicate that a subtree contains a specific transformation.
        TransformFlags[TransformFlags["ContainsTypeScriptClassSyntax"] = 2048] = "ContainsTypeScriptClassSyntax";
        TransformFlags[TransformFlags["ContainsLexicalThis"] = 4096] = "ContainsLexicalThis";
        TransformFlags[TransformFlags["ContainsRestOrSpread"] = 8192] = "ContainsRestOrSpread";
        TransformFlags[TransformFlags["ContainsObjectRestOrSpread"] = 16384] = "ContainsObjectRestOrSpread";
        TransformFlags[TransformFlags["ContainsComputedPropertyName"] = 32768] = "ContainsComputedPropertyName";
        TransformFlags[TransformFlags["ContainsBlockScopedBinding"] = 65536] = "ContainsBlockScopedBinding";
        TransformFlags[TransformFlags["ContainsBindingPattern"] = 131072] = "ContainsBindingPattern";
        TransformFlags[TransformFlags["ContainsYield"] = 262144] = "ContainsYield";
        TransformFlags[TransformFlags["ContainsAwait"] = 524288] = "ContainsAwait";
        TransformFlags[TransformFlags["ContainsHoistedDeclarationOrCompletion"] = 1048576] = "ContainsHoistedDeclarationOrCompletion";
        TransformFlags[TransformFlags["ContainsDynamicImport"] = 2097152] = "ContainsDynamicImport";
        TransformFlags[TransformFlags["ContainsClassFields"] = 4194304] = "ContainsClassFields";
        // Please leave this as 1 << 29.
        // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system.
        // It is a good reminder of how much room we have left
        TransformFlags[TransformFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags";
        // Assertions
        // - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
        TransformFlags[TransformFlags["AssertTypeScript"] = 1] = "AssertTypeScript";
        TransformFlags[TransformFlags["AssertJsx"] = 2] = "AssertJsx";
        TransformFlags[TransformFlags["AssertESNext"] = 4] = "AssertESNext";
        TransformFlags[TransformFlags["AssertES2020"] = 8] = "AssertES2020";
        TransformFlags[TransformFlags["AssertES2019"] = 16] = "AssertES2019";
        TransformFlags[TransformFlags["AssertES2018"] = 32] = "AssertES2018";
        TransformFlags[TransformFlags["AssertES2017"] = 64] = "AssertES2017";
        TransformFlags[TransformFlags["AssertES2016"] = 128] = "AssertES2016";
        TransformFlags[TransformFlags["AssertES2015"] = 256] = "AssertES2015";
        TransformFlags[TransformFlags["AssertGenerator"] = 512] = "AssertGenerator";
        TransformFlags[TransformFlags["AssertDestructuringAssignment"] = 1024] = "AssertDestructuringAssignment";
        // Scope Exclusions
        // - Bitmasks that exclude flags from propagating out of a specific context
        //   into the subtree flags of their container.
        TransformFlags[TransformFlags["OuterExpressionExcludes"] = 536870912] = "OuterExpressionExcludes";
        TransformFlags[TransformFlags["PropertyAccessExcludes"] = 536870912] = "PropertyAccessExcludes";
        TransformFlags[TransformFlags["NodeExcludes"] = 536870912] = "NodeExcludes";
        TransformFlags[TransformFlags["ArrowFunctionExcludes"] = 538920960] = "ArrowFunctionExcludes";
        TransformFlags[TransformFlags["FunctionExcludes"] = 538925056] = "FunctionExcludes";
        TransformFlags[TransformFlags["ConstructorExcludes"] = 538923008] = "ConstructorExcludes";
        TransformFlags[TransformFlags["MethodOrAccessorExcludes"] = 538923008] = "MethodOrAccessorExcludes";
        TransformFlags[TransformFlags["PropertyExcludes"] = 536875008] = "PropertyExcludes";
        TransformFlags[TransformFlags["ClassExcludes"] = 536905728] = "ClassExcludes";
        TransformFlags[TransformFlags["ModuleExcludes"] = 537991168] = "ModuleExcludes";
        TransformFlags[TransformFlags["TypeExcludes"] = -2] = "TypeExcludes";
        TransformFlags[TransformFlags["ObjectLiteralExcludes"] = 536922112] = "ObjectLiteralExcludes";
        TransformFlags[TransformFlags["ArrayLiteralOrCallOrNewExcludes"] = 536879104] = "ArrayLiteralOrCallOrNewExcludes";
        TransformFlags[TransformFlags["VariableDeclarationListExcludes"] = 537018368] = "VariableDeclarationListExcludes";
        TransformFlags[TransformFlags["ParameterExcludes"] = 536870912] = "ParameterExcludes";
        TransformFlags[TransformFlags["CatchClauseExcludes"] = 536887296] = "CatchClauseExcludes";
        TransformFlags[TransformFlags["BindingPatternExcludes"] = 536879104] = "BindingPatternExcludes";
        // Propagating flags
        // - Bitmasks for flags that should propagate from a child
        TransformFlags[TransformFlags["PropertyNamePropagatingFlags"] = 4096] = "PropertyNamePropagatingFlags";
        // Masks
        // - Additional bitmasks
    })(TransformFlags = ts.TransformFlags || (ts.TransformFlags = {}));
    var EmitFlags;
    (function (EmitFlags) {
        EmitFlags[EmitFlags["None"] = 0] = "None";
        EmitFlags[EmitFlags["SingleLine"] = 1] = "SingleLine";
        EmitFlags[EmitFlags["AdviseOnEmitNode"] = 2] = "AdviseOnEmitNode";
        EmitFlags[EmitFlags["NoSubstitution"] = 4] = "NoSubstitution";
        EmitFlags[EmitFlags["CapturesThis"] = 8] = "CapturesThis";
        EmitFlags[EmitFlags["NoLeadingSourceMap"] = 16] = "NoLeadingSourceMap";
        EmitFlags[EmitFlags["NoTrailingSourceMap"] = 32] = "NoTrailingSourceMap";
        EmitFlags[EmitFlags["NoSourceMap"] = 48] = "NoSourceMap";
        EmitFlags[EmitFlags["NoNestedSourceMaps"] = 64] = "NoNestedSourceMaps";
        EmitFlags[EmitFlags["NoTokenLeadingSourceMaps"] = 128] = "NoTokenLeadingSourceMaps";
        EmitFlags[EmitFlags["NoTokenTrailingSourceMaps"] = 256] = "NoTokenTrailingSourceMaps";
        EmitFlags[EmitFlags["NoTokenSourceMaps"] = 384] = "NoTokenSourceMaps";
        EmitFlags[EmitFlags["NoLeadingComments"] = 512] = "NoLeadingComments";
        EmitFlags[EmitFlags["NoTrailingComments"] = 1024] = "NoTrailingComments";
        EmitFlags[EmitFlags["NoComments"] = 1536] = "NoComments";
        EmitFlags[EmitFlags["NoNestedComments"] = 2048] = "NoNestedComments";
        EmitFlags[EmitFlags["HelperName"] = 4096] = "HelperName";
        EmitFlags[EmitFlags["ExportName"] = 8192] = "ExportName";
        EmitFlags[EmitFlags["LocalName"] = 16384] = "LocalName";
        EmitFlags[EmitFlags["InternalName"] = 32768] = "InternalName";
        EmitFlags[EmitFlags["Indented"] = 65536] = "Indented";
        EmitFlags[EmitFlags["NoIndentation"] = 131072] = "NoIndentation";
        EmitFlags[EmitFlags["AsyncFunctionBody"] = 262144] = "AsyncFunctionBody";
        EmitFlags[EmitFlags["ReuseTempVariableScope"] = 524288] = "ReuseTempVariableScope";
        EmitFlags[EmitFlags["CustomPrologue"] = 1048576] = "CustomPrologue";
        EmitFlags[EmitFlags["NoHoisting"] = 2097152] = "NoHoisting";
        EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker";
        EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator";
        EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping";
        /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper";
        /*@internal*/ EmitFlags[EmitFlags["NeverApplyImportHelper"] = 67108864] = "NeverApplyImportHelper";
        /*@internal*/ EmitFlags[EmitFlags["IgnoreSourceNewlines"] = 134217728] = "IgnoreSourceNewlines";
    })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {}));
    /**
     * Used by the checker, this enum keeps track of external emit helpers that should be type
     * checked.
     */
    /* @internal */
    var ExternalEmitHelpers;
    (function (ExternalEmitHelpers) {
        ExternalEmitHelpers[ExternalEmitHelpers["Extends"] = 1] = "Extends";
        ExternalEmitHelpers[ExternalEmitHelpers["Assign"] = 2] = "Assign";
        ExternalEmitHelpers[ExternalEmitHelpers["Rest"] = 4] = "Rest";
        ExternalEmitHelpers[ExternalEmitHelpers["Decorate"] = 8] = "Decorate";
        ExternalEmitHelpers[ExternalEmitHelpers["Metadata"] = 16] = "Metadata";
        ExternalEmitHelpers[ExternalEmitHelpers["Param"] = 32] = "Param";
        ExternalEmitHelpers[ExternalEmitHelpers["Awaiter"] = 64] = "Awaiter";
        ExternalEmitHelpers[ExternalEmitHelpers["Generator"] = 128] = "Generator";
        ExternalEmitHelpers[ExternalEmitHelpers["Values"] = 256] = "Values";
        ExternalEmitHelpers[ExternalEmitHelpers["Read"] = 512] = "Read";
        ExternalEmitHelpers[ExternalEmitHelpers["Spread"] = 1024] = "Spread";
        ExternalEmitHelpers[ExternalEmitHelpers["SpreadArrays"] = 2048] = "SpreadArrays";
        ExternalEmitHelpers[ExternalEmitHelpers["Await"] = 4096] = "Await";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGenerator"] = 8192] = "AsyncGenerator";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegator"] = 16384] = "AsyncDelegator";
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncValues"] = 32768] = "AsyncValues";
        ExternalEmitHelpers[ExternalEmitHelpers["ExportStar"] = 65536] = "ExportStar";
        ExternalEmitHelpers[ExternalEmitHelpers["MakeTemplateObject"] = 131072] = "MakeTemplateObject";
        ExternalEmitHelpers[ExternalEmitHelpers["ClassPrivateFieldGet"] = 262144] = "ClassPrivateFieldGet";
        ExternalEmitHelpers[ExternalEmitHelpers["ClassPrivateFieldSet"] = 524288] = "ClassPrivateFieldSet";
        ExternalEmitHelpers[ExternalEmitHelpers["CreateBinding"] = 1048576] = "CreateBinding";
        ExternalEmitHelpers[ExternalEmitHelpers["FirstEmitHelper"] = 1] = "FirstEmitHelper";
        ExternalEmitHelpers[ExternalEmitHelpers["LastEmitHelper"] = 1048576] = "LastEmitHelper";
        // Helpers included by ES2015 for..of
        ExternalEmitHelpers[ExternalEmitHelpers["ForOfIncludes"] = 256] = "ForOfIncludes";
        // Helpers included by ES2017 for..await..of
        ExternalEmitHelpers[ExternalEmitHelpers["ForAwaitOfIncludes"] = 32768] = "ForAwaitOfIncludes";
        // Helpers included by ES2017 async generators
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncGeneratorIncludes"] = 12288] = "AsyncGeneratorIncludes";
        // Helpers included by yield* in ES2017 async generators
        ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegatorIncludes"] = 53248] = "AsyncDelegatorIncludes";
        // Helpers included by ES2015 spread
        ExternalEmitHelpers[ExternalEmitHelpers["SpreadIncludes"] = 1536] = "SpreadIncludes";
    })(ExternalEmitHelpers = ts.ExternalEmitHelpers || (ts.ExternalEmitHelpers = {}));
    var EmitHint;
    (function (EmitHint) {
        EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile";
        EmitHint[EmitHint["Expression"] = 1] = "Expression";
        EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName";
        EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter";
        EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified";
        EmitHint[EmitHint["EmbeddedStatement"] = 5] = "EmbeddedStatement";
        EmitHint[EmitHint["JsxAttributeValue"] = 6] = "JsxAttributeValue";
    })(EmitHint = ts.EmitHint || (ts.EmitHint = {}));
    /* @internal */
    var LexicalEnvironmentFlags;
    (function (LexicalEnvironmentFlags) {
        LexicalEnvironmentFlags[LexicalEnvironmentFlags["None"] = 0] = "None";
        LexicalEnvironmentFlags[LexicalEnvironmentFlags["InParameters"] = 1] = "InParameters";
        LexicalEnvironmentFlags[LexicalEnvironmentFlags["VariablesHoistedInParameters"] = 2] = "VariablesHoistedInParameters"; // a temp variable was hoisted while visiting a parameter list
    })(LexicalEnvironmentFlags = ts.LexicalEnvironmentFlags || (ts.LexicalEnvironmentFlags = {}));
    /*@internal*/
    var BundleFileSectionKind;
    (function (BundleFileSectionKind) {
        BundleFileSectionKind["Prologue"] = "prologue";
        BundleFileSectionKind["EmitHelpers"] = "emitHelpers";
        BundleFileSectionKind["NoDefaultLib"] = "no-default-lib";
        BundleFileSectionKind["Reference"] = "reference";
        BundleFileSectionKind["Type"] = "type";
        BundleFileSectionKind["Lib"] = "lib";
        BundleFileSectionKind["Prepend"] = "prepend";
        BundleFileSectionKind["Text"] = "text";
        BundleFileSectionKind["Internal"] = "internal";
        // comments?
    })(BundleFileSectionKind = ts.BundleFileSectionKind || (ts.BundleFileSectionKind = {}));
    var ListFormat;
    (function (ListFormat) {
        ListFormat[ListFormat["None"] = 0] = "None";
        // Line separators
        ListFormat[ListFormat["SingleLine"] = 0] = "SingleLine";
        ListFormat[ListFormat["MultiLine"] = 1] = "MultiLine";
        ListFormat[ListFormat["PreserveLines"] = 2] = "PreserveLines";
        ListFormat[ListFormat["LinesMask"] = 3] = "LinesMask";
        // Delimiters
        ListFormat[ListFormat["NotDelimited"] = 0] = "NotDelimited";
        ListFormat[ListFormat["BarDelimited"] = 4] = "BarDelimited";
        ListFormat[ListFormat["AmpersandDelimited"] = 8] = "AmpersandDelimited";
        ListFormat[ListFormat["CommaDelimited"] = 16] = "CommaDelimited";
        ListFormat[ListFormat["AsteriskDelimited"] = 32] = "AsteriskDelimited";
        ListFormat[ListFormat["DelimitersMask"] = 60] = "DelimitersMask";
        ListFormat[ListFormat["AllowTrailingComma"] = 64] = "AllowTrailingComma";
        // Whitespace
        ListFormat[ListFormat["Indented"] = 128] = "Indented";
        ListFormat[ListFormat["SpaceBetweenBraces"] = 256] = "SpaceBetweenBraces";
        ListFormat[ListFormat["SpaceBetweenSiblings"] = 512] = "SpaceBetweenSiblings";
        // Brackets/Braces
        ListFormat[ListFormat["Braces"] = 1024] = "Braces";
        ListFormat[ListFormat["Parenthesis"] = 2048] = "Parenthesis";
        ListFormat[ListFormat["AngleBrackets"] = 4096] = "AngleBrackets";
        ListFormat[ListFormat["SquareBrackets"] = 8192] = "SquareBrackets";
        ListFormat[ListFormat["BracketsMask"] = 15360] = "BracketsMask";
        ListFormat[ListFormat["OptionalIfUndefined"] = 16384] = "OptionalIfUndefined";
        ListFormat[ListFormat["OptionalIfEmpty"] = 32768] = "OptionalIfEmpty";
        ListFormat[ListFormat["Optional"] = 49152] = "Optional";
        // Other
        ListFormat[ListFormat["PreferNewLine"] = 65536] = "PreferNewLine";
        ListFormat[ListFormat["NoTrailingNewLine"] = 131072] = "NoTrailingNewLine";
        ListFormat[ListFormat["NoInterveningComments"] = 262144] = "NoInterveningComments";
        ListFormat[ListFormat["NoSpaceIfEmpty"] = 524288] = "NoSpaceIfEmpty";
        ListFormat[ListFormat["SingleElement"] = 1048576] = "SingleElement";
        ListFormat[ListFormat["SpaceAfterList"] = 2097152] = "SpaceAfterList";
        // Precomputed Formats
        ListFormat[ListFormat["Modifiers"] = 262656] = "Modifiers";
        ListFormat[ListFormat["HeritageClauses"] = 512] = "HeritageClauses";
        ListFormat[ListFormat["SingleLineTypeLiteralMembers"] = 768] = "SingleLineTypeLiteralMembers";
        ListFormat[ListFormat["MultiLineTypeLiteralMembers"] = 32897] = "MultiLineTypeLiteralMembers";
        ListFormat[ListFormat["TupleTypeElements"] = 528] = "TupleTypeElements";
        ListFormat[ListFormat["UnionTypeConstituents"] = 516] = "UnionTypeConstituents";
        ListFormat[ListFormat["IntersectionTypeConstituents"] = 520] = "IntersectionTypeConstituents";
        ListFormat[ListFormat["ObjectBindingPatternElements"] = 525136] = "ObjectBindingPatternElements";
        ListFormat[ListFormat["ArrayBindingPatternElements"] = 524880] = "ArrayBindingPatternElements";
        ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 526226] = "ObjectLiteralExpressionProperties";
        ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 8914] = "ArrayLiteralExpressionElements";
        ListFormat[ListFormat["CommaListElements"] = 528] = "CommaListElements";
        ListFormat[ListFormat["CallExpressionArguments"] = 2576] = "CallExpressionArguments";
        ListFormat[ListFormat["NewExpressionArguments"] = 18960] = "NewExpressionArguments";
        ListFormat[ListFormat["TemplateExpressionSpans"] = 262144] = "TemplateExpressionSpans";
        ListFormat[ListFormat["SingleLineBlockStatements"] = 768] = "SingleLineBlockStatements";
        ListFormat[ListFormat["MultiLineBlockStatements"] = 129] = "MultiLineBlockStatements";
        ListFormat[ListFormat["VariableDeclarationList"] = 528] = "VariableDeclarationList";
        ListFormat[ListFormat["SingleLineFunctionBodyStatements"] = 768] = "SingleLineFunctionBodyStatements";
        ListFormat[ListFormat["MultiLineFunctionBodyStatements"] = 1] = "MultiLineFunctionBodyStatements";
        ListFormat[ListFormat["ClassHeritageClauses"] = 0] = "ClassHeritageClauses";
        ListFormat[ListFormat["ClassMembers"] = 129] = "ClassMembers";
        ListFormat[ListFormat["InterfaceMembers"] = 129] = "InterfaceMembers";
        ListFormat[ListFormat["EnumMembers"] = 145] = "EnumMembers";
        ListFormat[ListFormat["CaseBlockClauses"] = 129] = "CaseBlockClauses";
        ListFormat[ListFormat["NamedImportsOrExportsElements"] = 525136] = "NamedImportsOrExportsElements";
        ListFormat[ListFormat["JsxElementOrFragmentChildren"] = 262144] = "JsxElementOrFragmentChildren";
        ListFormat[ListFormat["JsxElementAttributes"] = 262656] = "JsxElementAttributes";
        ListFormat[ListFormat["CaseOrDefaultClauseStatements"] = 163969] = "CaseOrDefaultClauseStatements";
        ListFormat[ListFormat["HeritageClauseTypes"] = 528] = "HeritageClauseTypes";
        ListFormat[ListFormat["SourceFileStatements"] = 131073] = "SourceFileStatements";
        ListFormat[ListFormat["Decorators"] = 2146305] = "Decorators";
        ListFormat[ListFormat["TypeArguments"] = 53776] = "TypeArguments";
        ListFormat[ListFormat["TypeParameters"] = 53776] = "TypeParameters";
        ListFormat[ListFormat["Parameters"] = 2576] = "Parameters";
        ListFormat[ListFormat["IndexSignatureParameters"] = 8848] = "IndexSignatureParameters";
        ListFormat[ListFormat["JSDocComment"] = 33] = "JSDocComment";
    })(ListFormat = ts.ListFormat || (ts.ListFormat = {}));
    /* @internal */
    var PragmaKindFlags;
    (function (PragmaKindFlags) {
        PragmaKindFlags[PragmaKindFlags["None"] = 0] = "None";
        /**
         * Triple slash comment of the form
         * /// <pragma-name argname="value" />
         */
        PragmaKindFlags[PragmaKindFlags["TripleSlashXML"] = 1] = "TripleSlashXML";
        /**
         * Single line comment of the form
         * // @pragma-name argval1 argval2
         * or
         * /// @pragma-name argval1 argval2
         */
        PragmaKindFlags[PragmaKindFlags["SingleLine"] = 2] = "SingleLine";
        /**
         * Multiline non-jsdoc pragma of the form
         * /* @pragma-name argval1 argval2 * /
         */
        PragmaKindFlags[PragmaKindFlags["MultiLine"] = 4] = "MultiLine";
        PragmaKindFlags[PragmaKindFlags["All"] = 7] = "All";
        PragmaKindFlags[PragmaKindFlags["Default"] = 7] = "Default";
    })(PragmaKindFlags = ts.PragmaKindFlags || (ts.PragmaKindFlags = {}));
    // While not strictly a type, this is here because `PragmaMap` needs to be here to be used with `SourceFile`, and we don't
    //  fancy effectively defining it twice, once in value-space and once in type-space
    /* @internal */
    ts.commentPragmas = {
        "reference": {
            args: [
                { name: "types", optional: true, captureSpan: true },
                { name: "lib", optional: true, captureSpan: true },
                { name: "path", optional: true, captureSpan: true },
                { name: "no-default-lib", optional: true }
            ],
            kind: 1 /* TripleSlashXML */
        },
        "amd-dependency": {
            args: [{ name: "path" }, { name: "name", optional: true }],
            kind: 1 /* TripleSlashXML */
        },
        "amd-module": {
            args: [{ name: "name" }],
            kind: 1 /* TripleSlashXML */
        },
        "ts-check": {
            kind: 2 /* SingleLine */
        },
        "ts-nocheck": {
            kind: 2 /* SingleLine */
        },
        "jsx": {
            args: [{ name: "factory" }],
            kind: 4 /* MultiLine */
        },
    };
})(ts || (ts = {}));
var ts;
(function (ts) {
    /**
     * djb2 hashing algorithm
     * http://www.cse.yorku.ca/~oz/hash.html
     */
    /* @internal */
    function generateDjb2Hash(data) {
        var acc = 5381;
        for (var i = 0; i < data.length; i++) {
            acc = ((acc << 5) + acc) + data.charCodeAt(i);
        }
        return acc.toString();
    }
    ts.generateDjb2Hash = generateDjb2Hash;
    /**
     * Set a high stack trace limit to provide more information in case of an error.
     * Called for command-line and server use cases.
     * Not called if TypeScript is used as a library.
     */
    /* @internal */
    function setStackTraceLimit() {
        if (Error.stackTraceLimit < 100) { // Also tests that we won't set the property if it doesn't exist.
            Error.stackTraceLimit = 100;
        }
    }
    ts.setStackTraceLimit = setStackTraceLimit;
    var FileWatcherEventKind;
    (function (FileWatcherEventKind) {
        FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created";
        FileWatcherEventKind[FileWatcherEventKind["Changed"] = 1] = "Changed";
        FileWatcherEventKind[FileWatcherEventKind["Deleted"] = 2] = "Deleted";
    })(FileWatcherEventKind = ts.FileWatcherEventKind || (ts.FileWatcherEventKind = {}));
    /* @internal */
    var PollingInterval;
    (function (PollingInterval) {
        PollingInterval[PollingInterval["High"] = 2000] = "High";
        PollingInterval[PollingInterval["Medium"] = 500] = "Medium";
        PollingInterval[PollingInterval["Low"] = 250] = "Low";
    })(PollingInterval = ts.PollingInterval || (ts.PollingInterval = {}));
    /* @internal */
    ts.missingFileModifiedTime = new Date(0); // Any subsequent modification will occur after this time
    function createPollingIntervalBasedLevels(levels) {
        var _a;
        return _a = {},
            _a[PollingInterval.Low] = levels.Low,
            _a[PollingInterval.Medium] = levels.Medium,
            _a[PollingInterval.High] = levels.High,
            _a;
    }
    var defaultChunkLevels = { Low: 32, Medium: 64, High: 256 };
    var pollingChunkSize = createPollingIntervalBasedLevels(defaultChunkLevels);
    /* @internal */
    ts.unchangedPollThresholds = createPollingIntervalBasedLevels(defaultChunkLevels);
    /* @internal */
    function setCustomPollingValues(system) {
        if (!system.getEnvironmentVariable) {
            return;
        }
        var pollingIntervalChanged = setCustomLevels("TSC_WATCH_POLLINGINTERVAL", PollingInterval);
        pollingChunkSize = getCustomPollingBasedLevels("TSC_WATCH_POLLINGCHUNKSIZE", defaultChunkLevels) || pollingChunkSize;
        ts.unchangedPollThresholds = getCustomPollingBasedLevels("TSC_WATCH_UNCHANGEDPOLLTHRESHOLDS", defaultChunkLevels) || ts.unchangedPollThresholds;
        function getLevel(envVar, level) {
            return system.getEnvironmentVariable(envVar + "_" + level.toUpperCase());
        }
        function getCustomLevels(baseVariable) {
            var customLevels;
            setCustomLevel("Low");
            setCustomLevel("Medium");
            setCustomLevel("High");
            return customLevels;
            function setCustomLevel(level) {
                var customLevel = getLevel(baseVariable, level);
                if (customLevel) {
                    (customLevels || (customLevels = {}))[level] = Number(customLevel);
                }
            }
        }
        function setCustomLevels(baseVariable, levels) {
            var customLevels = getCustomLevels(baseVariable);
            if (customLevels) {
                setLevel("Low");
                setLevel("Medium");
                setLevel("High");
                return true;
            }
            return false;
            function setLevel(level) {
                levels[level] = customLevels[level] || levels[level];
            }
        }
        function getCustomPollingBasedLevels(baseVariable, defaultLevels) {
            var customLevels = getCustomLevels(baseVariable);
            return (pollingIntervalChanged || customLevels) &&
                createPollingIntervalBasedLevels(customLevels ? __assign(__assign({}, defaultLevels), customLevels) : defaultLevels);
        }
    }
    ts.setCustomPollingValues = setCustomPollingValues;
    /* @internal */
    function createDynamicPriorityPollingWatchFile(host) {
        var watchedFiles = [];
        var changedFilesInLastPoll = [];
        var lowPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.Low);
        var mediumPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.Medium);
        var highPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.High);
        return watchFile;
        function watchFile(fileName, callback, defaultPollingInterval) {
            var file = {
                fileName: fileName,
                callback: callback,
                unchangedPolls: 0,
                mtime: getModifiedTime(fileName)
            };
            watchedFiles.push(file);
            addToPollingIntervalQueue(file, defaultPollingInterval);
            return {
                close: function () {
                    file.isClosed = true;
                    // Remove from watchedFiles
                    ts.unorderedRemoveItem(watchedFiles, file);
                    // Do not update polling interval queue since that will happen as part of polling
                }
            };
        }
        function createPollingIntervalQueue(pollingInterval) {
            var queue = [];
            queue.pollingInterval = pollingInterval;
            queue.pollIndex = 0;
            queue.pollScheduled = false;
            return queue;
        }
        function pollPollingIntervalQueue(queue) {
            queue.pollIndex = pollQueue(queue, queue.pollingInterval, queue.pollIndex, pollingChunkSize[queue.pollingInterval]);
            // Set the next polling index and timeout
            if (queue.length) {
                scheduleNextPoll(queue.pollingInterval);
            }
            else {
                ts.Debug.assert(queue.pollIndex === 0);
                queue.pollScheduled = false;
            }
        }
        function pollLowPollingIntervalQueue(queue) {
            // Always poll complete list of changedFilesInLastPoll
            pollQueue(changedFilesInLastPoll, PollingInterval.Low, /*pollIndex*/ 0, changedFilesInLastPoll.length);
            // Finally do the actual polling of the queue
            pollPollingIntervalQueue(queue);
            // Schedule poll if there are files in changedFilesInLastPoll but no files in the actual queue
            // as pollPollingIntervalQueue wont schedule for next poll
            if (!queue.pollScheduled && changedFilesInLastPoll.length) {
                scheduleNextPoll(PollingInterval.Low);
            }
        }
        function pollQueue(queue, pollingInterval, pollIndex, chunkSize) {
            // Max visit would be all elements of the queue
            var needsVisit = queue.length;
            var definedValueCopyToIndex = pollIndex;
            for (var polled = 0; polled < chunkSize && needsVisit > 0; nextPollIndex(), needsVisit--) {
                var watchedFile = queue[pollIndex];
                if (!watchedFile) {
                    continue;
                }
                else if (watchedFile.isClosed) {
                    queue[pollIndex] = undefined;
                    continue;
                }
                polled++;
                var fileChanged = onWatchedFileStat(watchedFile, getModifiedTime(watchedFile.fileName));
                if (watchedFile.isClosed) {
                    // Closed watcher as part of callback
                    queue[pollIndex] = undefined;
                }
                else if (fileChanged) {
                    watchedFile.unchangedPolls = 0;
                    // Changed files go to changedFilesInLastPoll queue
                    if (queue !== changedFilesInLastPoll) {
                        queue[pollIndex] = undefined;
                        addChangedFileToLowPollingIntervalQueue(watchedFile);
                    }
                }
                else if (watchedFile.unchangedPolls !== ts.unchangedPollThresholds[pollingInterval]) {
                    watchedFile.unchangedPolls++;
                }
                else if (queue === changedFilesInLastPoll) {
                    // Restart unchangedPollCount for unchanged file and move to low polling interval queue
                    watchedFile.unchangedPolls = 1;
                    queue[pollIndex] = undefined;
                    addToPollingIntervalQueue(watchedFile, PollingInterval.Low);
                }
                else if (pollingInterval !== PollingInterval.High) {
                    watchedFile.unchangedPolls++;
                    queue[pollIndex] = undefined;
                    addToPollingIntervalQueue(watchedFile, pollingInterval === PollingInterval.Low ? PollingInterval.Medium : PollingInterval.High);
                }
                if (queue[pollIndex]) {
                    // Copy this file to the non hole location
                    if (definedValueCopyToIndex < pollIndex) {
                        queue[definedValueCopyToIndex] = watchedFile;
                        queue[pollIndex] = undefined;
                    }
                    definedValueCopyToIndex++;
                }
            }
            // Return next poll index
            return pollIndex;
            function nextPollIndex() {
                pollIndex++;
                if (pollIndex === queue.length) {
                    if (definedValueCopyToIndex < pollIndex) {
                        // There are holes from nextDefinedValueIndex to end of queue, change queue size
                        queue.length = definedValueCopyToIndex;
                    }
                    pollIndex = 0;
                    definedValueCopyToIndex = 0;
                }
            }
        }
        function pollingIntervalQueue(pollingInterval) {
            switch (pollingInterval) {
                case PollingInterval.Low:
                    return lowPollingIntervalQueue;
                case PollingInterval.Medium:
                    return mediumPollingIntervalQueue;
                case PollingInterval.High:
                    return highPollingIntervalQueue;
            }
        }
        function addToPollingIntervalQueue(file, pollingInterval) {
            pollingIntervalQueue(pollingInterval).push(file);
            scheduleNextPollIfNotAlreadyScheduled(pollingInterval);
        }
        function addChangedFileToLowPollingIntervalQueue(file) {
            changedFilesInLastPoll.push(file);
            scheduleNextPollIfNotAlreadyScheduled(PollingInterval.Low);
        }
        function scheduleNextPollIfNotAlreadyScheduled(pollingInterval) {
            if (!pollingIntervalQueue(pollingInterval).pollScheduled) {
                scheduleNextPoll(pollingInterval);
            }
        }
        function scheduleNextPoll(pollingInterval) {
            pollingIntervalQueue(pollingInterval).pollScheduled = host.setTimeout(pollingInterval === PollingInterval.Low ? pollLowPollingIntervalQueue : pollPollingIntervalQueue, pollingInterval, pollingIntervalQueue(pollingInterval));
        }
        function getModifiedTime(fileName) {
            return host.getModifiedTime(fileName) || ts.missingFileModifiedTime;
        }
    }
    ts.createDynamicPriorityPollingWatchFile = createDynamicPriorityPollingWatchFile;
    function createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames) {
        // One file can have multiple watchers
        var fileWatcherCallbacks = ts.createMultiMap();
        var dirWatchers = ts.createMap();
        var toCanonicalName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        return nonPollingWatchFile;
        function nonPollingWatchFile(fileName, callback, _pollingInterval, fallbackOptions) {
            var filePath = toCanonicalName(fileName);
            fileWatcherCallbacks.add(filePath, callback);
            var dirPath = ts.getDirectoryPath(filePath) || ".";
            var watcher = dirWatchers.get(dirPath) ||
                createDirectoryWatcher(ts.getDirectoryPath(fileName) || ".", dirPath, fallbackOptions);
            watcher.referenceCount++;
            return {
                close: function () {
                    if (watcher.referenceCount === 1) {
                        watcher.close();
                        dirWatchers.delete(dirPath);
                    }
                    else {
                        watcher.referenceCount--;
                    }
                    fileWatcherCallbacks.remove(filePath, callback);
                }
            };
        }
        function createDirectoryWatcher(dirName, dirPath, fallbackOptions) {
            var watcher = fsWatch(dirName, 1 /* Directory */, function (_eventName, relativeFileName) {
                // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
                if (!ts.isString(relativeFileName)) {
                    return;
                }
                var fileName = ts.getNormalizedAbsolutePath(relativeFileName, dirName);
                // Some applications save a working file via rename operations
                var callbacks = fileName && fileWatcherCallbacks.get(toCanonicalName(fileName));
                if (callbacks) {
                    for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) {
                        var fileCallback = callbacks_1[_i];
                        fileCallback(fileName, FileWatcherEventKind.Changed);
                    }
                }
            }, 
            /*recursive*/ false, PollingInterval.Medium, fallbackOptions);
            watcher.referenceCount = 0;
            dirWatchers.set(dirPath, watcher);
            return watcher;
        }
    }
    /* @internal */
    function createSingleFileWatcherPerName(watchFile, useCaseSensitiveFileNames) {
        var cache = ts.createMap();
        var callbacksCache = ts.createMultiMap();
        var toCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        return function (fileName, callback, pollingInterval, options) {
            var path = toCanonicalFileName(fileName);
            var existing = cache.get(path);
            if (existing) {
                existing.refCount++;
            }
            else {
                cache.set(path, {
                    watcher: watchFile(fileName, function (fileName, eventKind) { return ts.forEach(callbacksCache.get(path), function (cb) { return cb(fileName, eventKind); }); }, pollingInterval, options),
                    refCount: 1
                });
            }
            callbacksCache.add(path, callback);
            return {
                close: function () {
                    var watcher = ts.Debug.checkDefined(cache.get(path));
                    callbacksCache.remove(path, callback);
                    watcher.refCount--;
                    if (watcher.refCount)
                        return;
                    cache.delete(path);
                    ts.closeFileWatcherOf(watcher);
                }
            };
        };
    }
    ts.createSingleFileWatcherPerName = createSingleFileWatcherPerName;
    /**
     * Returns true if file status changed
     */
    /*@internal*/
    function onWatchedFileStat(watchedFile, modifiedTime) {
        var oldTime = watchedFile.mtime.getTime();
        var newTime = modifiedTime.getTime();
        if (oldTime !== newTime) {
            watchedFile.mtime = modifiedTime;
            watchedFile.callback(watchedFile.fileName, getFileWatcherEventKind(oldTime, newTime));
            return true;
        }
        return false;
    }
    ts.onWatchedFileStat = onWatchedFileStat;
    /*@internal*/
    function getFileWatcherEventKind(oldTime, newTime) {
        return oldTime === 0
            ? FileWatcherEventKind.Created
            : newTime === 0
                ? FileWatcherEventKind.Deleted
                : FileWatcherEventKind.Changed;
    }
    ts.getFileWatcherEventKind = getFileWatcherEventKind;
    /*@internal*/
    ts.ignoredPaths = ["/node_modules/.", "/.git", "/.#"];
    /*@internal*/
    ts.sysLog = ts.noop; // eslint-disable-line prefer-const
    /*@internal*/
    function setSysLog(logger) {
        ts.sysLog = logger;
    }
    ts.setSysLog = setSysLog;
    /**
     * Watch the directory recursively using host provided method to watch child directories
     * that means if this is recursive watcher, watch the children directories as well
     * (eg on OS that dont support recursive watch using fs.watch use fs.watchFile)
     */
    /*@internal*/
    function createDirectoryWatcherSupportingRecursive(host) {
        var cache = ts.createMap();
        var callbackCache = ts.createMultiMap();
        var cacheToUpdateChildWatches = ts.createMap();
        var timerToUpdateChildWatches;
        var filePathComparer = ts.getStringComparer(!host.useCaseSensitiveFileNames);
        var toCanonicalFilePath = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        return function (dirName, callback, recursive, options) { return recursive ?
            createDirectoryWatcher(dirName, options, callback) :
            host.watchDirectory(dirName, callback, recursive, options); };
        /**
         * Create the directory watcher for the dirPath.
         */
        function createDirectoryWatcher(dirName, options, callback) {
            var dirPath = toCanonicalFilePath(dirName);
            var directoryWatcher = cache.get(dirPath);
            if (directoryWatcher) {
                directoryWatcher.refCount++;
            }
            else {
                directoryWatcher = {
                    watcher: host.watchDirectory(dirName, function (fileName) {
                        if (isIgnoredPath(fileName))
                            return;
                        if (options === null || options === void 0 ? void 0 : options.synchronousWatchDirectory) {
                            // Call the actual callback
                            invokeCallbacks(dirPath, fileName);
                            // Iterate through existing children and update the watches if needed
                            updateChildWatches(dirName, dirPath, options);
                        }
                        else {
                            nonSyncUpdateChildWatches(dirName, dirPath, fileName, options);
                        }
                    }, /*recursive*/ false, options),
                    refCount: 1,
                    childWatches: ts.emptyArray
                };
                cache.set(dirPath, directoryWatcher);
                updateChildWatches(dirName, dirPath, options);
            }
            var callbackToAdd = callback && { dirName: dirName, callback: callback };
            if (callbackToAdd) {
                callbackCache.add(dirPath, callbackToAdd);
            }
            return {
                dirName: dirName,
                close: function () {
                    var directoryWatcher = ts.Debug.checkDefined(cache.get(dirPath));
                    if (callbackToAdd)
                        callbackCache.remove(dirPath, callbackToAdd);
                    directoryWatcher.refCount--;
                    if (directoryWatcher.refCount)
                        return;
                    cache.delete(dirPath);
                    ts.closeFileWatcherOf(directoryWatcher);
                    directoryWatcher.childWatches.forEach(ts.closeFileWatcher);
                }
            };
        }
        function invokeCallbacks(dirPath, fileNameOrInvokeMap) {
            var fileName;
            var invokeMap;
            if (ts.isString(fileNameOrInvokeMap)) {
                fileName = fileNameOrInvokeMap;
            }
            else {
                invokeMap = fileNameOrInvokeMap;
            }
            // Call the actual callback
            callbackCache.forEach(function (callbacks, rootDirName) {
                if (invokeMap && invokeMap.has(rootDirName))
                    return;
                if (rootDirName === dirPath || (ts.startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === ts.directorySeparator)) {
                    if (invokeMap) {
                        invokeMap.set(rootDirName, true);
                    }
                    else {
                        callbacks.forEach(function (_a) {
                            var callback = _a.callback;
                            return callback(fileName);
                        });
                    }
                }
            });
        }
        function nonSyncUpdateChildWatches(dirName, dirPath, fileName, options) {
            // Iterate through existing children and update the watches if needed
            var parentWatcher = cache.get(dirPath);
            if (parentWatcher && host.directoryExists(dirName)) {
                // Schedule the update and postpone invoke for callbacks
                scheduleUpdateChildWatches(dirName, dirPath, options);
                return;
            }
            // Call the actual callbacks and remove child watches
            invokeCallbacks(dirPath, fileName);
            removeChildWatches(parentWatcher);
        }
        function scheduleUpdateChildWatches(dirName, dirPath, options) {
            if (!cacheToUpdateChildWatches.has(dirPath)) {
                cacheToUpdateChildWatches.set(dirPath, { dirName: dirName, options: options });
            }
            if (timerToUpdateChildWatches) {
                host.clearTimeout(timerToUpdateChildWatches);
                timerToUpdateChildWatches = undefined;
            }
            timerToUpdateChildWatches = host.setTimeout(onTimerToUpdateChildWatches, 1000);
        }
        function onTimerToUpdateChildWatches() {
            timerToUpdateChildWatches = undefined;
            ts.sysLog("sysLog:: onTimerToUpdateChildWatches:: " + cacheToUpdateChildWatches.size);
            var start = ts.timestamp();
            var invokeMap = ts.createMap();
            while (!timerToUpdateChildWatches && cacheToUpdateChildWatches.size) {
                var _a = cacheToUpdateChildWatches.entries().next(), _b = _a.value, dirPath = _b[0], _c = _b[1], dirName = _c.dirName, options = _c.options, done = _a.done;
                ts.Debug.assert(!done);
                cacheToUpdateChildWatches.delete(dirPath);
                // Because the child refresh is fresh, we would need to invalidate whole root directory being watched
                // to ensure that all the changes are reflected at this time
                invokeCallbacks(dirPath, invokeMap);
                updateChildWatches(dirName, dirPath, options);
            }
            ts.sysLog("sysLog:: invokingWatchers:: " + (ts.timestamp() - start) + "ms:: " + cacheToUpdateChildWatches.size);
            callbackCache.forEach(function (callbacks, rootDirName) {
                if (invokeMap.has(rootDirName)) {
                    callbacks.forEach(function (_a) {
                        var callback = _a.callback, dirName = _a.dirName;
                        return callback(dirName);
                    });
                }
            });
            var elapsed = ts.timestamp() - start;
            ts.sysLog("sysLog:: Elapsed " + elapsed + "ms:: onTimerToUpdateChildWatches:: " + cacheToUpdateChildWatches.size + " " + timerToUpdateChildWatches);
        }
        function removeChildWatches(parentWatcher) {
            if (!parentWatcher)
                return;
            var existingChildWatches = parentWatcher.childWatches;
            parentWatcher.childWatches = ts.emptyArray;
            for (var _i = 0, existingChildWatches_1 = existingChildWatches; _i < existingChildWatches_1.length; _i++) {
                var childWatcher = existingChildWatches_1[_i];
                childWatcher.close();
                removeChildWatches(cache.get(toCanonicalFilePath(childWatcher.dirName)));
            }
        }
        function updateChildWatches(dirName, dirPath, options) {
            // Iterate through existing children and update the watches if needed
            var parentWatcher = cache.get(dirPath);
            if (parentWatcher) {
                parentWatcher.childWatches = watchChildDirectories(dirName, parentWatcher.childWatches, options);
            }
        }
        /**
         * Watch the directories in the parentDir
         */
        function watchChildDirectories(parentDir, existingChildWatches, options) {
            var newChildWatches;
            ts.enumerateInsertsAndDeletes(host.directoryExists(parentDir) ? ts.mapDefined(host.getAccessibleSortedChildDirectories(parentDir), function (child) {
                var childFullName = ts.getNormalizedAbsolutePath(child, parentDir);
                // Filter our the symbolic link directories since those arent included in recursive watch
                // which is same behaviour when recursive: true is passed to fs.watch
                return !isIgnoredPath(childFullName) && filePathComparer(childFullName, ts.normalizePath(host.realpath(childFullName))) === 0 /* EqualTo */ ? childFullName : undefined;
            }) : ts.emptyArray, existingChildWatches, function (child, childWatcher) { return filePathComparer(child, childWatcher.dirName); }, createAndAddChildDirectoryWatcher, ts.closeFileWatcher, addChildDirectoryWatcher);
            return newChildWatches || ts.emptyArray;
            /**
             * Create new childDirectoryWatcher and add it to the new ChildDirectoryWatcher list
             */
            function createAndAddChildDirectoryWatcher(childName) {
                var result = createDirectoryWatcher(childName, options);
                addChildDirectoryWatcher(result);
            }
            /**
             * Add child directory watcher to the new ChildDirectoryWatcher list
             */
            function addChildDirectoryWatcher(childWatcher) {
                (newChildWatches || (newChildWatches = [])).push(childWatcher);
            }
        }
        function isIgnoredPath(path) {
            return ts.some(ts.ignoredPaths, function (searchPath) { return isInPath(path, searchPath); });
        }
        function isInPath(path, searchPath) {
            if (ts.stringContains(path, searchPath))
                return true;
            if (host.useCaseSensitiveFileNames)
                return false;
            return ts.stringContains(toCanonicalFilePath(path), searchPath);
        }
    }
    ts.createDirectoryWatcherSupportingRecursive = createDirectoryWatcherSupportingRecursive;
    /*@internal*/
    var FileSystemEntryKind;
    (function (FileSystemEntryKind) {
        FileSystemEntryKind[FileSystemEntryKind["File"] = 0] = "File";
        FileSystemEntryKind[FileSystemEntryKind["Directory"] = 1] = "Directory";
    })(FileSystemEntryKind = ts.FileSystemEntryKind || (ts.FileSystemEntryKind = {}));
    /*@internal*/
    function createFileWatcherCallback(callback) {
        return function (_fileName, eventKind) { return callback(eventKind === FileWatcherEventKind.Changed ? "change" : "rename", ""); };
    }
    ts.createFileWatcherCallback = createFileWatcherCallback;
    function createFsWatchCallbackForFileWatcherCallback(fileName, callback, fileExists) {
        return function (eventName) {
            if (eventName === "rename") {
                callback(fileName, fileExists(fileName) ? FileWatcherEventKind.Created : FileWatcherEventKind.Deleted);
            }
            else {
                // Change
                callback(fileName, FileWatcherEventKind.Changed);
            }
        };
    }
    function createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback) {
        return function (eventName, relativeFileName) {
            // In watchDirectory we only care about adding and removing files (when event name is
            // "rename"); changes made within files are handled by corresponding fileWatchers (when
            // event name is "change")
            if (eventName === "rename") {
                // When deleting a file, the passed baseFileName is null
                callback(!relativeFileName ? directoryName : ts.normalizePath(ts.combinePaths(directoryName, relativeFileName)));
            }
        };
    }
    /*@internal*/
    function createSystemWatchFunctions(_a) {
        var pollingWatchFile = _a.pollingWatchFile, getModifiedTime = _a.getModifiedTime, setTimeout = _a.setTimeout, clearTimeout = _a.clearTimeout, fsWatch = _a.fsWatch, fileExists = _a.fileExists, useCaseSensitiveFileNames = _a.useCaseSensitiveFileNames, fsSupportsRecursiveFsWatch = _a.fsSupportsRecursiveFsWatch, directoryExists = _a.directoryExists, getAccessibleSortedChildDirectories = _a.getAccessibleSortedChildDirectories, realpath = _a.realpath, tscWatchFile = _a.tscWatchFile, useNonPollingWatchers = _a.useNonPollingWatchers, tscWatchDirectory = _a.tscWatchDirectory;
        var dynamicPollingWatchFile;
        var nonPollingWatchFile;
        var hostRecursiveDirectoryWatcher;
        return {
            watchFile: watchFile,
            watchDirectory: watchDirectory
        };
        function watchFile(fileName, callback, pollingInterval, options) {
            options = updateOptionsForWatchFile(options, useNonPollingWatchers);
            var watchFileKind = ts.Debug.checkDefined(options.watchFile);
            switch (watchFileKind) {
                case ts.WatchFileKind.FixedPollingInterval:
                    return pollingWatchFile(fileName, callback, PollingInterval.Low, /*options*/ undefined);
                case ts.WatchFileKind.PriorityPollingInterval:
                    return pollingWatchFile(fileName, callback, pollingInterval, /*options*/ undefined);
                case ts.WatchFileKind.DynamicPriorityPolling:
                    return ensureDynamicPollingWatchFile()(fileName, callback, pollingInterval, /*options*/ undefined);
                case ts.WatchFileKind.UseFsEvents:
                    return fsWatch(fileName, 0 /* File */, createFsWatchCallbackForFileWatcherCallback(fileName, callback, fileExists), 
                    /*recursive*/ false, pollingInterval, ts.getFallbackOptions(options));
                case ts.WatchFileKind.UseFsEventsOnParentDirectory:
                    if (!nonPollingWatchFile) {
                        nonPollingWatchFile = createUseFsEventsOnParentDirectoryWatchFile(fsWatch, useCaseSensitiveFileNames);
                    }
                    return nonPollingWatchFile(fileName, callback, pollingInterval, ts.getFallbackOptions(options));
                default:
                    ts.Debug.assertNever(watchFileKind);
            }
        }
        function ensureDynamicPollingWatchFile() {
            return dynamicPollingWatchFile ||
                (dynamicPollingWatchFile = createDynamicPriorityPollingWatchFile({ getModifiedTime: getModifiedTime, setTimeout: setTimeout }));
        }
        function updateOptionsForWatchFile(options, useNonPollingWatchers) {
            if (options && options.watchFile !== undefined)
                return options;
            switch (tscWatchFile) {
                case "PriorityPollingInterval":
                    // Use polling interval based on priority when create watch using host.watchFile
                    return { watchFile: ts.WatchFileKind.PriorityPollingInterval };
                case "DynamicPriorityPolling":
                    // Use polling interval but change the interval depending on file changes and their default polling interval
                    return { watchFile: ts.WatchFileKind.DynamicPriorityPolling };
                case "UseFsEvents":
                    // Use notifications from FS to watch with falling back to fs.watchFile
                    return generateWatchFileOptions(ts.WatchFileKind.UseFsEvents, ts.PollingWatchKind.PriorityInterval, options);
                case "UseFsEventsWithFallbackDynamicPolling":
                    // Use notifications from FS to watch with falling back to dynamic watch file
                    return generateWatchFileOptions(ts.WatchFileKind.UseFsEvents, ts.PollingWatchKind.DynamicPriority, options);
                case "UseFsEventsOnParentDirectory":
                    useNonPollingWatchers = true;
                // fall through
                default:
                    return useNonPollingWatchers ?
                        // Use notifications from FS to watch with falling back to fs.watchFile
                        generateWatchFileOptions(ts.WatchFileKind.UseFsEventsOnParentDirectory, ts.PollingWatchKind.PriorityInterval, options) :
                        // Default to do not use fixed polling interval
                        { watchFile: ts.WatchFileKind.FixedPollingInterval };
            }
        }
        function generateWatchFileOptions(watchFile, fallbackPolling, options) {
            var defaultFallbackPolling = options === null || options === void 0 ? void 0 : options.fallbackPolling;
            return {
                watchFile: watchFile,
                fallbackPolling: defaultFallbackPolling === undefined ?
                    fallbackPolling :
                    defaultFallbackPolling
            };
        }
        function watchDirectory(directoryName, callback, recursive, options) {
            if (fsSupportsRecursiveFsWatch) {
                return fsWatch(directoryName, 1 /* Directory */, createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback), recursive, PollingInterval.Medium, ts.getFallbackOptions(options));
            }
            if (!hostRecursiveDirectoryWatcher) {
                hostRecursiveDirectoryWatcher = createDirectoryWatcherSupportingRecursive({
                    useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                    directoryExists: directoryExists,
                    getAccessibleSortedChildDirectories: getAccessibleSortedChildDirectories,
                    watchDirectory: nonRecursiveWatchDirectory,
                    realpath: realpath,
                    setTimeout: setTimeout,
                    clearTimeout: clearTimeout
                });
            }
            return hostRecursiveDirectoryWatcher(directoryName, callback, recursive, options);
        }
        function nonRecursiveWatchDirectory(directoryName, callback, recursive, options) {
            ts.Debug.assert(!recursive);
            options = updateOptionsForWatchDirectory(options);
            var watchDirectoryKind = ts.Debug.checkDefined(options.watchDirectory);
            switch (watchDirectoryKind) {
                case ts.WatchDirectoryKind.FixedPollingInterval:
                    return pollingWatchFile(directoryName, function () { return callback(directoryName); }, PollingInterval.Medium, 
                    /*options*/ undefined);
                case ts.WatchDirectoryKind.DynamicPriorityPolling:
                    return ensureDynamicPollingWatchFile()(directoryName, function () { return callback(directoryName); }, PollingInterval.Medium, 
                    /*options*/ undefined);
                case ts.WatchDirectoryKind.UseFsEvents:
                    return fsWatch(directoryName, 1 /* Directory */, createFsWatchCallbackForDirectoryWatcherCallback(directoryName, callback), recursive, PollingInterval.Medium, ts.getFallbackOptions(options));
                default:
                    ts.Debug.assertNever(watchDirectoryKind);
            }
        }
        function updateOptionsForWatchDirectory(options) {
            if (options && options.watchDirectory !== undefined)
                return options;
            switch (tscWatchDirectory) {
                case "RecursiveDirectoryUsingFsWatchFile":
                    // Use polling interval based on priority when create watch using host.watchFile
                    return { watchDirectory: ts.WatchDirectoryKind.FixedPollingInterval };
                case "RecursiveDirectoryUsingDynamicPriorityPolling":
                    // Use polling interval but change the interval depending on file changes and their default polling interval
                    return { watchDirectory: ts.WatchDirectoryKind.DynamicPriorityPolling };
                default:
                    var defaultFallbackPolling = options === null || options === void 0 ? void 0 : options.fallbackPolling;
                    return {
                        watchDirectory: ts.WatchDirectoryKind.UseFsEvents,
                        fallbackPolling: defaultFallbackPolling !== undefined ?
                            defaultFallbackPolling :
                            undefined
                    };
            }
        }
    }
    ts.createSystemWatchFunctions = createSystemWatchFunctions;
    /**
     * patch writefile to create folder before writing the file
     */
    /*@internal*/
    function patchWriteFileEnsuringDirectory(sys) {
        // patch writefile to create folder before writing the file
        var originalWriteFile = sys.writeFile;
        sys.writeFile = function (path, data, writeBom) {
            return ts.writeFileEnsuringDirectories(path, data, !!writeBom, function (path, data, writeByteOrderMark) { return originalWriteFile.call(sys, path, data, writeByteOrderMark); }, function (path) { return sys.createDirectory(path); }, function (path) { return sys.directoryExists(path); });
        };
    }
    ts.patchWriteFileEnsuringDirectory = patchWriteFileEnsuringDirectory;
    function getNodeMajorVersion() {
        if (typeof process === "undefined") {
            return undefined;
        }
        var version = process.version;
        if (!version) {
            return undefined;
        }
        var dot = version.indexOf(".");
        if (dot === -1) {
            return undefined;
        }
        return parseInt(version.substring(1, dot));
    }
    ts.getNodeMajorVersion = getNodeMajorVersion;
    // TODO: GH#18217 this is used as if it's certainly defined in many places.
    // eslint-disable-next-line prefer-const
    ts.sys = (function () {
        // NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
        // byte order mark from the specified encoding. Using any other byte order mark does
        // not actually work.
        var byteOrderMarkIndicator = "\uFEFF";
        function getNodeSystem() {
            var nativePattern = /^native |^\([^)]+\)$|^(internal[\\/]|[a-zA-Z0-9_\s]+(\.js)?$)/;
            var _fs = require("fs");
            var _path = require("path");
            var _os = require("os");
            // crypto can be absent on reduced node installations
            var _crypto;
            try {
                _crypto = require("crypto");
            }
            catch (_a) {
                _crypto = undefined;
            }
            var activeSession;
            var profilePath = "./profile.cpuprofile";
            var Buffer = require("buffer").Buffer;
            var nodeVersion = getNodeMajorVersion();
            var isNode4OrLater = nodeVersion >= 4;
            var isLinuxOrMacOs = process.platform === "linux" || process.platform === "darwin";
            var platform = _os.platform();
            var useCaseSensitiveFileNames = isFileSystemCaseSensitive();
            var fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
            var _b = createSystemWatchFunctions({
                pollingWatchFile: createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames),
                getModifiedTime: getModifiedTime,
                setTimeout: setTimeout,
                clearTimeout: clearTimeout,
                fsWatch: fsWatch,
                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                fileExists: fileExists,
                // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
                // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
                fsSupportsRecursiveFsWatch: fsSupportsRecursiveFsWatch,
                directoryExists: directoryExists,
                getAccessibleSortedChildDirectories: function (path) { return getAccessibleFileSystemEntries(path).directories; },
                realpath: realpath,
                tscWatchFile: process.env.TSC_WATCHFILE,
                useNonPollingWatchers: process.env.TSC_NONPOLLING_WATCHER,
                tscWatchDirectory: process.env.TSC_WATCHDIRECTORY,
            }), watchFile = _b.watchFile, watchDirectory = _b.watchDirectory;
            var nodeSystem = {
                args: process.argv.slice(2),
                newLine: _os.EOL,
                useCaseSensitiveFileNames: useCaseSensitiveFileNames,
                write: function (s) {
                    process.stdout.write(s);
                },
                writeOutputIsTTY: function () {
                    return process.stdout.isTTY;
                },
                readFile: readFile,
                writeFile: writeFile,
                watchFile: watchFile,
                watchDirectory: watchDirectory,
                resolvePath: function (path) { return _path.resolve(path); },
                fileExists: fileExists,
                directoryExists: directoryExists,
                createDirectory: function (directoryName) {
                    if (!nodeSystem.directoryExists(directoryName)) {
                        // Wrapped in a try-catch to prevent crashing if we are in a race
                        // with another copy of ourselves to create the same directory
                        try {
                            _fs.mkdirSync(directoryName);
                        }
                        catch (e) {
                            if (e.code !== "EEXIST") {
                                // Failed for some other reason (access denied?); still throw
                                throw e;
                            }
                        }
                    }
                },
                getExecutingFilePath: function () {
                    return __filename;
                },
                getCurrentDirectory: function () {
                    return process.cwd();
                },
                getDirectories: getDirectories,
                getEnvironmentVariable: function (name) {
                    return process.env[name] || "";
                },
                readDirectory: readDirectory,
                getModifiedTime: getModifiedTime,
                setModifiedTime: setModifiedTime,
                deleteFile: deleteFile,
                createHash: _crypto ? createSHA256Hash : generateDjb2Hash,
                createSHA256Hash: _crypto ? createSHA256Hash : undefined,
                getMemoryUsage: function () {
                    if (global.gc) {
                        global.gc();
                    }
                    return process.memoryUsage().heapUsed;
                },
                getFileSize: function (path) {
                    try {
                        var stat = _fs.statSync(path);
                        if (stat.isFile()) {
                            return stat.size;
                        }
                    }
                    catch ( /*ignore*/_a) { /*ignore*/ }
                    return 0;
                },
                exit: function (exitCode) {
                    disableCPUProfiler(function () { return process.exit(exitCode); });
                },
                enableCPUProfiler: enableCPUProfiler,
                disableCPUProfiler: disableCPUProfiler,
                realpath: realpath,
                debugMode: !!process.env.NODE_INSPECTOR_IPC || ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }),
                tryEnableSourceMapsForHost: function () {
                    try {
                        require("source-map-support").install();
                    }
                    catch (_a) {
                        // Could not enable source maps.
                    }
                },
                setTimeout: setTimeout,
                clearTimeout: clearTimeout,
                clearScreen: function () {
                    process.stdout.write("\x1Bc");
                },
                setBlocking: function () {
                    if (process.stdout && process.stdout._handle && process.stdout._handle.setBlocking) {
                        process.stdout._handle.setBlocking(true);
                    }
                },
                bufferFrom: bufferFrom,
                base64decode: function (input) { return bufferFrom(input, "base64").toString("utf8"); },
                base64encode: function (input) { return bufferFrom(input).toString("base64"); },
                require: function (baseDir, moduleName) {
                    try {
                        var modulePath = ts.resolveJSModule(moduleName, baseDir, nodeSystem);
                        return { module: require(modulePath), modulePath: modulePath, error: undefined };
                    }
                    catch (error) {
                        return { module: undefined, modulePath: undefined, error: error };
                    }
                }
            };
            return nodeSystem;
            /**
             * Uses the builtin inspector APIs to capture a CPU profile
             * See https://nodejs.org/api/inspector.html#inspector_example_usage for details
             */
            function enableCPUProfiler(path, cb) {
                if (activeSession) {
                    cb();
                    return false;
                }
                var inspector = require("inspector");
                if (!inspector || !inspector.Session) {
                    cb();
                    return false;
                }
                var session = new inspector.Session();
                session.connect();
                session.post("Profiler.enable", function () {
                    session.post("Profiler.start", function () {
                        activeSession = session;
                        profilePath = path;
                        cb();
                    });
                });
                return true;
            }
            /**
             * Strips non-TS paths from the profile, so users with private projects shouldn't
             * need to worry about leaking paths by submitting a cpu profile to us
             */
            function cleanupPaths(profile) {
                var externalFileCounter = 0;
                var remappedPaths = ts.createMap();
                var normalizedDir = ts.normalizeSlashes(__dirname);
                // Windows rooted dir names need an extra `/` prepended to be valid file:/// urls
                var fileUrlRoot = "file://" + (ts.getRootLength(normalizedDir) === 1 ? "" : "/") + normalizedDir;
                for (var _i = 0, _a = profile.nodes; _i < _a.length; _i++) {
                    var node = _a[_i];
                    if (node.callFrame.url) {
                        var url = ts.normalizeSlashes(node.callFrame.url);
                        if (ts.containsPath(fileUrlRoot, url, useCaseSensitiveFileNames)) {
                            node.callFrame.url = ts.getRelativePathToDirectoryOrUrl(fileUrlRoot, url, fileUrlRoot, ts.createGetCanonicalFileName(useCaseSensitiveFileNames), /*isAbsolutePathAnUrl*/ true);
                        }
                        else if (!nativePattern.test(url)) {
                            node.callFrame.url = (remappedPaths.has(url) ? remappedPaths : remappedPaths.set(url, "external" + externalFileCounter + ".js")).get(url);
                            externalFileCounter++;
                        }
                    }
                }
                return profile;
            }
            function disableCPUProfiler(cb) {
                if (activeSession && activeSession !== "stopping") {
                    var s_1 = activeSession;
                    activeSession.post("Profiler.stop", function (err, _a) {
                        var profile = _a.profile;
                        if (!err) {
                            try {
                                if (_fs.statSync(profilePath).isDirectory()) {
                                    profilePath = _path.join(profilePath, (new Date()).toISOString().replace(/:/g, "-") + "+P" + process.pid + ".cpuprofile");
                                }
                            }
                            catch (_b) {
                                // do nothing and ignore fallible fs operation
                            }
                            try {
                                _fs.mkdirSync(_path.dirname(profilePath), { recursive: true });
                            }
                            catch (_c) {
                                // do nothing and ignore fallible fs operation
                            }
                            _fs.writeFileSync(profilePath, JSON.stringify(cleanupPaths(profile)));
                        }
                        activeSession = undefined;
                        s_1.disconnect();
                        cb();
                    });
                    activeSession = "stopping";
                    return true;
                }
                else {
                    cb();
                    return false;
                }
            }
            function bufferFrom(input, encoding) {
                // See https://github.com/Microsoft/TypeScript/issues/25652
                return Buffer.from && Buffer.from !== Int8Array.from
                    ? Buffer.from(input, encoding)
                    : new Buffer(input, encoding);
            }
            function isFileSystemCaseSensitive() {
                // win32\win64 are case insensitive platforms
                if (platform === "win32" || platform === "win64") {
                    return false;
                }
                // If this file exists under a different case, we must be case-insensitve.
                return !fileExists(swapCase(__filename));
            }
            /** Convert all lowercase chars to uppercase, and vice-versa */
            function swapCase(s) {
                return s.replace(/\w/g, function (ch) {
                    var up = ch.toUpperCase();
                    return ch === up ? ch.toLowerCase() : up;
                });
            }
            function fsWatchFileWorker(fileName, callback, pollingInterval) {
                _fs.watchFile(fileName, { persistent: true, interval: pollingInterval }, fileChanged);
                var eventKind;
                return {
                    close: function () { return _fs.unwatchFile(fileName, fileChanged); }
                };
                function fileChanged(curr, prev) {
                    // previous event kind check is to ensure we recongnize the file as previously also missing when it is restored or renamed twice (that is it disappears and reappears)
                    // In such case, prevTime returned is same as prev time of event when file was deleted as per node documentation
                    var isPreviouslyDeleted = +prev.mtime === 0 || eventKind === FileWatcherEventKind.Deleted;
                    if (+curr.mtime === 0) {
                        if (isPreviouslyDeleted) {
                            // Already deleted file, no need to callback again
                            return;
                        }
                        eventKind = FileWatcherEventKind.Deleted;
                    }
                    else if (isPreviouslyDeleted) {
                        eventKind = FileWatcherEventKind.Created;
                    }
                    // If there is no change in modified time, ignore the event
                    else if (+curr.mtime === +prev.mtime) {
                        return;
                    }
                    else {
                        // File changed
                        eventKind = FileWatcherEventKind.Changed;
                    }
                    callback(fileName, eventKind);
                }
            }
            function fsWatch(fileOrDirectory, entryKind, callback, recursive, fallbackPollingInterval, fallbackOptions) {
                var options;
                var lastDirectoryPartWithDirectorySeparator;
                var lastDirectoryPart;
                if (isLinuxOrMacOs) {
                    lastDirectoryPartWithDirectorySeparator = fileOrDirectory.substr(fileOrDirectory.lastIndexOf(ts.directorySeparator));
                    lastDirectoryPart = lastDirectoryPartWithDirectorySeparator.slice(ts.directorySeparator.length);
                }
                /** Watcher for the file system entry depending on whether it is missing or present */
                var watcher = !fileSystemEntryExists(fileOrDirectory, entryKind) ?
                    watchMissingFileSystemEntry() :
                    watchPresentFileSystemEntry();
                return {
                    close: function () {
                        // Close the watcher (either existing file system entry watcher or missing file system entry watcher)
                        watcher.close();
                        watcher = undefined;
                    }
                };
                /**
                 * Invoke the callback with rename and update the watcher if not closed
                 * @param createWatcher
                 */
                function invokeCallbackAndUpdateWatcher(createWatcher) {
                    ts.sysLog("sysLog:: " + fileOrDirectory + ":: Changing watcher to " + (createWatcher === watchPresentFileSystemEntry ? "Present" : "Missing") + "FileSystemEntryWatcher");
                    // Call the callback for current directory
                    callback("rename", "");
                    // If watcher is not closed, update it
                    if (watcher) {
                        watcher.close();
                        watcher = createWatcher();
                    }
                }
                /**
                 * Watch the file or directory that is currently present
                 * and when the watched file or directory is deleted, switch to missing file system entry watcher
                 */
                function watchPresentFileSystemEntry() {
                    // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
                    // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
                    if (options === undefined) {
                        if (fsSupportsRecursiveFsWatch) {
                            options = { persistent: true, recursive: !!recursive };
                        }
                        else {
                            options = { persistent: true };
                        }
                    }
                    try {
                        var presentWatcher = _fs.watch(fileOrDirectory, options, isLinuxOrMacOs ?
                            callbackChangingToMissingFileSystemEntry :
                            callback);
                        // Watch the missing file or directory or error
                        presentWatcher.on("error", function () { return invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry); });
                        return presentWatcher;
                    }
                    catch (e) {
                        // Catch the exception and use polling instead
                        // Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
                        // so instead of throwing error, use fs.watchFile
                        return watchPresentFileSystemEntryWithFsWatchFile();
                    }
                }
                function callbackChangingToMissingFileSystemEntry(event, relativeName) {
                    // because relativeName is not guaranteed to be correct we need to check on each rename with few combinations
                    // Eg on ubuntu while watching app/node_modules the relativeName is "node_modules" which is neither relative nor full path
                    return event === "rename" &&
                        (!relativeName ||
                            relativeName === lastDirectoryPart ||
                            relativeName.lastIndexOf(lastDirectoryPartWithDirectorySeparator) === relativeName.length - lastDirectoryPartWithDirectorySeparator.length) &&
                        !fileSystemEntryExists(fileOrDirectory, entryKind) ?
                        invokeCallbackAndUpdateWatcher(watchMissingFileSystemEntry) :
                        callback(event, relativeName);
                }
                /**
                 * Watch the file or directory using fs.watchFile since fs.watch threw exception
                 * Eg. on linux the number of watches are limited and one could easily exhaust watches and the exception ENOSPC is thrown when creating watcher at that point
                 */
                function watchPresentFileSystemEntryWithFsWatchFile() {
                    ts.sysLog("sysLog:: " + fileOrDirectory + ":: Changing to fsWatchFile");
                    return watchFile(fileOrDirectory, createFileWatcherCallback(callback), fallbackPollingInterval, fallbackOptions);
                }
                /**
                 * Watch the file or directory that is missing
                 * and switch to existing file or directory when the missing filesystem entry is created
                 */
                function watchMissingFileSystemEntry() {
                    return watchFile(fileOrDirectory, function (_fileName, eventKind) {
                        if (eventKind === FileWatcherEventKind.Created && fileSystemEntryExists(fileOrDirectory, entryKind)) {
                            // Call the callback for current file or directory
                            // For now it could be callback for the inner directory creation,
                            // but just return current directory, better than current no-op
                            invokeCallbackAndUpdateWatcher(watchPresentFileSystemEntry);
                        }
                    }, fallbackPollingInterval, fallbackOptions);
                }
            }
            function readFileWorker(fileName, _encoding) {
                var buffer;
                try {
                    buffer = _fs.readFileSync(fileName);
                }
                catch (e) {
                    return undefined;
                }
                var len = buffer.length;
                if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
                    // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
                    // flip all byte pairs and treat as little endian.
                    len &= ~1; // Round down to a multiple of 2
                    for (var i = 0; i < len; i += 2) {
                        var temp = buffer[i];
                        buffer[i] = buffer[i + 1];
                        buffer[i + 1] = temp;
                    }
                    return buffer.toString("utf16le", 2);
                }
                if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
                    // Little endian UTF-16 byte order mark detected
                    return buffer.toString("utf16le", 2);
                }
                if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
                    // UTF-8 byte order mark detected
                    return buffer.toString("utf8", 3);
                }
                // Default is UTF-8 with no byte order mark
                return buffer.toString("utf8");
            }
            function readFile(fileName, _encoding) {
                ts.perfLogger.logStartReadFile(fileName);
                var file = readFileWorker(fileName, _encoding);
                ts.perfLogger.logStopReadFile();
                return file;
            }
            function writeFile(fileName, data, writeByteOrderMark) {
                ts.perfLogger.logEvent("WriteFile: " + fileName);
                // If a BOM is required, emit one
                if (writeByteOrderMark) {
                    data = byteOrderMarkIndicator + data;
                }
                var fd;
                try {
                    fd = _fs.openSync(fileName, "w");
                    _fs.writeSync(fd, data, /*position*/ undefined, "utf8");
                }
                finally {
                    if (fd !== undefined) {
                        _fs.closeSync(fd);
                    }
                }
            }
            function getAccessibleFileSystemEntries(path) {
                ts.perfLogger.logEvent("ReadDir: " + (path || "."));
                try {
                    var entries = _fs.readdirSync(path || ".", { withFileTypes: true });
                    var files = [];
                    var directories = [];
                    for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) {
                        var dirent = entries_2[_i];
                        // withFileTypes is not supported before Node 10.10.
                        var entry = typeof dirent === "string" ? dirent : dirent.name;
                        // This is necessary because on some file system node fails to exclude
                        // "." and "..". See https://github.com/nodejs/node/issues/4002
                        if (entry === "." || entry === "..") {
                            continue;
                        }
                        var stat = void 0;
                        if (typeof dirent === "string" || dirent.isSymbolicLink()) {
                            var name = ts.combinePaths(path, entry);
                            try {
                                stat = _fs.statSync(name);
                            }
                            catch (e) {
                                continue;
                            }
                        }
                        else {
                            stat = dirent;
                        }
                        if (stat.isFile()) {
                            files.push(entry);
                        }
                        else if (stat.isDirectory()) {
                            directories.push(entry);
                        }
                    }
                    files.sort();
                    directories.sort();
                    return { files: files, directories: directories };
                }
                catch (e) {
                    return ts.emptyFileSystemEntries;
                }
            }
            function readDirectory(path, extensions, excludes, includes, depth) {
                return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries, realpath);
            }
            function fileSystemEntryExists(path, entryKind) {
                try {
                    var stat = _fs.statSync(path);
                    switch (entryKind) {
                        case 0 /* File */: return stat.isFile();
                        case 1 /* Directory */: return stat.isDirectory();
                        default: return false;
                    }
                }
                catch (e) {
                    return false;
                }
            }
            function fileExists(path) {
                return fileSystemEntryExists(path, 0 /* File */);
            }
            function directoryExists(path) {
                return fileSystemEntryExists(path, 1 /* Directory */);
            }
            function getDirectories(path) {
                return getAccessibleFileSystemEntries(path).directories.slice();
            }
            function realpath(path) {
                try {
                    return _fs.realpathSync(path);
                }
                catch (_a) {
                    return path;
                }
            }
            function getModifiedTime(path) {
                try {
                    return _fs.statSync(path).mtime;
                }
                catch (e) {
                    return undefined;
                }
            }
            function setModifiedTime(path, time) {
                try {
                    _fs.utimesSync(path, time, time);
                }
                catch (e) {
                    return;
                }
            }
            function deleteFile(path) {
                try {
                    return _fs.unlinkSync(path);
                }
                catch (e) {
                    return;
                }
            }
            function createSHA256Hash(data) {
                var hash = _crypto.createHash("sha256");
                hash.update(data);
                return hash.digest("hex");
            }
        }
        var sys;
        if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") {
            // process and process.nextTick checks if current environment is node-like
            // process.browser check excludes webpack and browserify
            sys = getNodeSystem();
        }
        if (sys) {
            // patch writefile to create folder before writing the file
            patchWriteFileEnsuringDirectory(sys);
        }
        return sys;
    })();
    if (ts.sys && ts.sys.getEnvironmentVariable) {
        setCustomPollingValues(ts.sys);
        ts.Debug.setAssertionLevel(/^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))
            ? 1 /* Normal */
            : 0 /* None */);
    }
    if (ts.sys && ts.sys.debugMode) {
        ts.Debug.isDebugging = true;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    /**
     * Internally, we represent paths as strings with '/' as the directory separator.
     * When we make system calls (eg: LanguageServiceHost.getDirectory()),
     * we expect the host to correctly handle paths in our specified format.
     */
    ts.directorySeparator = "/";
    var altDirectorySeparator = "\\";
    var urlSchemeSeparator = "://";
    var backslashRegExp = /\\/g;
    //// Path Tests
    /**
     * Determines whether a charCode corresponds to `/` or `\`.
     */
    function isAnyDirectorySeparator(charCode) {
        return charCode === 47 /* slash */ || charCode === 92 /* backslash */;
    }
    ts.isAnyDirectorySeparator = isAnyDirectorySeparator;
    /**
     * Determines whether a path starts with a URL scheme (e.g. starts with `http://`, `ftp://`, `file://`, etc.).
     */
    function isUrl(path) {
        return getEncodedRootLength(path) < 0;
    }
    ts.isUrl = isUrl;
    /**
     * Determines whether a path is an absolute disk path (e.g. starts with `/`, or a dos path
     * like `c:`, `c:\` or `c:/`).
     */
    function isRootedDiskPath(path) {
        return getEncodedRootLength(path) > 0;
    }
    ts.isRootedDiskPath = isRootedDiskPath;
    /**
     * Determines whether a path consists only of a path root.
     */
    function isDiskPathRoot(path) {
        var rootLength = getEncodedRootLength(path);
        return rootLength > 0 && rootLength === path.length;
    }
    ts.isDiskPathRoot = isDiskPathRoot;
    /**
     * Determines whether a path starts with an absolute path component (i.e. `/`, `c:/`, `file://`, etc.).
     *
     * ```ts
     * // POSIX
     * pathIsAbsolute("/path/to/file.ext") === true
     * // DOS
     * pathIsAbsolute("c:/path/to/file.ext") === true
     * // URL
     * pathIsAbsolute("file:///path/to/file.ext") === true
     * // Non-absolute
     * pathIsAbsolute("path/to/file.ext") === false
     * pathIsAbsolute("./path/to/file.ext") === false
     * ```
     */
    function pathIsAbsolute(path) {
        return getEncodedRootLength(path) !== 0;
    }
    ts.pathIsAbsolute = pathIsAbsolute;
    /**
     * Determines whether a path starts with a relative path component (i.e. `.` or `..`).
     */
    function pathIsRelative(path) {
        return /^\.\.?($|[\\/])/.test(path);
    }
    ts.pathIsRelative = pathIsRelative;
    function hasExtension(fileName) {
        return ts.stringContains(getBaseFileName(fileName), ".");
    }
    ts.hasExtension = hasExtension;
    function fileExtensionIs(path, extension) {
        return path.length > extension.length && ts.endsWith(path, extension);
    }
    ts.fileExtensionIs = fileExtensionIs;
    function fileExtensionIsOneOf(path, extensions) {
        for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) {
            var extension = extensions_1[_i];
            if (fileExtensionIs(path, extension)) {
                return true;
            }
        }
        return false;
    }
    ts.fileExtensionIsOneOf = fileExtensionIsOneOf;
    /**
     * Determines whether a path has a trailing separator (`/` or `\\`).
     */
    function hasTrailingDirectorySeparator(path) {
        return path.length > 0 && isAnyDirectorySeparator(path.charCodeAt(path.length - 1));
    }
    ts.hasTrailingDirectorySeparator = hasTrailingDirectorySeparator;
    //// Path Parsing
    function isVolumeCharacter(charCode) {
        return (charCode >= 97 /* a */ && charCode <= 122 /* z */) ||
            (charCode >= 65 /* A */ && charCode <= 90 /* Z */);
    }
    function getFileUrlVolumeSeparatorEnd(url, start) {
        var ch0 = url.charCodeAt(start);
        if (ch0 === 58 /* colon */)
            return start + 1;
        if (ch0 === 37 /* percent */ && url.charCodeAt(start + 1) === 51 /* _3 */) {
            var ch2 = url.charCodeAt(start + 2);
            if (ch2 === 97 /* a */ || ch2 === 65 /* A */)
                return start + 3;
        }
        return -1;
    }
    /**
     * Returns length of the root part of a path or URL (i.e. length of "/", "x:/", "//server/share/, file:///user/files").
     * If the root is part of a URL, the twos-complement of the root length is returned.
     */
    function getEncodedRootLength(path) {
        if (!path)
            return 0;
        var ch0 = path.charCodeAt(0);
        // POSIX or UNC
        if (ch0 === 47 /* slash */ || ch0 === 92 /* backslash */) {
            if (path.charCodeAt(1) !== ch0)
                return 1; // POSIX: "/" (or non-normalized "\")
            var p1 = path.indexOf(ch0 === 47 /* slash */ ? ts.directorySeparator : altDirectorySeparator, 2);
            if (p1 < 0)
                return path.length; // UNC: "//server" or "\\server"
            return p1 + 1; // UNC: "//server/" or "\\server\"
        }
        // DOS
        if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* colon */) {
            var ch2 = path.charCodeAt(2);
            if (ch2 === 47 /* slash */ || ch2 === 92 /* backslash */)
                return 3; // DOS: "c:/" or "c:\"
            if (path.length === 2)
                return 2; // DOS: "c:" (but not "c:d")
        }
        // URL
        var schemeEnd = path.indexOf(urlSchemeSeparator);
        if (schemeEnd !== -1) {
            var authorityStart = schemeEnd + urlSchemeSeparator.length;
            var authorityEnd = path.indexOf(ts.directorySeparator, authorityStart);
            if (authorityEnd !== -1) { // URL: "file:///", "file://server/", "file://server/path"
                // For local "file" URLs, include the leading DOS volume (if present).
                // Per https://www.ietf.org/rfc/rfc1738.txt, a host of "" or "localhost" is a
                // special case interpreted as "the machine from which the URL is being interpreted".
                var scheme = path.slice(0, schemeEnd);
                var authority = path.slice(authorityStart, authorityEnd);
                if (scheme === "file" && (authority === "" || authority === "localhost") &&
                    isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) {
                    var volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2);
                    if (volumeSeparatorEnd !== -1) {
                        if (path.charCodeAt(volumeSeparatorEnd) === 47 /* slash */) {
                            // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/"
                            return ~(volumeSeparatorEnd + 1);
                        }
                        if (volumeSeparatorEnd === path.length) {
                            // URL: "file:///c:", "file://localhost/c:", "file:///c$3a", "file://localhost/c%3a"
                            // but not "file:///c:d" or "file:///c%3ad"
                            return ~volumeSeparatorEnd;
                        }
                    }
                }
                return ~(authorityEnd + 1); // URL: "file://server/", "http://server/"
            }
            return ~path.length; // URL: "file://server", "http://server"
        }
        // relative
        return 0;
    }
    /**
     * Returns length of the root part of a path or URL (i.e. length of "/", "x:/", "//server/share/, file:///user/files").
     *
     * For example:
     * ```ts
     * getRootLength("a") === 0                   // ""
     * getRootLength("/") === 1                   // "/"
     * getRootLength("c:") === 2                  // "c:"
     * getRootLength("c:d") === 0                 // ""
     * getRootLength("c:/") === 3                 // "c:/"
     * getRootLength("c:\\") === 3                // "c:\\"
     * getRootLength("//server") === 7            // "//server"
     * getRootLength("//server/share") === 8      // "//server/"
     * getRootLength("\\\\server") === 7          // "\\\\server"
     * getRootLength("\\\\server\\share") === 8   // "\\\\server\\"
     * getRootLength("file:///path") === 8        // "file:///"
     * getRootLength("file:///c:") === 10         // "file:///c:"
     * getRootLength("file:///c:d") === 8         // "file:///"
     * getRootLength("file:///c:/path") === 11    // "file:///c:/"
     * getRootLength("file://server") === 13      // "file://server"
     * getRootLength("file://server/path") === 14 // "file://server/"
     * getRootLength("http://server") === 13      // "http://server"
     * getRootLength("http://server/path") === 14 // "http://server/"
     * ```
     */
    function getRootLength(path) {
        var rootLength = getEncodedRootLength(path);
        return rootLength < 0 ? ~rootLength : rootLength;
    }
    ts.getRootLength = getRootLength;
    function getDirectoryPath(path) {
        path = normalizeSlashes(path);
        // If the path provided is itself the root, then return it.
        var rootLength = getRootLength(path);
        if (rootLength === path.length)
            return path;
        // return the leading portion of the path up to the last (non-terminal) directory separator
        // but not including any trailing directory separator.
        path = removeTrailingDirectorySeparator(path);
        return path.slice(0, Math.max(rootLength, path.lastIndexOf(ts.directorySeparator)));
    }
    ts.getDirectoryPath = getDirectoryPath;
    function getBaseFileName(path, extensions, ignoreCase) {
        path = normalizeSlashes(path);
        // if the path provided is itself the root, then it has not file name.
        var rootLength = getRootLength(path);
        if (rootLength === path.length)
            return "";
        // return the trailing portion of the path starting after the last (non-terminal) directory
        // separator but not including any trailing directory separator.
        path = removeTrailingDirectorySeparator(path);
        var name = path.slice(Math.max(getRootLength(path), path.lastIndexOf(ts.directorySeparator) + 1));
        var extension = extensions !== undefined && ignoreCase !== undefined ? getAnyExtensionFromPath(name, extensions, ignoreCase) : undefined;
        return extension ? name.slice(0, name.length - extension.length) : name;
    }
    ts.getBaseFileName = getBaseFileName;
    function tryGetExtensionFromPath(path, extension, stringEqualityComparer) {
        if (!ts.startsWith(extension, "."))
            extension = "." + extension;
        if (path.length >= extension.length && path.charCodeAt(path.length - extension.length) === 46 /* dot */) {
            var pathExtension = path.slice(path.length - extension.length);
            if (stringEqualityComparer(pathExtension, extension)) {
                return pathExtension;
            }
        }
    }
    function getAnyExtensionFromPathWorker(path, extensions, stringEqualityComparer) {
        if (typeof extensions === "string") {
            return tryGetExtensionFromPath(path, extensions, stringEqualityComparer) || "";
        }
        for (var _i = 0, extensions_2 = extensions; _i < extensions_2.length; _i++) {
            var extension = extensions_2[_i];
            var result = tryGetExtensionFromPath(path, extension, stringEqualityComparer);
            if (result)
                return result;
        }
        return "";
    }
    function getAnyExtensionFromPath(path, extensions, ignoreCase) {
        // Retrieves any string from the final "." onwards from a base file name.
        // Unlike extensionFromPath, which throws an exception on unrecognized extensions.
        if (extensions) {
            return getAnyExtensionFromPathWorker(removeTrailingDirectorySeparator(path), extensions, ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive);
        }
        var baseFileName = getBaseFileName(path);
        var extensionIndex = baseFileName.lastIndexOf(".");
        if (extensionIndex >= 0) {
            return baseFileName.substring(extensionIndex);
        }
        return "";
    }
    ts.getAnyExtensionFromPath = getAnyExtensionFromPath;
    function pathComponents(path, rootLength) {
        var root = path.substring(0, rootLength);
        var rest = path.substring(rootLength).split(ts.directorySeparator);
        if (rest.length && !ts.lastOrUndefined(rest))
            rest.pop();
        return __spreadArrays([root], rest);
    }
    /**
     * Parse a path into an array containing a root component (at index 0) and zero or more path
     * components (at indices > 0). The result is not normalized.
     * If the path is relative, the root component is `""`.
     * If the path is absolute, the root component includes the first path separator (`/`).
     *
     * ```ts
     * // POSIX
     * getPathComponents("/path/to/file.ext") === ["/", "path", "to", "file.ext"]
     * getPathComponents("/path/to/") === ["/", "path", "to"]
     * getPathComponents("/") === ["/"]
     * // DOS
     * getPathComponents("c:/path/to/file.ext") === ["c:/", "path", "to", "file.ext"]
     * getPathComponents("c:/path/to/") === ["c:/", "path", "to"]
     * getPathComponents("c:/") === ["c:/"]
     * getPathComponents("c:") === ["c:"]
     * // URL
     * getPathComponents("http://typescriptlang.org/path/to/file.ext") === ["http://typescriptlang.org/", "path", "to", "file.ext"]
     * getPathComponents("http://typescriptlang.org/path/to/") === ["http://typescriptlang.org/", "path", "to"]
     * getPathComponents("http://typescriptlang.org/") === ["http://typescriptlang.org/"]
     * getPathComponents("http://typescriptlang.org") === ["http://typescriptlang.org"]
     * getPathComponents("file://server/path/to/file.ext") === ["file://server/", "path", "to", "file.ext"]
     * getPathComponents("file://server/path/to/") === ["file://server/", "path", "to"]
     * getPathComponents("file://server/") === ["file://server/"]
     * getPathComponents("file://server") === ["file://server"]
     * getPathComponents("file:///path/to/file.ext") === ["file:///", "path", "to", "file.ext"]
     * getPathComponents("file:///path/to/") === ["file:///", "path", "to"]
     * getPathComponents("file:///") === ["file:///"]
     * getPathComponents("file://") === ["file://"]
     */
    function getPathComponents(path, currentDirectory) {
        if (currentDirectory === void 0) { currentDirectory = ""; }
        path = combinePaths(currentDirectory, path);
        return pathComponents(path, getRootLength(path));
    }
    ts.getPathComponents = getPathComponents;
    //// Path Formatting
    /**
     * Formats a parsed path consisting of a root component (at index 0) and zero or more path
     * segments (at indices > 0).
     *
     * ```ts
     * getPathFromPathComponents(["/", "path", "to", "file.ext"]) === "/path/to/file.ext"
     * ```
     */
    function getPathFromPathComponents(pathComponents) {
        if (pathComponents.length === 0)
            return "";
        var root = pathComponents[0] && ensureTrailingDirectorySeparator(pathComponents[0]);
        return root + pathComponents.slice(1).join(ts.directorySeparator);
    }
    ts.getPathFromPathComponents = getPathFromPathComponents;
    //// Path Normalization
    /**
     * Normalize path separators, converting `\` into `/`.
     */
    function normalizeSlashes(path) {
        return path.replace(backslashRegExp, ts.directorySeparator);
    }
    ts.normalizeSlashes = normalizeSlashes;
    /**
     * Reduce an array of path components to a more simplified path by navigating any
     * `"."` or `".."` entries in the path.
     */
    function reducePathComponents(components) {
        if (!ts.some(components))
            return [];
        var reduced = [components[0]];
        for (var i = 1; i < components.length; i++) {
            var component = components[i];
            if (!component)
                continue;
            if (component === ".")
                continue;
            if (component === "..") {
                if (reduced.length > 1) {
                    if (reduced[reduced.length - 1] !== "..") {
                        reduced.pop();
                        continue;
                    }
                }
                else if (reduced[0])
                    continue;
            }
            reduced.push(component);
        }
        return reduced;
    }
    ts.reducePathComponents = reducePathComponents;
    /**
     * Combines paths. If a path is absolute, it replaces any previous path. Relative paths are not simplified.
     *
     * ```ts
     * // Non-rooted
     * combinePaths("path", "to", "file.ext") === "path/to/file.ext"
     * combinePaths("path", "dir", "..", "to", "file.ext") === "path/dir/../to/file.ext"
     * // POSIX
     * combinePaths("/path", "to", "file.ext") === "/path/to/file.ext"
     * combinePaths("/path", "/to", "file.ext") === "/to/file.ext"
     * // DOS
     * combinePaths("c:/path", "to", "file.ext") === "c:/path/to/file.ext"
     * combinePaths("c:/path", "c:/to", "file.ext") === "c:/to/file.ext"
     * // URL
     * combinePaths("file:///path", "to", "file.ext") === "file:///path/to/file.ext"
     * combinePaths("file:///path", "file:///to", "file.ext") === "file:///to/file.ext"
     * ```
     */
    function combinePaths(path) {
        var paths = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            paths[_i - 1] = arguments[_i];
        }
        if (path)
            path = normalizeSlashes(path);
        for (var _a = 0, paths_1 = paths; _a < paths_1.length; _a++) {
            var relativePath = paths_1[_a];
            if (!relativePath)
                continue;
            relativePath = normalizeSlashes(relativePath);
            if (!path || getRootLength(relativePath) !== 0) {
                path = relativePath;
            }
            else {
                path = ensureTrailingDirectorySeparator(path) + relativePath;
            }
        }
        return path;
    }
    ts.combinePaths = combinePaths;
    /**
     * Combines and resolves paths. If a path is absolute, it replaces any previous path. Any
     * `.` and `..` path components are resolved. Trailing directory separators are preserved.
     *
     * ```ts
     * resolvePath("/path", "to", "file.ext") === "path/to/file.ext"
     * resolvePath("/path", "to", "file.ext/") === "path/to/file.ext/"
     * resolvePath("/path", "dir", "..", "to", "file.ext") === "path/to/file.ext"
     * ```
     */
    function resolvePath(path) {
        var paths = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            paths[_i - 1] = arguments[_i];
        }
        return normalizePath(ts.some(paths) ? combinePaths.apply(void 0, __spreadArrays([path], paths)) : normalizeSlashes(path));
    }
    ts.resolvePath = resolvePath;
    /**
     * Parse a path into an array containing a root component (at index 0) and zero or more path
     * components (at indices > 0). The result is normalized.
     * If the path is relative, the root component is `""`.
     * If the path is absolute, the root component includes the first path separator (`/`).
     *
     * ```ts
     * getNormalizedPathComponents("to/dir/../file.ext", "/path/") === ["/", "path", "to", "file.ext"]
     * ```
     */
    function getNormalizedPathComponents(path, currentDirectory) {
        return reducePathComponents(getPathComponents(path, currentDirectory));
    }
    ts.getNormalizedPathComponents = getNormalizedPathComponents;
    function getNormalizedAbsolutePath(fileName, currentDirectory) {
        return getPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
    }
    ts.getNormalizedAbsolutePath = getNormalizedAbsolutePath;
    function normalizePath(path) {
        path = normalizeSlashes(path);
        var normalized = getPathFromPathComponents(reducePathComponents(getPathComponents(path)));
        return normalized && hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalized) : normalized;
    }
    ts.normalizePath = normalizePath;
    function getPathWithoutRoot(pathComponents) {
        if (pathComponents.length === 0)
            return "";
        return pathComponents.slice(1).join(ts.directorySeparator);
    }
    function getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory) {
        return getPathWithoutRoot(getNormalizedPathComponents(fileName, currentDirectory));
    }
    ts.getNormalizedAbsolutePathWithoutRoot = getNormalizedAbsolutePathWithoutRoot;
    function toPath(fileName, basePath, getCanonicalFileName) {
        var nonCanonicalizedPath = isRootedDiskPath(fileName)
            ? normalizePath(fileName)
            : getNormalizedAbsolutePath(fileName, basePath);
        return getCanonicalFileName(nonCanonicalizedPath);
    }
    ts.toPath = toPath;
    function normalizePathAndParts(path) {
        path = normalizeSlashes(path);
        var _a = reducePathComponents(getPathComponents(path)), root = _a[0], parts = _a.slice(1);
        if (parts.length) {
            var joinedParts = root + parts.join(ts.directorySeparator);
            return { path: hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(joinedParts) : joinedParts, parts: parts };
        }
        else {
            return { path: root, parts: parts };
        }
    }
    ts.normalizePathAndParts = normalizePathAndParts;
    function removeTrailingDirectorySeparator(path) {
        if (hasTrailingDirectorySeparator(path)) {
            return path.substr(0, path.length - 1);
        }
        return path;
    }
    ts.removeTrailingDirectorySeparator = removeTrailingDirectorySeparator;
    function ensureTrailingDirectorySeparator(path) {
        if (!hasTrailingDirectorySeparator(path)) {
            return path + ts.directorySeparator;
        }
        return path;
    }
    ts.ensureTrailingDirectorySeparator = ensureTrailingDirectorySeparator;
    /**
     * Ensures a path is either absolute (prefixed with `/` or `c:`) or dot-relative (prefixed
     * with `./` or `../`) so as not to be confused with an unprefixed module name.
     *
     * ```ts
     * ensurePathIsNonModuleName("/path/to/file.ext") === "/path/to/file.ext"
     * ensurePathIsNonModuleName("./path/to/file.ext") === "./path/to/file.ext"
     * ensurePathIsNonModuleName("../path/to/file.ext") === "../path/to/file.ext"
     * ensurePathIsNonModuleName("path/to/file.ext") === "./path/to/file.ext"
     * ```
     */
    function ensurePathIsNonModuleName(path) {
        return !pathIsAbsolute(path) && !pathIsRelative(path) ? "./" + path : path;
    }
    ts.ensurePathIsNonModuleName = ensurePathIsNonModuleName;
    function changeAnyExtension(path, ext, extensions, ignoreCase) {
        var pathext = extensions !== undefined && ignoreCase !== undefined ? getAnyExtensionFromPath(path, extensions, ignoreCase) : getAnyExtensionFromPath(path);
        return pathext ? path.slice(0, path.length - pathext.length) + (ts.startsWith(ext, ".") ? ext : "." + ext) : path;
    }
    ts.changeAnyExtension = changeAnyExtension;
    //// Path Comparisons
    // check path for these segments: '', '.'. '..'
    var relativePathSegmentRegExp = /(^|\/)\.{0,2}($|\/)/;
    function comparePathsWorker(a, b, componentComparer) {
        if (a === b)
            return 0 /* EqualTo */;
        if (a === undefined)
            return -1 /* LessThan */;
        if (b === undefined)
            return 1 /* GreaterThan */;
        // NOTE: Performance optimization - shortcut if the root segments differ as there would be no
        //       need to perform path reduction.
        var aRoot = a.substring(0, getRootLength(a));
        var bRoot = b.substring(0, getRootLength(b));
        var result = ts.compareStringsCaseInsensitive(aRoot, bRoot);
        if (result !== 0 /* EqualTo */) {
            return result;
        }
        // NOTE: Performance optimization - shortcut if there are no relative path segments in
        //       the non-root portion of the path
        var aRest = a.substring(aRoot.length);
        var bRest = b.substring(bRoot.length);
        if (!relativePathSegmentRegExp.test(aRest) && !relativePathSegmentRegExp.test(bRest)) {
            return componentComparer(aRest, bRest);
        }
        // The path contains a relative path segment. Normalize the paths and perform a slower component
        // by component comparison.
        var aComponents = reducePathComponents(getPathComponents(a));
        var bComponents = reducePathComponents(getPathComponents(b));
        var sharedLength = Math.min(aComponents.length, bComponents.length);
        for (var i = 1; i < sharedLength; i++) {
            var result_1 = componentComparer(aComponents[i], bComponents[i]);
            if (result_1 !== 0 /* EqualTo */) {
                return result_1;
            }
        }
        return ts.compareValues(aComponents.length, bComponents.length);
    }
    /**
     * Performs a case-sensitive comparison of two paths. Path roots are always compared case-insensitively.
     */
    function comparePathsCaseSensitive(a, b) {
        return comparePathsWorker(a, b, ts.compareStringsCaseSensitive);
    }
    ts.comparePathsCaseSensitive = comparePathsCaseSensitive;
    /**
     * Performs a case-insensitive comparison of two paths.
     */
    function comparePathsCaseInsensitive(a, b) {
        return comparePathsWorker(a, b, ts.compareStringsCaseInsensitive);
    }
    ts.comparePathsCaseInsensitive = comparePathsCaseInsensitive;
    function comparePaths(a, b, currentDirectory, ignoreCase) {
        if (typeof currentDirectory === "string") {
            a = combinePaths(currentDirectory, a);
            b = combinePaths(currentDirectory, b);
        }
        else if (typeof currentDirectory === "boolean") {
            ignoreCase = currentDirectory;
        }
        return comparePathsWorker(a, b, ts.getStringComparer(ignoreCase));
    }
    ts.comparePaths = comparePaths;
    function containsPath(parent, child, currentDirectory, ignoreCase) {
        if (typeof currentDirectory === "string") {
            parent = combinePaths(currentDirectory, parent);
            child = combinePaths(currentDirectory, child);
        }
        else if (typeof currentDirectory === "boolean") {
            ignoreCase = currentDirectory;
        }
        if (parent === undefined || child === undefined)
            return false;
        if (parent === child)
            return true;
        var parentComponents = reducePathComponents(getPathComponents(parent));
        var childComponents = reducePathComponents(getPathComponents(child));
        if (childComponents.length < parentComponents.length) {
            return false;
        }
        var componentEqualityComparer = ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive;
        for (var i = 0; i < parentComponents.length; i++) {
            var equalityComparer = i === 0 ? ts.equateStringsCaseInsensitive : componentEqualityComparer;
            if (!equalityComparer(parentComponents[i], childComponents[i])) {
                return false;
            }
        }
        return true;
    }
    ts.containsPath = containsPath;
    /**
     * Determines whether `fileName` starts with the specified `directoryName` using the provided path canonicalization callback.
     * Comparison is case-sensitive between the canonical paths.
     *
     * @deprecated Use `containsPath` if possible.
     */
    function startsWithDirectory(fileName, directoryName, getCanonicalFileName) {
        var canonicalFileName = getCanonicalFileName(fileName);
        var canonicalDirectoryName = getCanonicalFileName(directoryName);
        return ts.startsWith(canonicalFileName, canonicalDirectoryName + "/") || ts.startsWith(canonicalFileName, canonicalDirectoryName + "\\");
    }
    ts.startsWithDirectory = startsWithDirectory;
    //// Relative Paths
    function getPathComponentsRelativeTo(from, to, stringEqualityComparer, getCanonicalFileName) {
        var fromComponents = reducePathComponents(getPathComponents(from));
        var toComponents = reducePathComponents(getPathComponents(to));
        var start;
        for (start = 0; start < fromComponents.length && start < toComponents.length; start++) {
            var fromComponent = getCanonicalFileName(fromComponents[start]);
            var toComponent = getCanonicalFileName(toComponents[start]);
            var comparer = start === 0 ? ts.equateStringsCaseInsensitive : stringEqualityComparer;
            if (!comparer(fromComponent, toComponent))
                break;
        }
        if (start === 0) {
            return toComponents;
        }
        var components = toComponents.slice(start);
        var relative = [];
        for (; start < fromComponents.length; start++) {
            relative.push("..");
        }
        return __spreadArrays([""], relative, components);
    }
    ts.getPathComponentsRelativeTo = getPathComponentsRelativeTo;
    function getRelativePathFromDirectory(fromDirectory, to, getCanonicalFileNameOrIgnoreCase) {
        ts.Debug.assert((getRootLength(fromDirectory) > 0) === (getRootLength(to) > 0), "Paths must either both be absolute or both be relative");
        var getCanonicalFileName = typeof getCanonicalFileNameOrIgnoreCase === "function" ? getCanonicalFileNameOrIgnoreCase : ts.identity;
        var ignoreCase = typeof getCanonicalFileNameOrIgnoreCase === "boolean" ? getCanonicalFileNameOrIgnoreCase : false;
        var pathComponents = getPathComponentsRelativeTo(fromDirectory, to, ignoreCase ? ts.equateStringsCaseInsensitive : ts.equateStringsCaseSensitive, getCanonicalFileName);
        return getPathFromPathComponents(pathComponents);
    }
    ts.getRelativePathFromDirectory = getRelativePathFromDirectory;
    function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) {
        return !isRootedDiskPath(absoluteOrRelativePath)
            ? absoluteOrRelativePath
            : getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
    }
    ts.convertToRelativePath = convertToRelativePath;
    function getRelativePathFromFile(from, to, getCanonicalFileName) {
        return ensurePathIsNonModuleName(getRelativePathFromDirectory(getDirectoryPath(from), to, getCanonicalFileName));
    }
    ts.getRelativePathFromFile = getRelativePathFromFile;
    function getRelativePathToDirectoryOrUrl(directoryPathOrUrl, relativeOrAbsolutePath, currentDirectory, getCanonicalFileName, isAbsolutePathAnUrl) {
        var pathComponents = getPathComponentsRelativeTo(resolvePath(currentDirectory, directoryPathOrUrl), resolvePath(currentDirectory, relativeOrAbsolutePath), ts.equateStringsCaseSensitive, getCanonicalFileName);
        var firstComponent = pathComponents[0];
        if (isAbsolutePathAnUrl && isRootedDiskPath(firstComponent)) {
            var prefix = firstComponent.charAt(0) === ts.directorySeparator ? "file://" : "file:///";
            pathComponents[0] = prefix + firstComponent;
        }
        return getPathFromPathComponents(pathComponents);
    }
    ts.getRelativePathToDirectoryOrUrl = getRelativePathToDirectoryOrUrl;
    function forEachAncestorDirectory(directory, callback) {
        while (true) {
            var result = callback(directory);
            if (result !== undefined) {
                return result;
            }
            var parentPath = getDirectoryPath(directory);
            if (parentPath === directory) {
                return undefined;
            }
            directory = parentPath;
        }
    }
    ts.forEachAncestorDirectory = forEachAncestorDirectory;
    function isNodeModulesDirectory(dirPath) {
        return ts.endsWith(dirPath, "/node_modules");
    }
    ts.isNodeModulesDirectory = isNodeModulesDirectory;
})(ts || (ts = {}));
// <auto-generated />
// generated from './diagnosticInformationMap.generated.ts' by 'src/compiler'
/* @internal */
var ts;
(function (ts) {
    function diag(code, category, key, message, reportsUnnecessary, elidedInCompatabilityPyramid) {
        return { code: code, category: category, key: key, message: message, reportsUnnecessary: reportsUnnecessary, elidedInCompatabilityPyramid: elidedInCompatabilityPyramid };
    }
    ts.Diagnostics = {
        Unterminated_string_literal: diag(1002, ts.DiagnosticCategory.Error, "Unterminated_string_literal_1002", "Unterminated string literal."),
        Identifier_expected: diag(1003, ts.DiagnosticCategory.Error, "Identifier_expected_1003", "Identifier expected."),
        _0_expected: diag(1005, ts.DiagnosticCategory.Error, "_0_expected_1005", "'{0}' expected."),
        A_file_cannot_have_a_reference_to_itself: diag(1006, ts.DiagnosticCategory.Error, "A_file_cannot_have_a_reference_to_itself_1006", "A file cannot have a reference to itself."),
        The_parser_expected_to_find_a_to_match_the_token_here: diag(1007, ts.DiagnosticCategory.Error, "The_parser_expected_to_find_a_to_match_the_token_here_1007", "The parser expected to find a '}' to match the '{' token here."),
        Trailing_comma_not_allowed: diag(1009, ts.DiagnosticCategory.Error, "Trailing_comma_not_allowed_1009", "Trailing comma not allowed."),
        Asterisk_Slash_expected: diag(1010, ts.DiagnosticCategory.Error, "Asterisk_Slash_expected_1010", "'*/' expected."),
        An_element_access_expression_should_take_an_argument: diag(1011, ts.DiagnosticCategory.Error, "An_element_access_expression_should_take_an_argument_1011", "An element access expression should take an argument."),
        Unexpected_token: diag(1012, ts.DiagnosticCategory.Error, "Unexpected_token_1012", "Unexpected token."),
        A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma: diag(1013, ts.DiagnosticCategory.Error, "A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma_1013", "A rest parameter or binding pattern may not have a trailing comma."),
        A_rest_parameter_must_be_last_in_a_parameter_list: diag(1014, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_last_in_a_parameter_list_1014", "A rest parameter must be last in a parameter list."),
        Parameter_cannot_have_question_mark_and_initializer: diag(1015, ts.DiagnosticCategory.Error, "Parameter_cannot_have_question_mark_and_initializer_1015", "Parameter cannot have question mark and initializer."),
        A_required_parameter_cannot_follow_an_optional_parameter: diag(1016, ts.DiagnosticCategory.Error, "A_required_parameter_cannot_follow_an_optional_parameter_1016", "A required parameter cannot follow an optional parameter."),
        An_index_signature_cannot_have_a_rest_parameter: diag(1017, ts.DiagnosticCategory.Error, "An_index_signature_cannot_have_a_rest_parameter_1017", "An index signature cannot have a rest parameter."),
        An_index_signature_parameter_cannot_have_an_accessibility_modifier: diag(1018, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018", "An index signature parameter cannot have an accessibility modifier."),
        An_index_signature_parameter_cannot_have_a_question_mark: diag(1019, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_a_question_mark_1019", "An index signature parameter cannot have a question mark."),
        An_index_signature_parameter_cannot_have_an_initializer: diag(1020, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_initializer_1020", "An index signature parameter cannot have an initializer."),
        An_index_signature_must_have_a_type_annotation: diag(1021, ts.DiagnosticCategory.Error, "An_index_signature_must_have_a_type_annotation_1021", "An index signature must have a type annotation."),
        An_index_signature_parameter_must_have_a_type_annotation: diag(1022, ts.DiagnosticCategory.Error, "An_index_signature_parameter_must_have_a_type_annotation_1022", "An index signature parameter must have a type annotation."),
        An_index_signature_parameter_type_must_be_either_string_or_number: diag(1023, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_must_be_either_string_or_number_1023", "An index signature parameter type must be either 'string' or 'number'."),
        readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature: diag(1024, ts.DiagnosticCategory.Error, "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024", "'readonly' modifier can only appear on a property declaration or index signature."),
        An_index_signature_cannot_have_a_trailing_comma: diag(1025, ts.DiagnosticCategory.Error, "An_index_signature_cannot_have_a_trailing_comma_1025", "An index signature cannot have a trailing comma."),
        Accessibility_modifier_already_seen: diag(1028, ts.DiagnosticCategory.Error, "Accessibility_modifier_already_seen_1028", "Accessibility modifier already seen."),
        _0_modifier_must_precede_1_modifier: diag(1029, ts.DiagnosticCategory.Error, "_0_modifier_must_precede_1_modifier_1029", "'{0}' modifier must precede '{1}' modifier."),
        _0_modifier_already_seen: diag(1030, ts.DiagnosticCategory.Error, "_0_modifier_already_seen_1030", "'{0}' modifier already seen."),
        _0_modifier_cannot_appear_on_a_class_element: diag(1031, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_class_element_1031", "'{0}' modifier cannot appear on a class element."),
        super_must_be_followed_by_an_argument_list_or_member_access: diag(1034, ts.DiagnosticCategory.Error, "super_must_be_followed_by_an_argument_list_or_member_access_1034", "'super' must be followed by an argument list or member access."),
        Only_ambient_modules_can_use_quoted_names: diag(1035, ts.DiagnosticCategory.Error, "Only_ambient_modules_can_use_quoted_names_1035", "Only ambient modules can use quoted names."),
        Statements_are_not_allowed_in_ambient_contexts: diag(1036, ts.DiagnosticCategory.Error, "Statements_are_not_allowed_in_ambient_contexts_1036", "Statements are not allowed in ambient contexts."),
        A_declare_modifier_cannot_be_used_in_an_already_ambient_context: diag(1038, ts.DiagnosticCategory.Error, "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038", "A 'declare' modifier cannot be used in an already ambient context."),
        Initializers_are_not_allowed_in_ambient_contexts: diag(1039, ts.DiagnosticCategory.Error, "Initializers_are_not_allowed_in_ambient_contexts_1039", "Initializers are not allowed in ambient contexts."),
        _0_modifier_cannot_be_used_in_an_ambient_context: diag(1040, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_in_an_ambient_context_1040", "'{0}' modifier cannot be used in an ambient context."),
        _0_modifier_cannot_be_used_with_a_class_declaration: diag(1041, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_a_class_declaration_1041", "'{0}' modifier cannot be used with a class declaration."),
        _0_modifier_cannot_be_used_here: diag(1042, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_here_1042", "'{0}' modifier cannot be used here."),
        _0_modifier_cannot_appear_on_a_data_property: diag(1043, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_data_property_1043", "'{0}' modifier cannot appear on a data property."),
        _0_modifier_cannot_appear_on_a_module_or_namespace_element: diag(1044, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044", "'{0}' modifier cannot appear on a module or namespace element."),
        A_0_modifier_cannot_be_used_with_an_interface_declaration: diag(1045, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_interface_declaration_1045", "A '{0}' modifier cannot be used with an interface declaration."),
        Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier: diag(1046, ts.DiagnosticCategory.Error, "Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier_1046", "Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier."),
        A_rest_parameter_cannot_be_optional: diag(1047, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_be_optional_1047", "A rest parameter cannot be optional."),
        A_rest_parameter_cannot_have_an_initializer: diag(1048, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_have_an_initializer_1048", "A rest parameter cannot have an initializer."),
        A_set_accessor_must_have_exactly_one_parameter: diag(1049, ts.DiagnosticCategory.Error, "A_set_accessor_must_have_exactly_one_parameter_1049", "A 'set' accessor must have exactly one parameter."),
        A_set_accessor_cannot_have_an_optional_parameter: diag(1051, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_an_optional_parameter_1051", "A 'set' accessor cannot have an optional parameter."),
        A_set_accessor_parameter_cannot_have_an_initializer: diag(1052, ts.DiagnosticCategory.Error, "A_set_accessor_parameter_cannot_have_an_initializer_1052", "A 'set' accessor parameter cannot have an initializer."),
        A_set_accessor_cannot_have_rest_parameter: diag(1053, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_rest_parameter_1053", "A 'set' accessor cannot have rest parameter."),
        A_get_accessor_cannot_have_parameters: diag(1054, ts.DiagnosticCategory.Error, "A_get_accessor_cannot_have_parameters_1054", "A 'get' accessor cannot have parameters."),
        Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value: diag(1055, ts.DiagnosticCategory.Error, "Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Prom_1055", "Type '{0}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value."),
        Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: diag(1056, ts.DiagnosticCategory.Error, "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056", "Accessors are only available when targeting ECMAScript 5 and higher."),
        An_async_function_or_method_must_have_a_valid_awaitable_return_type: diag(1057, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_have_a_valid_awaitable_return_type_1057", "An async function or method must have a valid awaitable return type."),
        The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1058, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_t_1058", "The return type of an async function must either be a valid promise or must not contain a callable 'then' member."),
        A_promise_must_have_a_then_method: diag(1059, ts.DiagnosticCategory.Error, "A_promise_must_have_a_then_method_1059", "A promise must have a 'then' method."),
        The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback: diag(1060, ts.DiagnosticCategory.Error, "The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback_1060", "The first parameter of the 'then' method of a promise must be a callback."),
        Enum_member_must_have_initializer: diag(1061, ts.DiagnosticCategory.Error, "Enum_member_must_have_initializer_1061", "Enum member must have initializer."),
        Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method: diag(1062, ts.DiagnosticCategory.Error, "Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062", "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method."),
        An_export_assignment_cannot_be_used_in_a_namespace: diag(1063, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_namespace_1063", "An export assignment cannot be used in a namespace."),
        The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type: diag(1064, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1064", "The return type of an async function or method must be the global Promise<T> type."),
        In_ambient_enum_declarations_member_initializer_must_be_constant_expression: diag(1066, ts.DiagnosticCategory.Error, "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066", "In ambient enum declarations member initializer must be constant expression."),
        Unexpected_token_A_constructor_method_accessor_or_property_was_expected: diag(1068, ts.DiagnosticCategory.Error, "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068", "Unexpected token. A constructor, method, accessor, or property was expected."),
        Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces: diag(1069, ts.DiagnosticCategory.Error, "Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces_1069", "Unexpected token. A type parameter name was expected without curly braces."),
        _0_modifier_cannot_appear_on_a_type_member: diag(1070, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_type_member_1070", "'{0}' modifier cannot appear on a type member."),
        _0_modifier_cannot_appear_on_an_index_signature: diag(1071, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_an_index_signature_1071", "'{0}' modifier cannot appear on an index signature."),
        A_0_modifier_cannot_be_used_with_an_import_declaration: diag(1079, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_import_declaration_1079", "A '{0}' modifier cannot be used with an import declaration."),
        Invalid_reference_directive_syntax: diag(1084, ts.DiagnosticCategory.Error, "Invalid_reference_directive_syntax_1084", "Invalid 'reference' directive syntax."),
        Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0: diag(1085, ts.DiagnosticCategory.Error, "Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0_1085", "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'."),
        _0_modifier_cannot_appear_on_a_constructor_declaration: diag(1089, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_constructor_declaration_1089", "'{0}' modifier cannot appear on a constructor declaration."),
        _0_modifier_cannot_appear_on_a_parameter: diag(1090, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_parameter_1090", "'{0}' modifier cannot appear on a parameter."),
        Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: diag(1091, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091", "Only a single variable declaration is allowed in a 'for...in' statement."),
        Type_parameters_cannot_appear_on_a_constructor_declaration: diag(1092, ts.DiagnosticCategory.Error, "Type_parameters_cannot_appear_on_a_constructor_declaration_1092", "Type parameters cannot appear on a constructor declaration."),
        Type_annotation_cannot_appear_on_a_constructor_declaration: diag(1093, ts.DiagnosticCategory.Error, "Type_annotation_cannot_appear_on_a_constructor_declaration_1093", "Type annotation cannot appear on a constructor declaration."),
        An_accessor_cannot_have_type_parameters: diag(1094, ts.DiagnosticCategory.Error, "An_accessor_cannot_have_type_parameters_1094", "An accessor cannot have type parameters."),
        A_set_accessor_cannot_have_a_return_type_annotation: diag(1095, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_a_return_type_annotation_1095", "A 'set' accessor cannot have a return type annotation."),
        An_index_signature_must_have_exactly_one_parameter: diag(1096, ts.DiagnosticCategory.Error, "An_index_signature_must_have_exactly_one_parameter_1096", "An index signature must have exactly one parameter."),
        _0_list_cannot_be_empty: diag(1097, ts.DiagnosticCategory.Error, "_0_list_cannot_be_empty_1097", "'{0}' list cannot be empty."),
        Type_parameter_list_cannot_be_empty: diag(1098, ts.DiagnosticCategory.Error, "Type_parameter_list_cannot_be_empty_1098", "Type parameter list cannot be empty."),
        Type_argument_list_cannot_be_empty: diag(1099, ts.DiagnosticCategory.Error, "Type_argument_list_cannot_be_empty_1099", "Type argument list cannot be empty."),
        Invalid_use_of_0_in_strict_mode: diag(1100, ts.DiagnosticCategory.Error, "Invalid_use_of_0_in_strict_mode_1100", "Invalid use of '{0}' in strict mode."),
        with_statements_are_not_allowed_in_strict_mode: diag(1101, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_strict_mode_1101", "'with' statements are not allowed in strict mode."),
        delete_cannot_be_called_on_an_identifier_in_strict_mode: diag(1102, ts.DiagnosticCategory.Error, "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102", "'delete' cannot be called on an identifier in strict mode."),
        A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator: diag(1103, ts.DiagnosticCategory.Error, "A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator_1103", "A 'for-await-of' statement is only allowed within an async function or async generator."),
        A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: diag(1104, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104", "A 'continue' statement can only be used within an enclosing iteration statement."),
        A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: diag(1105, ts.DiagnosticCategory.Error, "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105", "A 'break' statement can only be used within an enclosing iteration or switch statement."),
        Jump_target_cannot_cross_function_boundary: diag(1107, ts.DiagnosticCategory.Error, "Jump_target_cannot_cross_function_boundary_1107", "Jump target cannot cross function boundary."),
        A_return_statement_can_only_be_used_within_a_function_body: diag(1108, ts.DiagnosticCategory.Error, "A_return_statement_can_only_be_used_within_a_function_body_1108", "A 'return' statement can only be used within a function body."),
        Expression_expected: diag(1109, ts.DiagnosticCategory.Error, "Expression_expected_1109", "Expression expected."),
        Type_expected: diag(1110, ts.DiagnosticCategory.Error, "Type_expected_1110", "Type expected."),
        A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: diag(1113, ts.DiagnosticCategory.Error, "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113", "A 'default' clause cannot appear more than once in a 'switch' statement."),
        Duplicate_label_0: diag(1114, ts.DiagnosticCategory.Error, "Duplicate_label_0_1114", "Duplicate label '{0}'."),
        A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: diag(1115, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115", "A 'continue' statement can only jump to a label of an enclosing iteration statement."),
        A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement: diag(1116, ts.DiagnosticCategory.Error, "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116", "A 'break' statement can only jump to a label of an enclosing statement."),
        An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: diag(1117, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode_1117", "An object literal cannot have multiple properties with the same name in strict mode."),
        An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: diag(1118, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118", "An object literal cannot have multiple get/set accessors with the same name."),
        An_object_literal_cannot_have_property_and_accessor_with_the_same_name: diag(1119, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119", "An object literal cannot have property and accessor with the same name."),
        An_export_assignment_cannot_have_modifiers: diag(1120, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_have_modifiers_1120", "An export assignment cannot have modifiers."),
        Octal_literals_are_not_allowed_in_strict_mode: diag(1121, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_strict_mode_1121", "Octal literals are not allowed in strict mode."),
        Variable_declaration_list_cannot_be_empty: diag(1123, ts.DiagnosticCategory.Error, "Variable_declaration_list_cannot_be_empty_1123", "Variable declaration list cannot be empty."),
        Digit_expected: diag(1124, ts.DiagnosticCategory.Error, "Digit_expected_1124", "Digit expected."),
        Hexadecimal_digit_expected: diag(1125, ts.DiagnosticCategory.Error, "Hexadecimal_digit_expected_1125", "Hexadecimal digit expected."),
        Unexpected_end_of_text: diag(1126, ts.DiagnosticCategory.Error, "Unexpected_end_of_text_1126", "Unexpected end of text."),
        Invalid_character: diag(1127, ts.DiagnosticCategory.Error, "Invalid_character_1127", "Invalid character."),
        Declaration_or_statement_expected: diag(1128, ts.DiagnosticCategory.Error, "Declaration_or_statement_expected_1128", "Declaration or statement expected."),
        Statement_expected: diag(1129, ts.DiagnosticCategory.Error, "Statement_expected_1129", "Statement expected."),
        case_or_default_expected: diag(1130, ts.DiagnosticCategory.Error, "case_or_default_expected_1130", "'case' or 'default' expected."),
        Property_or_signature_expected: diag(1131, ts.DiagnosticCategory.Error, "Property_or_signature_expected_1131", "Property or signature expected."),
        Enum_member_expected: diag(1132, ts.DiagnosticCategory.Error, "Enum_member_expected_1132", "Enum member expected."),
        Variable_declaration_expected: diag(1134, ts.DiagnosticCategory.Error, "Variable_declaration_expected_1134", "Variable declaration expected."),
        Argument_expression_expected: diag(1135, ts.DiagnosticCategory.Error, "Argument_expression_expected_1135", "Argument expression expected."),
        Property_assignment_expected: diag(1136, ts.DiagnosticCategory.Error, "Property_assignment_expected_1136", "Property assignment expected."),
        Expression_or_comma_expected: diag(1137, ts.DiagnosticCategory.Error, "Expression_or_comma_expected_1137", "Expression or comma expected."),
        Parameter_declaration_expected: diag(1138, ts.DiagnosticCategory.Error, "Parameter_declaration_expected_1138", "Parameter declaration expected."),
        Type_parameter_declaration_expected: diag(1139, ts.DiagnosticCategory.Error, "Type_parameter_declaration_expected_1139", "Type parameter declaration expected."),
        Type_argument_expected: diag(1140, ts.DiagnosticCategory.Error, "Type_argument_expected_1140", "Type argument expected."),
        String_literal_expected: diag(1141, ts.DiagnosticCategory.Error, "String_literal_expected_1141", "String literal expected."),
        Line_break_not_permitted_here: diag(1142, ts.DiagnosticCategory.Error, "Line_break_not_permitted_here_1142", "Line break not permitted here."),
        or_expected: diag(1144, ts.DiagnosticCategory.Error, "or_expected_1144", "'{' or ';' expected."),
        Declaration_expected: diag(1146, ts.DiagnosticCategory.Error, "Declaration_expected_1146", "Declaration expected."),
        Import_declarations_in_a_namespace_cannot_reference_a_module: diag(1147, ts.DiagnosticCategory.Error, "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", "Import declarations in a namespace cannot reference a module."),
        Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: diag(1148, ts.DiagnosticCategory.Error, "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", "Cannot use imports, exports, or module augmentations when '--module' is 'none'."),
        File_name_0_differs_from_already_included_file_name_1_only_in_casing: diag(1149, ts.DiagnosticCategory.Error, "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", "File name '{0}' differs from already included file name '{1}' only in casing."),
        const_declarations_must_be_initialized: diag(1155, ts.DiagnosticCategory.Error, "const_declarations_must_be_initialized_1155", "'const' declarations must be initialized."),
        const_declarations_can_only_be_declared_inside_a_block: diag(1156, ts.DiagnosticCategory.Error, "const_declarations_can_only_be_declared_inside_a_block_1156", "'const' declarations can only be declared inside a block."),
        let_declarations_can_only_be_declared_inside_a_block: diag(1157, ts.DiagnosticCategory.Error, "let_declarations_can_only_be_declared_inside_a_block_1157", "'let' declarations can only be declared inside a block."),
        Unterminated_template_literal: diag(1160, ts.DiagnosticCategory.Error, "Unterminated_template_literal_1160", "Unterminated template literal."),
        Unterminated_regular_expression_literal: diag(1161, ts.DiagnosticCategory.Error, "Unterminated_regular_expression_literal_1161", "Unterminated regular expression literal."),
        An_object_member_cannot_be_declared_optional: diag(1162, ts.DiagnosticCategory.Error, "An_object_member_cannot_be_declared_optional_1162", "An object member cannot be declared optional."),
        A_yield_expression_is_only_allowed_in_a_generator_body: diag(1163, ts.DiagnosticCategory.Error, "A_yield_expression_is_only_allowed_in_a_generator_body_1163", "A 'yield' expression is only allowed in a generator body."),
        Computed_property_names_are_not_allowed_in_enums: diag(1164, ts.DiagnosticCategory.Error, "Computed_property_names_are_not_allowed_in_enums_1164", "Computed property names are not allowed in enums."),
        A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1165, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_t_1165", "A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1166, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_1166", "A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1168, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_ty_1168", "A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1169, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_1169", "A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1170, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type__1170", "A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type."),
        A_comma_expression_is_not_allowed_in_a_computed_property_name: diag(1171, ts.DiagnosticCategory.Error, "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171", "A comma expression is not allowed in a computed property name."),
        extends_clause_already_seen: diag(1172, ts.DiagnosticCategory.Error, "extends_clause_already_seen_1172", "'extends' clause already seen."),
        extends_clause_must_precede_implements_clause: diag(1173, ts.DiagnosticCategory.Error, "extends_clause_must_precede_implements_clause_1173", "'extends' clause must precede 'implements' clause."),
        Classes_can_only_extend_a_single_class: diag(1174, ts.DiagnosticCategory.Error, "Classes_can_only_extend_a_single_class_1174", "Classes can only extend a single class."),
        implements_clause_already_seen: diag(1175, ts.DiagnosticCategory.Error, "implements_clause_already_seen_1175", "'implements' clause already seen."),
        Interface_declaration_cannot_have_implements_clause: diag(1176, ts.DiagnosticCategory.Error, "Interface_declaration_cannot_have_implements_clause_1176", "Interface declaration cannot have 'implements' clause."),
        Binary_digit_expected: diag(1177, ts.DiagnosticCategory.Error, "Binary_digit_expected_1177", "Binary digit expected."),
        Octal_digit_expected: diag(1178, ts.DiagnosticCategory.Error, "Octal_digit_expected_1178", "Octal digit expected."),
        Unexpected_token_expected: diag(1179, ts.DiagnosticCategory.Error, "Unexpected_token_expected_1179", "Unexpected token. '{' expected."),
        Property_destructuring_pattern_expected: diag(1180, ts.DiagnosticCategory.Error, "Property_destructuring_pattern_expected_1180", "Property destructuring pattern expected."),
        Array_element_destructuring_pattern_expected: diag(1181, ts.DiagnosticCategory.Error, "Array_element_destructuring_pattern_expected_1181", "Array element destructuring pattern expected."),
        A_destructuring_declaration_must_have_an_initializer: diag(1182, ts.DiagnosticCategory.Error, "A_destructuring_declaration_must_have_an_initializer_1182", "A destructuring declaration must have an initializer."),
        An_implementation_cannot_be_declared_in_ambient_contexts: diag(1183, ts.DiagnosticCategory.Error, "An_implementation_cannot_be_declared_in_ambient_contexts_1183", "An implementation cannot be declared in ambient contexts."),
        Modifiers_cannot_appear_here: diag(1184, ts.DiagnosticCategory.Error, "Modifiers_cannot_appear_here_1184", "Modifiers cannot appear here."),
        Merge_conflict_marker_encountered: diag(1185, ts.DiagnosticCategory.Error, "Merge_conflict_marker_encountered_1185", "Merge conflict marker encountered."),
        A_rest_element_cannot_have_an_initializer: diag(1186, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_an_initializer_1186", "A rest element cannot have an initializer."),
        A_parameter_property_may_not_be_declared_using_a_binding_pattern: diag(1187, ts.DiagnosticCategory.Error, "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187", "A parameter property may not be declared using a binding pattern."),
        Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: diag(1188, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188", "Only a single variable declaration is allowed in a 'for...of' statement."),
        The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: diag(1189, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189", "The variable declaration of a 'for...in' statement cannot have an initializer."),
        The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: diag(1190, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190", "The variable declaration of a 'for...of' statement cannot have an initializer."),
        An_import_declaration_cannot_have_modifiers: diag(1191, ts.DiagnosticCategory.Error, "An_import_declaration_cannot_have_modifiers_1191", "An import declaration cannot have modifiers."),
        Module_0_has_no_default_export: diag(1192, ts.DiagnosticCategory.Error, "Module_0_has_no_default_export_1192", "Module '{0}' has no default export."),
        An_export_declaration_cannot_have_modifiers: diag(1193, ts.DiagnosticCategory.Error, "An_export_declaration_cannot_have_modifiers_1193", "An export declaration cannot have modifiers."),
        Export_declarations_are_not_permitted_in_a_namespace: diag(1194, ts.DiagnosticCategory.Error, "Export_declarations_are_not_permitted_in_a_namespace_1194", "Export declarations are not permitted in a namespace."),
        export_Asterisk_does_not_re_export_a_default: diag(1195, ts.DiagnosticCategory.Error, "export_Asterisk_does_not_re_export_a_default_1195", "'export *' does not re-export a default."),
        Catch_clause_variable_cannot_have_a_type_annotation: diag(1196, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_a_type_annotation_1196", "Catch clause variable cannot have a type annotation."),
        Catch_clause_variable_cannot_have_an_initializer: diag(1197, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_an_initializer_1197", "Catch clause variable cannot have an initializer."),
        An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: diag(1198, ts.DiagnosticCategory.Error, "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198", "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive."),
        Unterminated_Unicode_escape_sequence: diag(1199, ts.DiagnosticCategory.Error, "Unterminated_Unicode_escape_sequence_1199", "Unterminated Unicode escape sequence."),
        Line_terminator_not_permitted_before_arrow: diag(1200, ts.DiagnosticCategory.Error, "Line_terminator_not_permitted_before_arrow_1200", "Line terminator not permitted before arrow."),
        Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead: diag(1202, ts.DiagnosticCategory.Error, "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202", "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead."),
        Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead: diag(1203, ts.DiagnosticCategory.Error, "Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or__1203", "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead."),
        Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type: diag(1205, ts.DiagnosticCategory.Error, "Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type_1205", "Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'."),
        Decorators_are_not_valid_here: diag(1206, ts.DiagnosticCategory.Error, "Decorators_are_not_valid_here_1206", "Decorators are not valid here."),
        Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: diag(1207, ts.DiagnosticCategory.Error, "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207", "Decorators cannot be applied to multiple get/set accessors of the same name."),
        All_files_must_be_modules_when_the_isolatedModules_flag_is_provided: diag(1208, ts.DiagnosticCategory.Error, "All_files_must_be_modules_when_the_isolatedModules_flag_is_provided_1208", "All files must be modules when the '--isolatedModules' flag is provided."),
        Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: diag(1210, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode_1210", "Invalid use of '{0}'. Class definitions are automatically in strict mode."),
        A_class_declaration_without_the_default_modifier_must_have_a_name: diag(1211, ts.DiagnosticCategory.Error, "A_class_declaration_without_the_default_modifier_must_have_a_name_1211", "A class declaration without the 'default' modifier must have a name."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode: diag(1212, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212", "Identifier expected. '{0}' is a reserved word in strict mode."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: diag(1213, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213", "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode."),
        Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode: diag(1214, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214", "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode."),
        Invalid_use_of_0_Modules_are_automatically_in_strict_mode: diag(1215, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215", "Invalid use of '{0}'. Modules are automatically in strict mode."),
        Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules: diag(1216, ts.DiagnosticCategory.Error, "Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules_1216", "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules."),
        Export_assignment_is_not_supported_when_module_flag_is_system: diag(1218, ts.DiagnosticCategory.Error, "Export_assignment_is_not_supported_when_module_flag_is_system_1218", "Export assignment is not supported when '--module' flag is 'system'."),
        Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning: diag(1219, ts.DiagnosticCategory.Error, "Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_t_1219", "Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option in your 'tsconfig' or 'jsconfig' to remove this warning."),
        Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher: diag(1220, ts.DiagnosticCategory.Error, "Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher_1220", "Generators are only available when targeting ECMAScript 2015 or higher."),
        Generators_are_not_allowed_in_an_ambient_context: diag(1221, ts.DiagnosticCategory.Error, "Generators_are_not_allowed_in_an_ambient_context_1221", "Generators are not allowed in an ambient context."),
        An_overload_signature_cannot_be_declared_as_a_generator: diag(1222, ts.DiagnosticCategory.Error, "An_overload_signature_cannot_be_declared_as_a_generator_1222", "An overload signature cannot be declared as a generator."),
        _0_tag_already_specified: diag(1223, ts.DiagnosticCategory.Error, "_0_tag_already_specified_1223", "'{0}' tag already specified."),
        Signature_0_must_be_a_type_predicate: diag(1224, ts.DiagnosticCategory.Error, "Signature_0_must_be_a_type_predicate_1224", "Signature '{0}' must be a type predicate."),
        Cannot_find_parameter_0: diag(1225, ts.DiagnosticCategory.Error, "Cannot_find_parameter_0_1225", "Cannot find parameter '{0}'."),
        Type_predicate_0_is_not_assignable_to_1: diag(1226, ts.DiagnosticCategory.Error, "Type_predicate_0_is_not_assignable_to_1_1226", "Type predicate '{0}' is not assignable to '{1}'."),
        Parameter_0_is_not_in_the_same_position_as_parameter_1: diag(1227, ts.DiagnosticCategory.Error, "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227", "Parameter '{0}' is not in the same position as parameter '{1}'."),
        A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: diag(1228, ts.DiagnosticCategory.Error, "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228", "A type predicate is only allowed in return type position for functions and methods."),
        A_type_predicate_cannot_reference_a_rest_parameter: diag(1229, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_a_rest_parameter_1229", "A type predicate cannot reference a rest parameter."),
        A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: diag(1230, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230", "A type predicate cannot reference element '{0}' in a binding pattern."),
        An_export_assignment_can_only_be_used_in_a_module: diag(1231, ts.DiagnosticCategory.Error, "An_export_assignment_can_only_be_used_in_a_module_1231", "An export assignment can only be used in a module."),
        An_import_declaration_can_only_be_used_in_a_namespace_or_module: diag(1232, ts.DiagnosticCategory.Error, "An_import_declaration_can_only_be_used_in_a_namespace_or_module_1232", "An import declaration can only be used in a namespace or module."),
        An_export_declaration_can_only_be_used_in_a_module: diag(1233, ts.DiagnosticCategory.Error, "An_export_declaration_can_only_be_used_in_a_module_1233", "An export declaration can only be used in a module."),
        An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: diag(1234, ts.DiagnosticCategory.Error, "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234", "An ambient module declaration is only allowed at the top level in a file."),
        A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: diag(1235, ts.DiagnosticCategory.Error, "A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235", "A namespace declaration is only allowed in a namespace or module."),
        The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: diag(1236, ts.DiagnosticCategory.Error, "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236", "The return type of a property decorator function must be either 'void' or 'any'."),
        The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: diag(1237, ts.DiagnosticCategory.Error, "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237", "The return type of a parameter decorator function must be either 'void' or 'any'."),
        Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: diag(1238, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238", "Unable to resolve signature of class decorator when called as an expression."),
        Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: diag(1239, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239", "Unable to resolve signature of parameter decorator when called as an expression."),
        Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: diag(1240, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240", "Unable to resolve signature of property decorator when called as an expression."),
        Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: diag(1241, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241", "Unable to resolve signature of method decorator when called as an expression."),
        abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration: diag(1242, ts.DiagnosticCategory.Error, "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242", "'abstract' modifier can only appear on a class, method, or property declaration."),
        _0_modifier_cannot_be_used_with_1_modifier: diag(1243, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_1_modifier_1243", "'{0}' modifier cannot be used with '{1}' modifier."),
        Abstract_methods_can_only_appear_within_an_abstract_class: diag(1244, ts.DiagnosticCategory.Error, "Abstract_methods_can_only_appear_within_an_abstract_class_1244", "Abstract methods can only appear within an abstract class."),
        Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: diag(1245, ts.DiagnosticCategory.Error, "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245", "Method '{0}' cannot have an implementation because it is marked abstract."),
        An_interface_property_cannot_have_an_initializer: diag(1246, ts.DiagnosticCategory.Error, "An_interface_property_cannot_have_an_initializer_1246", "An interface property cannot have an initializer."),
        A_type_literal_property_cannot_have_an_initializer: diag(1247, ts.DiagnosticCategory.Error, "A_type_literal_property_cannot_have_an_initializer_1247", "A type literal property cannot have an initializer."),
        A_class_member_cannot_have_the_0_keyword: diag(1248, ts.DiagnosticCategory.Error, "A_class_member_cannot_have_the_0_keyword_1248", "A class member cannot have the '{0}' keyword."),
        A_decorator_can_only_decorate_a_method_implementation_not_an_overload: diag(1249, ts.DiagnosticCategory.Error, "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249", "A decorator can only decorate a method implementation, not an overload."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5: diag(1250, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode: diag(1251, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_d_1251", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Class definitions are automatically in strict mode."),
        Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode: diag(1252, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_1252", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode."),
        _0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag: diag(1253, ts.DiagnosticCategory.Error, "_0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag_1253", "'{0}' tag cannot be used independently as a top level JSDoc tag."),
        A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference: diag(1254, ts.DiagnosticCategory.Error, "A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_refere_1254", "A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference."),
        A_definite_assignment_assertion_is_not_permitted_in_this_context: diag(1255, ts.DiagnosticCategory.Error, "A_definite_assignment_assertion_is_not_permitted_in_this_context_1255", "A definite assignment assertion '!' is not permitted in this context."),
        A_rest_element_must_be_last_in_a_tuple_type: diag(1256, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_tuple_type_1256", "A rest element must be last in a tuple type."),
        A_required_element_cannot_follow_an_optional_element: diag(1257, ts.DiagnosticCategory.Error, "A_required_element_cannot_follow_an_optional_element_1257", "A required element cannot follow an optional element."),
        Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation: diag(1258, ts.DiagnosticCategory.Error, "Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation_1258", "Definite assignment assertions can only be used along with a type annotation."),
        Module_0_can_only_be_default_imported_using_the_1_flag: diag(1259, ts.DiagnosticCategory.Error, "Module_0_can_only_be_default_imported_using_the_1_flag_1259", "Module '{0}' can only be default-imported using the '{1}' flag"),
        Keywords_cannot_contain_escape_characters: diag(1260, ts.DiagnosticCategory.Error, "Keywords_cannot_contain_escape_characters_1260", "Keywords cannot contain escape characters."),
        Already_included_file_name_0_differs_from_file_name_1_only_in_casing: diag(1261, ts.DiagnosticCategory.Error, "Already_included_file_name_0_differs_from_file_name_1_only_in_casing_1261", "Already included file name '{0}' differs from file name '{1}' only in casing."),
        with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."),
        await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules: diag(1308, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules_1308", "'await' expressions are only allowed within async functions and at the top levels of modules."),
        can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."),
        The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."),
        Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."),
        Global_module_exports_may_only_appear_in_declaration_files: diag(1315, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_declaration_files_1315", "Global module exports may only appear in declaration files."),
        Global_module_exports_may_only_appear_at_top_level: diag(1316, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_at_top_level_1316", "Global module exports may only appear at top level."),
        A_parameter_property_cannot_be_declared_using_a_rest_parameter: diag(1317, ts.DiagnosticCategory.Error, "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317", "A parameter property cannot be declared using a rest parameter."),
        An_abstract_accessor_cannot_have_an_implementation: diag(1318, ts.DiagnosticCategory.Error, "An_abstract_accessor_cannot_have_an_implementation_1318", "An abstract accessor cannot have an implementation."),
        A_default_export_can_only_be_used_in_an_ECMAScript_style_module: diag(1319, ts.DiagnosticCategory.Error, "A_default_export_can_only_be_used_in_an_ECMAScript_style_module_1319", "A default export can only be used in an ECMAScript-style module."),
        Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1320, ts.DiagnosticCategory.Error, "Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member_1320", "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member."),
        Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1321, ts.DiagnosticCategory.Error, "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321", "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member."),
        Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1322, ts.DiagnosticCategory.Error, "Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322", "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member."),
        Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_esnext_commonjs_amd_system_or_umd: diag(1323, ts.DiagnosticCategory.Error, "Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_esnext_commonjs_amd_system__1323", "Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'esnext', 'commonjs', 'amd', 'system', or 'umd'."),
        Dynamic_import_must_have_one_specifier_as_an_argument: diag(1324, ts.DiagnosticCategory.Error, "Dynamic_import_must_have_one_specifier_as_an_argument_1324", "Dynamic import must have one specifier as an argument."),
        Specifier_of_dynamic_import_cannot_be_spread_element: diag(1325, ts.DiagnosticCategory.Error, "Specifier_of_dynamic_import_cannot_be_spread_element_1325", "Specifier of dynamic import cannot be spread element."),
        Dynamic_import_cannot_have_type_arguments: diag(1326, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_have_type_arguments_1326", "Dynamic import cannot have type arguments"),
        String_literal_with_double_quotes_expected: diag(1327, ts.DiagnosticCategory.Error, "String_literal_with_double_quotes_expected_1327", "String literal with double quotes expected."),
        Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal: diag(1328, ts.DiagnosticCategory.Error, "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328", "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal."),
        _0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0: diag(1329, ts.DiagnosticCategory.Error, "_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329", "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?"),
        A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly: diag(1330, ts.DiagnosticCategory.Error, "A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330", "A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'."),
        A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly: diag(1331, ts.DiagnosticCategory.Error, "A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly_1331", "A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'."),
        A_variable_whose_type_is_a_unique_symbol_type_must_be_const: diag(1332, ts.DiagnosticCategory.Error, "A_variable_whose_type_is_a_unique_symbol_type_must_be_const_1332", "A variable whose type is a 'unique symbol' type must be 'const'."),
        unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name: diag(1333, ts.DiagnosticCategory.Error, "unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name_1333", "'unique symbol' types may not be used on a variable declaration with a binding name."),
        unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement: diag(1334, ts.DiagnosticCategory.Error, "unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement_1334", "'unique symbol' types are only allowed on variables in a variable statement."),
        unique_symbol_types_are_not_allowed_here: diag(1335, ts.DiagnosticCategory.Error, "unique_symbol_types_are_not_allowed_here_1335", "'unique symbol' types are not allowed here."),
        An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead: diag(1336, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead_1336", "An index signature parameter type cannot be a type alias. Consider writing '[{0}: {1}]: {2}' instead."),
        An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead: diag(1337, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead_1337", "An index signature parameter type cannot be a union type. Consider using a mapped object type instead."),
        infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type: diag(1338, ts.DiagnosticCategory.Error, "infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type_1338", "'infer' declarations are only permitted in the 'extends' clause of a conditional type."),
        Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here: diag(1339, ts.DiagnosticCategory.Error, "Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here_1339", "Module '{0}' does not refer to a value, but is used as a value here."),
        Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0: diag(1340, ts.DiagnosticCategory.Error, "Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0_1340", "Module '{0}' does not refer to a type, but is used as a type here. Did you mean 'typeof import('{0}')'?"),
        Type_arguments_cannot_be_used_here: diag(1342, ts.DiagnosticCategory.Error, "Type_arguments_cannot_be_used_here_1342", "Type arguments cannot be used here."),
        The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_esnext_or_system: diag(1343, ts.DiagnosticCategory.Error, "The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_esnext_or_system_1343", "The 'import.meta' meta-property is only allowed when the '--module' option is 'esnext' or 'system'."),
        A_label_is_not_allowed_here: diag(1344, ts.DiagnosticCategory.Error, "A_label_is_not_allowed_here_1344", "'A label is not allowed here."),
        An_expression_of_type_void_cannot_be_tested_for_truthiness: diag(1345, ts.DiagnosticCategory.Error, "An_expression_of_type_void_cannot_be_tested_for_truthiness_1345", "An expression of type 'void' cannot be tested for truthiness"),
        This_parameter_is_not_allowed_with_use_strict_directive: diag(1346, ts.DiagnosticCategory.Error, "This_parameter_is_not_allowed_with_use_strict_directive_1346", "This parameter is not allowed with 'use strict' directive."),
        use_strict_directive_cannot_be_used_with_non_simple_parameter_list: diag(1347, ts.DiagnosticCategory.Error, "use_strict_directive_cannot_be_used_with_non_simple_parameter_list_1347", "'use strict' directive cannot be used with non-simple parameter list."),
        Non_simple_parameter_declared_here: diag(1348, ts.DiagnosticCategory.Error, "Non_simple_parameter_declared_here_1348", "Non-simple parameter declared here."),
        use_strict_directive_used_here: diag(1349, ts.DiagnosticCategory.Error, "use_strict_directive_used_here_1349", "'use strict' directive used here."),
        Print_the_final_configuration_instead_of_building: diag(1350, ts.DiagnosticCategory.Message, "Print_the_final_configuration_instead_of_building_1350", "Print the final configuration instead of building."),
        An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal: diag(1351, ts.DiagnosticCategory.Error, "An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal_1351", "An identifier or keyword cannot immediately follow a numeric literal."),
        A_bigint_literal_cannot_use_exponential_notation: diag(1352, ts.DiagnosticCategory.Error, "A_bigint_literal_cannot_use_exponential_notation_1352", "A bigint literal cannot use exponential notation."),
        A_bigint_literal_must_be_an_integer: diag(1353, ts.DiagnosticCategory.Error, "A_bigint_literal_must_be_an_integer_1353", "A bigint literal must be an integer."),
        readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types: diag(1354, ts.DiagnosticCategory.Error, "readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types_1354", "'readonly' type modifier is only permitted on array and tuple literal types."),
        A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals: diag(1355, ts.DiagnosticCategory.Error, "A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array__1355", "A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals."),
        Did_you_mean_to_mark_this_function_as_async: diag(1356, ts.DiagnosticCategory.Error, "Did_you_mean_to_mark_this_function_as_async_1356", "Did you mean to mark this function as 'async'?"),
        An_enum_member_name_must_be_followed_by_a_or: diag(1357, ts.DiagnosticCategory.Error, "An_enum_member_name_must_be_followed_by_a_or_1357", "An enum member name must be followed by a ',', '=', or '}'."),
        Tagged_template_expressions_are_not_permitted_in_an_optional_chain: diag(1358, ts.DiagnosticCategory.Error, "Tagged_template_expressions_are_not_permitted_in_an_optional_chain_1358", "Tagged template expressions are not permitted in an optional chain."),
        Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here: diag(1359, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here_1359", "Identifier expected. '{0}' is a reserved word that cannot be used here."),
        Did_you_mean_to_parenthesize_this_function_type: diag(1360, ts.DiagnosticCategory.Error, "Did_you_mean_to_parenthesize_this_function_type_1360", "Did you mean to parenthesize this function type?"),
        _0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type: diag(1361, ts.DiagnosticCategory.Error, "_0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type_1361", "'{0}' cannot be used as a value because it was imported using 'import type'."),
        _0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type: diag(1362, ts.DiagnosticCategory.Error, "_0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type_1362", "'{0}' cannot be used as a value because it was exported using 'export type'."),
        A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both: diag(1363, ts.DiagnosticCategory.Error, "A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both_1363", "A type-only import can specify a default import or named bindings, but not both."),
        Convert_to_type_only_export: diag(1364, ts.DiagnosticCategory.Message, "Convert_to_type_only_export_1364", "Convert to type-only export"),
        Convert_all_re_exported_types_to_type_only_exports: diag(1365, ts.DiagnosticCategory.Message, "Convert_all_re_exported_types_to_type_only_exports_1365", "Convert all re-exported types to type-only exports"),
        Split_into_two_separate_import_declarations: diag(1366, ts.DiagnosticCategory.Message, "Split_into_two_separate_import_declarations_1366", "Split into two separate import declarations"),
        Split_all_invalid_type_only_imports: diag(1367, ts.DiagnosticCategory.Message, "Split_all_invalid_type_only_imports_1367", "Split all invalid type-only imports"),
        Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types: diag(1368, ts.DiagnosticCategory.Message, "Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types_1368", "Specify emit/checking behavior for imports that are only used for types"),
        Did_you_mean_0: diag(1369, ts.DiagnosticCategory.Message, "Did_you_mean_0_1369", "Did you mean '{0}'?"),
        Only_ECMAScript_imports_may_use_import_type: diag(1370, ts.DiagnosticCategory.Error, "Only_ECMAScript_imports_may_use_import_type_1370", "Only ECMAScript imports may use 'import type'."),
        This_import_is_never_used_as_a_value_and_must_use_import_type_because_the_importsNotUsedAsValues_is_set_to_error: diag(1371, ts.DiagnosticCategory.Error, "This_import_is_never_used_as_a_value_and_must_use_import_type_because_the_importsNotUsedAsValues_is__1371", "This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'."),
        Convert_to_type_only_import: diag(1373, ts.DiagnosticCategory.Message, "Convert_to_type_only_import_1373", "Convert to type-only import"),
        Convert_all_imports_not_used_as_a_value_to_type_only_imports: diag(1374, ts.DiagnosticCategory.Message, "Convert_all_imports_not_used_as_a_value_to_type_only_imports_1374", "Convert all imports not used as a value to type-only imports"),
        await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module: diag(1375, ts.DiagnosticCategory.Error, "await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_fi_1375", "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module."),
        _0_was_imported_here: diag(1376, ts.DiagnosticCategory.Message, "_0_was_imported_here_1376", "'{0}' was imported here."),
        _0_was_exported_here: diag(1377, ts.DiagnosticCategory.Message, "_0_was_exported_here_1377", "'{0}' was exported here."),
        Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher: diag(1378, ts.DiagnosticCategory.Error, "Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_t_1378", "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher."),
        An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type: diag(1379, ts.DiagnosticCategory.Error, "An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type_1379", "An import alias cannot reference a declaration that was exported using 'export type'."),
        An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type: diag(1380, ts.DiagnosticCategory.Error, "An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type_1380", "An import alias cannot reference a declaration that was imported using 'import type'."),
        Unexpected_token_Did_you_mean_or_rbrace: diag(1381, ts.DiagnosticCategory.Error, "Unexpected_token_Did_you_mean_or_rbrace_1381", "Unexpected token. Did you mean `{'}'}` or `&rbrace;`?"),
        Unexpected_token_Did_you_mean_or_gt: diag(1382, ts.DiagnosticCategory.Error, "Unexpected_token_Did_you_mean_or_gt_1382", "Unexpected token. Did you mean `{'>'}` or `&gt;`?"),
        Only_named_exports_may_use_export_type: diag(1383, ts.DiagnosticCategory.Error, "Only_named_exports_may_use_export_type_1383", "Only named exports may use 'export type'."),
        A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list: diag(1384, ts.DiagnosticCategory.Error, "A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list_1384", "A 'new' expression with type arguments must always be followed by a parenthesized argument list."),
        The_types_of_0_are_incompatible_between_these_types: diag(2200, ts.DiagnosticCategory.Error, "The_types_of_0_are_incompatible_between_these_types_2200", "The types of '{0}' are incompatible between these types."),
        The_types_returned_by_0_are_incompatible_between_these_types: diag(2201, ts.DiagnosticCategory.Error, "The_types_returned_by_0_are_incompatible_between_these_types_2201", "The types returned by '{0}' are incompatible between these types."),
        Call_signature_return_types_0_and_1_are_incompatible: diag(2202, ts.DiagnosticCategory.Error, "Call_signature_return_types_0_and_1_are_incompatible_2202", "Call signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true),
        Construct_signature_return_types_0_and_1_are_incompatible: diag(2203, ts.DiagnosticCategory.Error, "Construct_signature_return_types_0_and_1_are_incompatible_2203", "Construct signature return types '{0}' and '{1}' are incompatible.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true),
        Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1: diag(2204, ts.DiagnosticCategory.Error, "Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1_2204", "Call signatures with no arguments have incompatible return types '{0}' and '{1}'.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true),
        Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1: diag(2205, ts.DiagnosticCategory.Error, "Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1_2205", "Construct signatures with no arguments have incompatible return types '{0}' and '{1}'.", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ true),
        Duplicate_identifier_0: diag(2300, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_2300", "Duplicate identifier '{0}'."),
        Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: diag(2301, ts.DiagnosticCategory.Error, "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301", "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor."),
        Static_members_cannot_reference_class_type_parameters: diag(2302, ts.DiagnosticCategory.Error, "Static_members_cannot_reference_class_type_parameters_2302", "Static members cannot reference class type parameters."),
        Circular_definition_of_import_alias_0: diag(2303, ts.DiagnosticCategory.Error, "Circular_definition_of_import_alias_0_2303", "Circular definition of import alias '{0}'."),
        Cannot_find_name_0: diag(2304, ts.DiagnosticCategory.Error, "Cannot_find_name_0_2304", "Cannot find name '{0}'."),
        Module_0_has_no_exported_member_1: diag(2305, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_2305", "Module '{0}' has no exported member '{1}'."),
        File_0_is_not_a_module: diag(2306, ts.DiagnosticCategory.Error, "File_0_is_not_a_module_2306", "File '{0}' is not a module."),
        Cannot_find_module_0_or_its_corresponding_type_declarations: diag(2307, ts.DiagnosticCategory.Error, "Cannot_find_module_0_or_its_corresponding_type_declarations_2307", "Cannot find module '{0}' or its corresponding type declarations."),
        Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity: diag(2308, ts.DiagnosticCategory.Error, "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308", "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity."),
        An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: diag(2309, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309", "An export assignment cannot be used in a module with other exported elements."),
        Type_0_recursively_references_itself_as_a_base_type: diag(2310, ts.DiagnosticCategory.Error, "Type_0_recursively_references_itself_as_a_base_type_2310", "Type '{0}' recursively references itself as a base type."),
        A_class_may_only_extend_another_class: diag(2311, ts.DiagnosticCategory.Error, "A_class_may_only_extend_another_class_2311", "A class may only extend another class."),
        An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2312, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_me_2312", "An interface can only extend an object type or intersection of object types with statically known members."),
        Type_parameter_0_has_a_circular_constraint: diag(2313, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_constraint_2313", "Type parameter '{0}' has a circular constraint."),
        Generic_type_0_requires_1_type_argument_s: diag(2314, ts.DiagnosticCategory.Error, "Generic_type_0_requires_1_type_argument_s_2314", "Generic type '{0}' requires {1} type argument(s)."),
        Type_0_is_not_generic: diag(2315, ts.DiagnosticCategory.Error, "Type_0_is_not_generic_2315", "Type '{0}' is not generic."),
        Global_type_0_must_be_a_class_or_interface_type: diag(2316, ts.DiagnosticCategory.Error, "Global_type_0_must_be_a_class_or_interface_type_2316", "Global type '{0}' must be a class or interface type."),
        Global_type_0_must_have_1_type_parameter_s: diag(2317, ts.DiagnosticCategory.Error, "Global_type_0_must_have_1_type_parameter_s_2317", "Global type '{0}' must have {1} type parameter(s)."),
        Cannot_find_global_type_0: diag(2318, ts.DiagnosticCategory.Error, "Cannot_find_global_type_0_2318", "Cannot find global type '{0}'."),
        Named_property_0_of_types_1_and_2_are_not_identical: diag(2319, ts.DiagnosticCategory.Error, "Named_property_0_of_types_1_and_2_are_not_identical_2319", "Named property '{0}' of types '{1}' and '{2}' are not identical."),
        Interface_0_cannot_simultaneously_extend_types_1_and_2: diag(2320, ts.DiagnosticCategory.Error, "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320", "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'."),
        Excessive_stack_depth_comparing_types_0_and_1: diag(2321, ts.DiagnosticCategory.Error, "Excessive_stack_depth_comparing_types_0_and_1_2321", "Excessive stack depth comparing types '{0}' and '{1}'."),
        Type_0_is_not_assignable_to_type_1: diag(2322, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_2322", "Type '{0}' is not assignable to type '{1}'."),
        Cannot_redeclare_exported_variable_0: diag(2323, ts.DiagnosticCategory.Error, "Cannot_redeclare_exported_variable_0_2323", "Cannot redeclare exported variable '{0}'."),
        Property_0_is_missing_in_type_1: diag(2324, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_2324", "Property '{0}' is missing in type '{1}'."),
        Property_0_is_private_in_type_1_but_not_in_type_2: diag(2325, ts.DiagnosticCategory.Error, "Property_0_is_private_in_type_1_but_not_in_type_2_2325", "Property '{0}' is private in type '{1}' but not in type '{2}'."),
        Types_of_property_0_are_incompatible: diag(2326, ts.DiagnosticCategory.Error, "Types_of_property_0_are_incompatible_2326", "Types of property '{0}' are incompatible."),
        Property_0_is_optional_in_type_1_but_required_in_type_2: diag(2327, ts.DiagnosticCategory.Error, "Property_0_is_optional_in_type_1_but_required_in_type_2_2327", "Property '{0}' is optional in type '{1}' but required in type '{2}'."),
        Types_of_parameters_0_and_1_are_incompatible: diag(2328, ts.DiagnosticCategory.Error, "Types_of_parameters_0_and_1_are_incompatible_2328", "Types of parameters '{0}' and '{1}' are incompatible."),
        Index_signature_is_missing_in_type_0: diag(2329, ts.DiagnosticCategory.Error, "Index_signature_is_missing_in_type_0_2329", "Index signature is missing in type '{0}'."),
        Index_signatures_are_incompatible: diag(2330, ts.DiagnosticCategory.Error, "Index_signatures_are_incompatible_2330", "Index signatures are incompatible."),
        this_cannot_be_referenced_in_a_module_or_namespace_body: diag(2331, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_module_or_namespace_body_2331", "'this' cannot be referenced in a module or namespace body."),
        this_cannot_be_referenced_in_current_location: diag(2332, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_current_location_2332", "'this' cannot be referenced in current location."),
        this_cannot_be_referenced_in_constructor_arguments: diag(2333, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_constructor_arguments_2333", "'this' cannot be referenced in constructor arguments."),
        this_cannot_be_referenced_in_a_static_property_initializer: diag(2334, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_static_property_initializer_2334", "'this' cannot be referenced in a static property initializer."),
        super_can_only_be_referenced_in_a_derived_class: diag(2335, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_a_derived_class_2335", "'super' can only be referenced in a derived class."),
        super_cannot_be_referenced_in_constructor_arguments: diag(2336, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_constructor_arguments_2336", "'super' cannot be referenced in constructor arguments."),
        Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: diag(2337, ts.DiagnosticCategory.Error, "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337", "Super calls are not permitted outside constructors or in nested functions inside constructors."),
        super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: diag(2338, ts.DiagnosticCategory.Error, "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338", "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class."),
        Property_0_does_not_exist_on_type_1: diag(2339, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_2339", "Property '{0}' does not exist on type '{1}'."),
        Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: diag(2340, ts.DiagnosticCategory.Error, "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340", "Only public and protected methods of the base class are accessible via the 'super' keyword."),
        Property_0_is_private_and_only_accessible_within_class_1: diag(2341, ts.DiagnosticCategory.Error, "Property_0_is_private_and_only_accessible_within_class_1_2341", "Property '{0}' is private and only accessible within class '{1}'."),
        An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: diag(2342, ts.DiagnosticCategory.Error, "An_index_expression_argument_must_be_of_type_string_number_symbol_or_any_2342", "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'."),
        This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0: diag(2343, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_ve_2343", "This syntax requires an imported helper named '{1}' which does not exist in '{0}'. Consider upgrading your version of '{0}'."),
        Type_0_does_not_satisfy_the_constraint_1: diag(2344, ts.DiagnosticCategory.Error, "Type_0_does_not_satisfy_the_constraint_1_2344", "Type '{0}' does not satisfy the constraint '{1}'."),
        Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: diag(2345, ts.DiagnosticCategory.Error, "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345", "Argument of type '{0}' is not assignable to parameter of type '{1}'."),
        Call_target_does_not_contain_any_signatures: diag(2346, ts.DiagnosticCategory.Error, "Call_target_does_not_contain_any_signatures_2346", "Call target does not contain any signatures."),
        Untyped_function_calls_may_not_accept_type_arguments: diag(2347, ts.DiagnosticCategory.Error, "Untyped_function_calls_may_not_accept_type_arguments_2347", "Untyped function calls may not accept type arguments."),
        Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: diag(2348, ts.DiagnosticCategory.Error, "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348", "Value of type '{0}' is not callable. Did you mean to include 'new'?"),
        This_expression_is_not_callable: diag(2349, ts.DiagnosticCategory.Error, "This_expression_is_not_callable_2349", "This expression is not callable."),
        Only_a_void_function_can_be_called_with_the_new_keyword: diag(2350, ts.DiagnosticCategory.Error, "Only_a_void_function_can_be_called_with_the_new_keyword_2350", "Only a void function can be called with the 'new' keyword."),
        This_expression_is_not_constructable: diag(2351, ts.DiagnosticCategory.Error, "This_expression_is_not_constructable_2351", "This expression is not constructable."),
        Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first: diag(2352, ts.DiagnosticCategory.Error, "Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the__2352", "Conversion of type '{0}' to type '{1}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first."),
        Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1: diag(2353, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353", "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'."),
        This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found: diag(2354, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354", "This syntax requires an imported helper but module '{0}' cannot be found."),
        A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value: diag(2355, ts.DiagnosticCategory.Error, "A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_2355", "A function whose declared type is neither 'void' nor 'any' must return a value."),
        An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2356, ts.DiagnosticCategory.Error, "An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type_2356", "An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type."),
        The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access: diag(2357, ts.DiagnosticCategory.Error, "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access_2357", "The operand of an increment or decrement operator must be a variable or a property access."),
        The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2358, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358", "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter."),
        The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: diag(2359, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_F_2359", "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type."),
        The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol: diag(2360, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol_2360", "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'."),
        The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2361, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter_2361", "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter."),
        The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2362, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2362", "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type."),
        The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type: diag(2363, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type_2363", "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type."),
        The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access: diag(2364, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access_2364", "The left-hand side of an assignment expression must be a variable or a property access."),
        Operator_0_cannot_be_applied_to_types_1_and_2: diag(2365, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_types_1_and_2_2365", "Operator '{0}' cannot be applied to types '{1}' and '{2}'."),
        Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined: diag(2366, ts.DiagnosticCategory.Error, "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366", "Function lacks ending return statement and return type does not include 'undefined'."),
        This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap: diag(2367, ts.DiagnosticCategory.Error, "This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap_2367", "This condition will always return '{0}' since the types '{1}' and '{2}' have no overlap."),
        Type_parameter_name_cannot_be_0: diag(2368, ts.DiagnosticCategory.Error, "Type_parameter_name_cannot_be_0_2368", "Type parameter name cannot be '{0}'."),
        A_parameter_property_is_only_allowed_in_a_constructor_implementation: diag(2369, ts.DiagnosticCategory.Error, "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369", "A parameter property is only allowed in a constructor implementation."),
        A_rest_parameter_must_be_of_an_array_type: diag(2370, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_of_an_array_type_2370", "A rest parameter must be of an array type."),
        A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: diag(2371, ts.DiagnosticCategory.Error, "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371", "A parameter initializer is only allowed in a function or constructor implementation."),
        Parameter_0_cannot_reference_itself: diag(2372, ts.DiagnosticCategory.Error, "Parameter_0_cannot_reference_itself_2372", "Parameter '{0}' cannot reference itself."),
        Parameter_0_cannot_reference_identifier_1_declared_after_it: diag(2373, ts.DiagnosticCategory.Error, "Parameter_0_cannot_reference_identifier_1_declared_after_it_2373", "Parameter '{0}' cannot reference identifier '{1}' declared after it."),
        Duplicate_string_index_signature: diag(2374, ts.DiagnosticCategory.Error, "Duplicate_string_index_signature_2374", "Duplicate string index signature."),
        Duplicate_number_index_signature: diag(2375, ts.DiagnosticCategory.Error, "Duplicate_number_index_signature_2375", "Duplicate number index signature."),
        A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_parameter_properties_or_private_identifiers: diag(2376, ts.DiagnosticCategory.Error, "A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_proper_2376", "A 'super' call must be the first statement in the constructor when a class contains initialized properties, parameter properties, or private identifiers."),
        Constructors_for_derived_classes_must_contain_a_super_call: diag(2377, ts.DiagnosticCategory.Error, "Constructors_for_derived_classes_must_contain_a_super_call_2377", "Constructors for derived classes must contain a 'super' call."),
        A_get_accessor_must_return_a_value: diag(2378, ts.DiagnosticCategory.Error, "A_get_accessor_must_return_a_value_2378", "A 'get' accessor must return a value."),
        Getter_and_setter_accessors_do_not_agree_in_visibility: diag(2379, ts.DiagnosticCategory.Error, "Getter_and_setter_accessors_do_not_agree_in_visibility_2379", "Getter and setter accessors do not agree in visibility."),
        get_and_set_accessor_must_have_the_same_type: diag(2380, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_type_2380", "'get' and 'set' accessor must have the same type."),
        A_signature_with_an_implementation_cannot_use_a_string_literal_type: diag(2381, ts.DiagnosticCategory.Error, "A_signature_with_an_implementation_cannot_use_a_string_literal_type_2381", "A signature with an implementation cannot use a string literal type."),
        Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: diag(2382, ts.DiagnosticCategory.Error, "Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382", "Specialized overload signature is not assignable to any non-specialized signature."),
        Overload_signatures_must_all_be_exported_or_non_exported: diag(2383, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_exported_or_non_exported_2383", "Overload signatures must all be exported or non-exported."),
        Overload_signatures_must_all_be_ambient_or_non_ambient: diag(2384, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_ambient_or_non_ambient_2384", "Overload signatures must all be ambient or non-ambient."),
        Overload_signatures_must_all_be_public_private_or_protected: diag(2385, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_public_private_or_protected_2385", "Overload signatures must all be public, private or protected."),
        Overload_signatures_must_all_be_optional_or_required: diag(2386, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_optional_or_required_2386", "Overload signatures must all be optional or required."),
        Function_overload_must_be_static: diag(2387, ts.DiagnosticCategory.Error, "Function_overload_must_be_static_2387", "Function overload must be static."),
        Function_overload_must_not_be_static: diag(2388, ts.DiagnosticCategory.Error, "Function_overload_must_not_be_static_2388", "Function overload must not be static."),
        Function_implementation_name_must_be_0: diag(2389, ts.DiagnosticCategory.Error, "Function_implementation_name_must_be_0_2389", "Function implementation name must be '{0}'."),
        Constructor_implementation_is_missing: diag(2390, ts.DiagnosticCategory.Error, "Constructor_implementation_is_missing_2390", "Constructor implementation is missing."),
        Function_implementation_is_missing_or_not_immediately_following_the_declaration: diag(2391, ts.DiagnosticCategory.Error, "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391", "Function implementation is missing or not immediately following the declaration."),
        Multiple_constructor_implementations_are_not_allowed: diag(2392, ts.DiagnosticCategory.Error, "Multiple_constructor_implementations_are_not_allowed_2392", "Multiple constructor implementations are not allowed."),
        Duplicate_function_implementation: diag(2393, ts.DiagnosticCategory.Error, "Duplicate_function_implementation_2393", "Duplicate function implementation."),
        This_overload_signature_is_not_compatible_with_its_implementation_signature: diag(2394, ts.DiagnosticCategory.Error, "This_overload_signature_is_not_compatible_with_its_implementation_signature_2394", "This overload signature is not compatible with its implementation signature."),
        Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: diag(2395, ts.DiagnosticCategory.Error, "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395", "Individual declarations in merged declaration '{0}' must be all exported or all local."),
        Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: diag(2396, ts.DiagnosticCategory.Error, "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396", "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters."),
        Declaration_name_conflicts_with_built_in_global_identifier_0: diag(2397, ts.DiagnosticCategory.Error, "Declaration_name_conflicts_with_built_in_global_identifier_0_2397", "Declaration name conflicts with built-in global identifier '{0}'."),
        constructor_cannot_be_used_as_a_parameter_property_name: diag(2398, ts.DiagnosticCategory.Error, "constructor_cannot_be_used_as_a_parameter_property_name_2398", "'constructor' cannot be used as a parameter property name."),
        Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: diag(2399, ts.DiagnosticCategory.Error, "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399", "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference."),
        Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: diag(2400, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400", "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference."),
        Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: diag(2401, ts.DiagnosticCategory.Error, "Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference_2401", "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference."),
        Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: diag(2402, ts.DiagnosticCategory.Error, "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402", "Expression resolves to '_super' that compiler uses to capture base class reference."),
        Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: diag(2403, ts.DiagnosticCategory.Error, "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403", "Subsequent variable declarations must have the same type.  Variable '{0}' must be of type '{1}', but here has type '{2}'."),
        The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation: diag(2404, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404", "The left-hand side of a 'for...in' statement cannot use a type annotation."),
        The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any: diag(2405, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405", "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."),
        The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access: diag(2406, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access_2406", "The left-hand side of a 'for...in' statement must be a variable or a property access."),
        The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0: diag(2407, ts.DiagnosticCategory.Error, "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_2407", "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type '{0}'."),
        Setters_cannot_return_a_value: diag(2408, ts.DiagnosticCategory.Error, "Setters_cannot_return_a_value_2408", "Setters cannot return a value."),
        Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: diag(2409, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409", "Return type of constructor signature must be assignable to the instance type of the class."),
        The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any: diag(2410, ts.DiagnosticCategory.Error, "The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410", "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'."),
        Property_0_of_type_1_is_not_assignable_to_string_index_type_2: diag(2411, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411", "Property '{0}' of type '{1}' is not assignable to string index type '{2}'."),
        Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: diag(2412, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412", "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'."),
        Numeric_index_type_0_is_not_assignable_to_string_index_type_1: diag(2413, ts.DiagnosticCategory.Error, "Numeric_index_type_0_is_not_assignable_to_string_index_type_1_2413", "Numeric index type '{0}' is not assignable to string index type '{1}'."),
        Class_name_cannot_be_0: diag(2414, ts.DiagnosticCategory.Error, "Class_name_cannot_be_0_2414", "Class name cannot be '{0}'."),
        Class_0_incorrectly_extends_base_class_1: diag(2415, ts.DiagnosticCategory.Error, "Class_0_incorrectly_extends_base_class_1_2415", "Class '{0}' incorrectly extends base class '{1}'."),
        Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2: diag(2416, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2_2416", "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'."),
        Class_static_side_0_incorrectly_extends_base_class_static_side_1: diag(2417, ts.DiagnosticCategory.Error, "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417", "Class static side '{0}' incorrectly extends base class static side '{1}'."),
        Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1: diag(2418, ts.DiagnosticCategory.Error, "Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1_2418", "Type of computed property's value is '{0}', which is not assignable to type '{1}'."),
        Class_0_incorrectly_implements_interface_1: diag(2420, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_interface_1_2420", "Class '{0}' incorrectly implements interface '{1}'."),
        A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2422, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_memb_2422", "A class can only implement an object type or intersection of object types with statically known members."),
        Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: diag(2423, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor."),
        Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2425, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425", "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function."),
        Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2426, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426", "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function."),
        Interface_name_cannot_be_0: diag(2427, ts.DiagnosticCategory.Error, "Interface_name_cannot_be_0_2427", "Interface name cannot be '{0}'."),
        All_declarations_of_0_must_have_identical_type_parameters: diag(2428, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_type_parameters_2428", "All declarations of '{0}' must have identical type parameters."),
        Interface_0_incorrectly_extends_interface_1: diag(2430, ts.DiagnosticCategory.Error, "Interface_0_incorrectly_extends_interface_1_2430", "Interface '{0}' incorrectly extends interface '{1}'."),
        Enum_name_cannot_be_0: diag(2431, ts.DiagnosticCategory.Error, "Enum_name_cannot_be_0_2431", "Enum name cannot be '{0}'."),
        In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: diag(2432, ts.DiagnosticCategory.Error, "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432", "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element."),
        A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged: diag(2433, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433", "A namespace declaration cannot be in a different file from a class or function with which it is merged."),
        A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged: diag(2434, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434", "A namespace declaration cannot be located prior to a class or function with which it is merged."),
        Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces: diag(2435, ts.DiagnosticCategory.Error, "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435", "Ambient modules cannot be nested in other modules or namespaces."),
        Ambient_module_declaration_cannot_specify_relative_module_name: diag(2436, ts.DiagnosticCategory.Error, "Ambient_module_declaration_cannot_specify_relative_module_name_2436", "Ambient module declaration cannot specify relative module name."),
        Module_0_is_hidden_by_a_local_declaration_with_the_same_name: diag(2437, ts.DiagnosticCategory.Error, "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437", "Module '{0}' is hidden by a local declaration with the same name."),
        Import_name_cannot_be_0: diag(2438, ts.DiagnosticCategory.Error, "Import_name_cannot_be_0_2438", "Import name cannot be '{0}'."),
        Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name: diag(2439, ts.DiagnosticCategory.Error, "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439", "Import or export declaration in an ambient module declaration cannot reference module through relative module name."),
        Import_declaration_conflicts_with_local_declaration_of_0: diag(2440, ts.DiagnosticCategory.Error, "Import_declaration_conflicts_with_local_declaration_of_0_2440", "Import declaration conflicts with local declaration of '{0}'."),
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module: diag(2441, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module."),
        Types_have_separate_declarations_of_a_private_property_0: diag(2442, ts.DiagnosticCategory.Error, "Types_have_separate_declarations_of_a_private_property_0_2442", "Types have separate declarations of a private property '{0}'."),
        Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: diag(2443, ts.DiagnosticCategory.Error, "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443", "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'."),
        Property_0_is_protected_in_type_1_but_public_in_type_2: diag(2444, ts.DiagnosticCategory.Error, "Property_0_is_protected_in_type_1_but_public_in_type_2_2444", "Property '{0}' is protected in type '{1}' but public in type '{2}'."),
        Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: diag(2445, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445", "Property '{0}' is protected and only accessible within class '{1}' and its subclasses."),
        Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: diag(2446, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_2446", "Property '{0}' is protected and only accessible through an instance of class '{1}'."),
        The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: diag(2447, ts.DiagnosticCategory.Error, "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447", "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead."),
        Block_scoped_variable_0_used_before_its_declaration: diag(2448, ts.DiagnosticCategory.Error, "Block_scoped_variable_0_used_before_its_declaration_2448", "Block-scoped variable '{0}' used before its declaration."),
        Class_0_used_before_its_declaration: diag(2449, ts.DiagnosticCategory.Error, "Class_0_used_before_its_declaration_2449", "Class '{0}' used before its declaration."),
        Enum_0_used_before_its_declaration: diag(2450, ts.DiagnosticCategory.Error, "Enum_0_used_before_its_declaration_2450", "Enum '{0}' used before its declaration."),
        Cannot_redeclare_block_scoped_variable_0: diag(2451, ts.DiagnosticCategory.Error, "Cannot_redeclare_block_scoped_variable_0_2451", "Cannot redeclare block-scoped variable '{0}'."),
        An_enum_member_cannot_have_a_numeric_name: diag(2452, ts.DiagnosticCategory.Error, "An_enum_member_cannot_have_a_numeric_name_2452", "An enum member cannot have a numeric name."),
        The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly: diag(2453, ts.DiagnosticCategory.Error, "The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_typ_2453", "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly."),
        Variable_0_is_used_before_being_assigned: diag(2454, ts.DiagnosticCategory.Error, "Variable_0_is_used_before_being_assigned_2454", "Variable '{0}' is used before being assigned."),
        Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: diag(2455, ts.DiagnosticCategory.Error, "Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0_2455", "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'."),
        Type_alias_0_circularly_references_itself: diag(2456, ts.DiagnosticCategory.Error, "Type_alias_0_circularly_references_itself_2456", "Type alias '{0}' circularly references itself."),
        Type_alias_name_cannot_be_0: diag(2457, ts.DiagnosticCategory.Error, "Type_alias_name_cannot_be_0_2457", "Type alias name cannot be '{0}'."),
        An_AMD_module_cannot_have_multiple_name_assignments: diag(2458, ts.DiagnosticCategory.Error, "An_AMD_module_cannot_have_multiple_name_assignments_2458", "An AMD module cannot have multiple name assignments."),
        Module_0_declares_1_locally_but_it_is_not_exported: diag(2459, ts.DiagnosticCategory.Error, "Module_0_declares_1_locally_but_it_is_not_exported_2459", "Module '{0}' declares '{1}' locally, but it is not exported."),
        Module_0_declares_1_locally_but_it_is_exported_as_2: diag(2460, ts.DiagnosticCategory.Error, "Module_0_declares_1_locally_but_it_is_exported_as_2_2460", "Module '{0}' declares '{1}' locally, but it is exported as '{2}'."),
        Type_0_is_not_an_array_type: diag(2461, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_2461", "Type '{0}' is not an array type."),
        A_rest_element_must_be_last_in_a_destructuring_pattern: diag(2462, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_destructuring_pattern_2462", "A rest element must be last in a destructuring pattern."),
        A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: diag(2463, ts.DiagnosticCategory.Error, "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463", "A binding pattern parameter cannot be optional in an implementation signature."),
        A_computed_property_name_must_be_of_type_string_number_symbol_or_any: diag(2464, ts.DiagnosticCategory.Error, "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464", "A computed property name must be of type 'string', 'number', 'symbol', or 'any'."),
        this_cannot_be_referenced_in_a_computed_property_name: diag(2465, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_computed_property_name_2465", "'this' cannot be referenced in a computed property name."),
        super_cannot_be_referenced_in_a_computed_property_name: diag(2466, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_a_computed_property_name_2466", "'super' cannot be referenced in a computed property name."),
        A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: diag(2467, ts.DiagnosticCategory.Error, "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467", "A computed property name cannot reference a type parameter from its containing type."),
        Cannot_find_global_value_0: diag(2468, ts.DiagnosticCategory.Error, "Cannot_find_global_value_0_2468", "Cannot find global value '{0}'."),
        The_0_operator_cannot_be_applied_to_type_symbol: diag(2469, ts.DiagnosticCategory.Error, "The_0_operator_cannot_be_applied_to_type_symbol_2469", "The '{0}' operator cannot be applied to type 'symbol'."),
        Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: diag(2470, ts.DiagnosticCategory.Error, "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470", "'Symbol' reference does not refer to the global Symbol constructor object."),
        A_computed_property_name_of_the_form_0_must_be_of_type_symbol: diag(2471, ts.DiagnosticCategory.Error, "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471", "A computed property name of the form '{0}' must be of type 'symbol'."),
        Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: diag(2472, ts.DiagnosticCategory.Error, "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472", "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher."),
        Enum_declarations_must_all_be_const_or_non_const: diag(2473, ts.DiagnosticCategory.Error, "Enum_declarations_must_all_be_const_or_non_const_2473", "Enum declarations must all be const or non-const."),
        const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values: diag(2474, ts.DiagnosticCategory.Error, "const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values_2474", "const enum member initializers can only contain literal values and other computed enum values."),
        const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query: diag(2475, ts.DiagnosticCategory.Error, "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475", "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query."),
        A_const_enum_member_can_only_be_accessed_using_a_string_literal: diag(2476, ts.DiagnosticCategory.Error, "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", "A const enum member can only be accessed using a string literal."),
        const_enum_member_initializer_was_evaluated_to_a_non_finite_value: diag(2477, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", "'const' enum member initializer was evaluated to a non-finite value."),
        const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: diag(2478, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", "'const' enum member initializer was evaluated to disallowed value 'NaN'."),
        Property_0_does_not_exist_on_const_enum_1: diag(2479, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_const_enum_1_2479", "Property '{0}' does not exist on 'const' enum '{1}'."),
        let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: diag(2480, ts.DiagnosticCategory.Error, "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", "'let' is not allowed to be used as a name in 'let' or 'const' declarations."),
        Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: diag(2481, ts.DiagnosticCategory.Error, "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481", "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'."),
        The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: diag(2483, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", "The left-hand side of a 'for...of' statement cannot use a type annotation."),
        Export_declaration_conflicts_with_exported_declaration_of_0: diag(2484, ts.DiagnosticCategory.Error, "Export_declaration_conflicts_with_exported_declaration_of_0_2484", "Export declaration conflicts with exported declaration of '{0}'."),
        The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access: diag(2487, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access_2487", "The left-hand side of a 'for...of' statement must be a variable or a property access."),
        Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2488, ts.DiagnosticCategory.Error, "Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator."),
        An_iterator_must_have_a_next_method: diag(2489, ts.DiagnosticCategory.Error, "An_iterator_must_have_a_next_method_2489", "An iterator must have a 'next()' method."),
        The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property: diag(2490, ts.DiagnosticCategory.Error, "The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property_2490", "The type returned by the '{0}()' method of an iterator must have a 'value' property."),
        The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern: diag(2491, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491", "The left-hand side of a 'for...in' statement cannot be a destructuring pattern."),
        Cannot_redeclare_identifier_0_in_catch_clause: diag(2492, ts.DiagnosticCategory.Error, "Cannot_redeclare_identifier_0_in_catch_clause_2492", "Cannot redeclare identifier '{0}' in catch clause."),
        Tuple_type_0_of_length_1_has_no_element_at_index_2: diag(2493, ts.DiagnosticCategory.Error, "Tuple_type_0_of_length_1_has_no_element_at_index_2_2493", "Tuple type '{0}' of length '{1}' has no element at index '{2}'."),
        Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher: diag(2494, ts.DiagnosticCategory.Error, "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494", "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher."),
        Type_0_is_not_an_array_type_or_a_string_type: diag(2495, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_2495", "Type '{0}' is not an array type or a string type."),
        The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression: diag(2496, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_stand_2496", "The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. Consider using a standard function expression."),
        This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export: diag(2497, ts.DiagnosticCategory.Error, "This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_2497", "This module can only be referenced with ECMAScript imports/exports by turning on the '{0}' flag and referencing its default export."),
        Module_0_uses_export_and_cannot_be_used_with_export_Asterisk: diag(2498, ts.DiagnosticCategory.Error, "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498", "Module '{0}' uses 'export =' and cannot be used with 'export *'."),
        An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2499, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499", "An interface can only extend an identifier/qualified-name with optional type arguments."),
        A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2500, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500", "A class can only implement an identifier/qualified-name with optional type arguments."),
        A_rest_element_cannot_contain_a_binding_pattern: diag(2501, ts.DiagnosticCategory.Error, "A_rest_element_cannot_contain_a_binding_pattern_2501", "A rest element cannot contain a binding pattern."),
        _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: diag(2502, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502", "'{0}' is referenced directly or indirectly in its own type annotation."),
        Cannot_find_namespace_0: diag(2503, ts.DiagnosticCategory.Error, "Cannot_find_namespace_0_2503", "Cannot find namespace '{0}'."),
        Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator: diag(2504, ts.DiagnosticCategory.Error, "Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_2504", "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator."),
        A_generator_cannot_have_a_void_type_annotation: diag(2505, ts.DiagnosticCategory.Error, "A_generator_cannot_have_a_void_type_annotation_2505", "A generator cannot have a 'void' type annotation."),
        _0_is_referenced_directly_or_indirectly_in_its_own_base_expression: diag(2506, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506", "'{0}' is referenced directly or indirectly in its own base expression."),
        Type_0_is_not_a_constructor_function_type: diag(2507, ts.DiagnosticCategory.Error, "Type_0_is_not_a_constructor_function_type_2507", "Type '{0}' is not a constructor function type."),
        No_base_constructor_has_the_specified_number_of_type_arguments: diag(2508, ts.DiagnosticCategory.Error, "No_base_constructor_has_the_specified_number_of_type_arguments_2508", "No base constructor has the specified number of type arguments."),
        Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members: diag(2509, ts.DiagnosticCategory.Error, "Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_2509", "Base constructor return type '{0}' is not an object type or intersection of object types with statically known members."),
        Base_constructors_must_all_have_the_same_return_type: diag(2510, ts.DiagnosticCategory.Error, "Base_constructors_must_all_have_the_same_return_type_2510", "Base constructors must all have the same return type."),
        Cannot_create_an_instance_of_an_abstract_class: diag(2511, ts.DiagnosticCategory.Error, "Cannot_create_an_instance_of_an_abstract_class_2511", "Cannot create an instance of an abstract class."),
        Overload_signatures_must_all_be_abstract_or_non_abstract: diag(2512, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_abstract_or_non_abstract_2512", "Overload signatures must all be abstract or non-abstract."),
        Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: diag(2513, ts.DiagnosticCategory.Error, "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513", "Abstract method '{0}' in class '{1}' cannot be accessed via super expression."),
        Classes_containing_abstract_methods_must_be_marked_abstract: diag(2514, ts.DiagnosticCategory.Error, "Classes_containing_abstract_methods_must_be_marked_abstract_2514", "Classes containing abstract methods must be marked abstract."),
        Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: diag(2515, ts.DiagnosticCategory.Error, "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515", "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'."),
        All_declarations_of_an_abstract_method_must_be_consecutive: diag(2516, ts.DiagnosticCategory.Error, "All_declarations_of_an_abstract_method_must_be_consecutive_2516", "All declarations of an abstract method must be consecutive."),
        Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: diag(2517, ts.DiagnosticCategory.Error, "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517", "Cannot assign an abstract constructor type to a non-abstract constructor type."),
        A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard: diag(2518, ts.DiagnosticCategory.Error, "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518", "A 'this'-based type guard is not compatible with a parameter-based type guard."),
        An_async_iterator_must_have_a_next_method: diag(2519, ts.DiagnosticCategory.Error, "An_async_iterator_must_have_a_next_method_2519", "An async iterator must have a 'next()' method."),
        Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: diag(2520, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520", "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions."),
        Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: diag(2521, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521", "Expression resolves to variable declaration '{0}' that compiler uses to support async functions."),
        The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method: diag(2522, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_usi_2522", "The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method."),
        yield_expressions_cannot_be_used_in_a_parameter_initializer: diag(2523, ts.DiagnosticCategory.Error, "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523", "'yield' expressions cannot be used in a parameter initializer."),
        await_expressions_cannot_be_used_in_a_parameter_initializer: diag(2524, ts.DiagnosticCategory.Error, "await_expressions_cannot_be_used_in_a_parameter_initializer_2524", "'await' expressions cannot be used in a parameter initializer."),
        Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value: diag(2525, ts.DiagnosticCategory.Error, "Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value_2525", "Initializer provides no value for this binding element and the binding element has no default value."),
        A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface: diag(2526, ts.DiagnosticCategory.Error, "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526", "A 'this' type is available only in a non-static member of a class or interface."),
        The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary: diag(2527, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527", "The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary."),
        A_module_cannot_have_multiple_default_exports: diag(2528, ts.DiagnosticCategory.Error, "A_module_cannot_have_multiple_default_exports_2528", "A module cannot have multiple default exports."),
        Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions: diag(2529, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions."),
        Property_0_is_incompatible_with_index_signature: diag(2530, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_index_signature_2530", "Property '{0}' is incompatible with index signature."),
        Object_is_possibly_null: diag(2531, ts.DiagnosticCategory.Error, "Object_is_possibly_null_2531", "Object is possibly 'null'."),
        Object_is_possibly_undefined: diag(2532, ts.DiagnosticCategory.Error, "Object_is_possibly_undefined_2532", "Object is possibly 'undefined'."),
        Object_is_possibly_null_or_undefined: diag(2533, ts.DiagnosticCategory.Error, "Object_is_possibly_null_or_undefined_2533", "Object is possibly 'null' or 'undefined'."),
        A_function_returning_never_cannot_have_a_reachable_end_point: diag(2534, ts.DiagnosticCategory.Error, "A_function_returning_never_cannot_have_a_reachable_end_point_2534", "A function returning 'never' cannot have a reachable end point."),
        Enum_type_0_has_members_with_initializers_that_are_not_literals: diag(2535, ts.DiagnosticCategory.Error, "Enum_type_0_has_members_with_initializers_that_are_not_literals_2535", "Enum type '{0}' has members with initializers that are not literals."),
        Type_0_cannot_be_used_to_index_type_1: diag(2536, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_to_index_type_1_2536", "Type '{0}' cannot be used to index type '{1}'."),
        Type_0_has_no_matching_index_signature_for_type_1: diag(2537, ts.DiagnosticCategory.Error, "Type_0_has_no_matching_index_signature_for_type_1_2537", "Type '{0}' has no matching index signature for type '{1}'."),
        Type_0_cannot_be_used_as_an_index_type: diag(2538, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_as_an_index_type_2538", "Type '{0}' cannot be used as an index type."),
        Cannot_assign_to_0_because_it_is_not_a_variable: diag(2539, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_not_a_variable_2539", "Cannot assign to '{0}' because it is not a variable."),
        Cannot_assign_to_0_because_it_is_a_read_only_property: diag(2540, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_read_only_property_2540", "Cannot assign to '{0}' because it is a read-only property."),
        The_target_of_an_assignment_must_be_a_variable_or_a_property_access: diag(2541, ts.DiagnosticCategory.Error, "The_target_of_an_assignment_must_be_a_variable_or_a_property_access_2541", "The target of an assignment must be a variable or a property access."),
        Index_signature_in_type_0_only_permits_reading: diag(2542, ts.DiagnosticCategory.Error, "Index_signature_in_type_0_only_permits_reading_2542", "Index signature in type '{0}' only permits reading."),
        Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference: diag(2543, ts.DiagnosticCategory.Error, "Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_me_2543", "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference."),
        Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference: diag(2544, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544", "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference."),
        A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any: diag(2545, ts.DiagnosticCategory.Error, "A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any_2545", "A mixin class must have a constructor with a single rest parameter of type 'any[]'."),
        The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property: diag(2547, ts.DiagnosticCategory.Error, "The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_pro_2547", "The type returned by the '{0}()' method of an async iterator must be a promise for a type with a 'value' property."),
        Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2548, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_2548", "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
        Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2549, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549", "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator."),
        Property_0_does_not_exist_on_type_1_Did_you_mean_2: diag(2551, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_Did_you_mean_2_2551", "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?"),
        Cannot_find_name_0_Did_you_mean_1: diag(2552, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_1_2552", "Cannot find name '{0}'. Did you mean '{1}'?"),
        Computed_values_are_not_permitted_in_an_enum_with_string_valued_members: diag(2553, ts.DiagnosticCategory.Error, "Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553", "Computed values are not permitted in an enum with string valued members."),
        Expected_0_arguments_but_got_1: diag(2554, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_2554", "Expected {0} arguments, but got {1}."),
        Expected_at_least_0_arguments_but_got_1: diag(2555, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_2555", "Expected at least {0} arguments, but got {1}."),
        Expected_0_arguments_but_got_1_or_more: diag(2556, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_or_more_2556", "Expected {0} arguments, but got {1} or more."),
        Expected_at_least_0_arguments_but_got_1_or_more: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_or_more_2557", "Expected at least {0} arguments, but got {1} or more."),
        Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."),
        Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."),
        Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"),
        Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2: diag(2561, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_writ_2561", "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?"),
        Base_class_expressions_cannot_reference_class_type_parameters: diag(2562, ts.DiagnosticCategory.Error, "Base_class_expressions_cannot_reference_class_type_parameters_2562", "Base class expressions cannot reference class type parameters."),
        The_containing_function_or_module_body_is_too_large_for_control_flow_analysis: diag(2563, ts.DiagnosticCategory.Error, "The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563", "The containing function or module body is too large for control flow analysis."),
        Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor: diag(2564, ts.DiagnosticCategory.Error, "Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor_2564", "Property '{0}' has no initializer and is not definitely assigned in the constructor."),
        Property_0_is_used_before_being_assigned: diag(2565, ts.DiagnosticCategory.Error, "Property_0_is_used_before_being_assigned_2565", "Property '{0}' is used before being assigned."),
        A_rest_element_cannot_have_a_property_name: diag(2566, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_a_property_name_2566", "A rest element cannot have a property name."),
        Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations: diag(2567, ts.DiagnosticCategory.Error, "Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations_2567", "Enum declarations can only merge with namespace or other enum declarations."),
        Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators: diag(2569, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569", "Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators."),
        Object_is_of_type_unknown: diag(2571, ts.DiagnosticCategory.Error, "Object_is_of_type_unknown_2571", "Object is of type 'unknown'."),
        Rest_signatures_are_incompatible: diag(2572, ts.DiagnosticCategory.Error, "Rest_signatures_are_incompatible_2572", "Rest signatures are incompatible."),
        Property_0_is_incompatible_with_rest_element_type: diag(2573, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_rest_element_type_2573", "Property '{0}' is incompatible with rest element type."),
        A_rest_element_type_must_be_an_array_type: diag(2574, ts.DiagnosticCategory.Error, "A_rest_element_type_must_be_an_array_type_2574", "A rest element type must be an array type."),
        No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments: diag(2575, ts.DiagnosticCategory.Error, "No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments_2575", "No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments."),
        Property_0_is_a_static_member_of_type_1: diag(2576, ts.DiagnosticCategory.Error, "Property_0_is_a_static_member_of_type_1_2576", "Property '{0}' is a static member of type '{1}'"),
        Return_type_annotation_circularly_references_itself: diag(2577, ts.DiagnosticCategory.Error, "Return_type_annotation_circularly_references_itself_2577", "Return type annotation circularly references itself."),
        Unused_ts_expect_error_directive: diag(2578, ts.DiagnosticCategory.Error, "Unused_ts_expect_error_directive_2578", "Unused '@ts-expect-error' directive."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode: diag(2580, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_2580", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node`."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery: diag(2581, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_2581", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery`."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha: diag(2582, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashje_2582", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha`."),
        Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later: diag(2583, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2583", "Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later."),
        Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom: diag(2584, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_2584", "Cannot find name '{0}'. Do you need to change your target library? Try changing the `lib` compiler option to include 'dom'."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later: diag(2585, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_2585", "'{0}' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later."),
        Enum_type_0_circularly_references_itself: diag(2586, ts.DiagnosticCategory.Error, "Enum_type_0_circularly_references_itself_2586", "Enum type '{0}' circularly references itself."),
        JSDoc_type_0_circularly_references_itself: diag(2587, ts.DiagnosticCategory.Error, "JSDoc_type_0_circularly_references_itself_2587", "JSDoc type '{0}' circularly references itself."),
        Cannot_assign_to_0_because_it_is_a_constant: diag(2588, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_constant_2588", "Cannot assign to '{0}' because it is a constant."),
        Type_instantiation_is_excessively_deep_and_possibly_infinite: diag(2589, ts.DiagnosticCategory.Error, "Type_instantiation_is_excessively_deep_and_possibly_infinite_2589", "Type instantiation is excessively deep and possibly infinite."),
        Expression_produces_a_union_type_that_is_too_complex_to_represent: diag(2590, ts.DiagnosticCategory.Error, "Expression_produces_a_union_type_that_is_too_complex_to_represent_2590", "Expression produces a union type that is too complex to represent."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_th_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_an_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery` and then add `jquery` to the types field in your tsconfig."),
        Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashje_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig."),
        This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."),
        _0_can_only_be_imported_by_using_a_default_import: diag(2595, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_default_import_2595", "'{0}' can only be imported by using a default import."),
        _0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2596, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."),
        _0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import: diag(2597, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", "'{0}' can only be imported by using a 'require' call or by using a default import."),
        _0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2598, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using__2598", "'{0}' can only be imported by using a 'require' call or by turning on the 'esModuleInterop' flag and using a default import."),
        JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."),
        The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."),
        JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."),
        Property_0_in_type_1_is_not_assignable_to_type_2: diag(2603, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_type_2_2603", "Property '{0}' in type '{1}' is not assignable to type '{2}'."),
        JSX_element_type_0_does_not_have_any_construct_or_call_signatures: diag(2604, ts.DiagnosticCategory.Error, "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604", "JSX element type '{0}' does not have any construct or call signatures."),
        JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements: diag(2605, ts.DiagnosticCategory.Error, "JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements_2605", "JSX element type '{0}' is not a constructor function for JSX elements."),
        Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property: diag(2606, ts.DiagnosticCategory.Error, "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606", "Property '{0}' of JSX spread attribute is not assignable to target property."),
        JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: diag(2607, ts.DiagnosticCategory.Error, "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607", "JSX element class does not support attributes because it does not have a '{0}' property."),
        The_global_type_JSX_0_may_not_have_more_than_one_property: diag(2608, ts.DiagnosticCategory.Error, "The_global_type_JSX_0_may_not_have_more_than_one_property_2608", "The global type 'JSX.{0}' may not have more than one property."),
        JSX_spread_child_must_be_an_array_type: diag(2609, ts.DiagnosticCategory.Error, "JSX_spread_child_must_be_an_array_type_2609", "JSX spread child must be an array type."),
        _0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property: diag(2610, ts.DiagnosticCategory.Error, "_0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property_2610", "'{0}' is defined as an accessor in class '{1}', but is overridden here in '{2}' as an instance property."),
        _0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor: diag(2611, ts.DiagnosticCategory.Error, "_0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor_2611", "'{0}' is defined as a property in class '{1}', but is overridden here in '{2}' as an accessor."),
        Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration: diag(2612, ts.DiagnosticCategory.Error, "Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_2612", "Property '{0}' will overwrite the base property in '{1}'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration."),
        Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead: diag(2613, ts.DiagnosticCategory.Error, "Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead_2613", "Module '{0}' has no default export. Did you mean to use 'import { {1} } from {0}' instead?"),
        Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead: diag(2614, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead_2614", "Module '{0}' has no exported member '{1}'. Did you mean to use 'import {1} from {0}' instead?"),
        Type_of_property_0_circularly_references_itself_in_mapped_type_1: diag(2615, ts.DiagnosticCategory.Error, "Type_of_property_0_circularly_references_itself_in_mapped_type_1_2615", "Type of property '{0}' circularly references itself in mapped type '{1}'."),
        _0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import: diag(2616, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import_2616", "'{0}' can only be imported by using 'import {1} = require({2})' or a default import."),
        _0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2617, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_us_2617", "'{0}' can only be imported by using 'import {1} = require({2})' or by turning on the 'esModuleInterop' flag and using a default import."),
        Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity: diag(2649, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity_2649", "Cannot augment module '{0}' with value exports because it resolves to a non-module entity."),
        A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: diag(2651, ts.DiagnosticCategory.Error, "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651", "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums."),
        Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: diag(2652, ts.DiagnosticCategory.Error, "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652", "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead."),
        Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1: diag(2653, ts.DiagnosticCategory.Error, "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653", "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'."),
        Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition: diag(2654, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654", "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition."),
        Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition: diag(2656, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656", "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition."),
        JSX_expressions_must_have_one_parent_element: diag(2657, ts.DiagnosticCategory.Error, "JSX_expressions_must_have_one_parent_element_2657", "JSX expressions must have one parent element."),
        Type_0_provides_no_match_for_the_signature_1: diag(2658, ts.DiagnosticCategory.Error, "Type_0_provides_no_match_for_the_signature_1_2658", "Type '{0}' provides no match for the signature '{1}'."),
        super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher: diag(2659, ts.DiagnosticCategory.Error, "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659", "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher."),
        super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions: diag(2660, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660", "'super' can only be referenced in members of derived classes or object literal expressions."),
        Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module: diag(2661, ts.DiagnosticCategory.Error, "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661", "Cannot export '{0}'. Only local declarations can be exported from a module."),
        Cannot_find_name_0_Did_you_mean_the_static_member_1_0: diag(2662, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662", "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?"),
        Cannot_find_name_0_Did_you_mean_the_instance_member_this_0: diag(2663, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663", "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?"),
        Invalid_module_name_in_augmentation_module_0_cannot_be_found: diag(2664, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664", "Invalid module name in augmentation, module '{0}' cannot be found."),
        Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented: diag(2665, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augm_2665", "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented."),
        Exports_and_export_assignments_are_not_permitted_in_module_augmentations: diag(2666, ts.DiagnosticCategory.Error, "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666", "Exports and export assignments are not permitted in module augmentations."),
        Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module: diag(2667, ts.DiagnosticCategory.Error, "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667", "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module."),
        export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible: diag(2668, ts.DiagnosticCategory.Error, "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668", "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible."),
        Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations: diag(2669, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669", "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."),
        Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context: diag(2670, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670", "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context."),
        Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity: diag(2671, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671", "Cannot augment module '{0}' because it resolves to a non-module entity."),
        Cannot_assign_a_0_constructor_type_to_a_1_constructor_type: diag(2672, ts.DiagnosticCategory.Error, "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672", "Cannot assign a '{0}' constructor type to a '{1}' constructor type."),
        Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration: diag(2673, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673", "Constructor of class '{0}' is private and only accessible within the class declaration."),
        Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration: diag(2674, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674", "Constructor of class '{0}' is protected and only accessible within the class declaration."),
        Cannot_extend_a_class_0_Class_constructor_is_marked_as_private: diag(2675, ts.DiagnosticCategory.Error, "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675", "Cannot extend a class '{0}'. Class constructor is marked as private."),
        Accessors_must_both_be_abstract_or_non_abstract: diag(2676, ts.DiagnosticCategory.Error, "Accessors_must_both_be_abstract_or_non_abstract_2676", "Accessors must both be abstract or non-abstract."),
        A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type: diag(2677, ts.DiagnosticCategory.Error, "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677", "A type predicate's type must be assignable to its parameter's type."),
        Type_0_is_not_comparable_to_type_1: diag(2678, ts.DiagnosticCategory.Error, "Type_0_is_not_comparable_to_type_1_2678", "Type '{0}' is not comparable to type '{1}'."),
        A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void: diag(2679, ts.DiagnosticCategory.Error, "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679", "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'."),
        A_0_parameter_must_be_the_first_parameter: diag(2680, ts.DiagnosticCategory.Error, "A_0_parameter_must_be_the_first_parameter_2680", "A '{0}' parameter must be the first parameter."),
        A_constructor_cannot_have_a_this_parameter: diag(2681, ts.DiagnosticCategory.Error, "A_constructor_cannot_have_a_this_parameter_2681", "A constructor cannot have a 'this' parameter."),
        get_and_set_accessor_must_have_the_same_this_type: diag(2682, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_this_type_2682", "'get' and 'set' accessor must have the same 'this' type."),
        this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: diag(2683, ts.DiagnosticCategory.Error, "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", "'this' implicitly has type 'any' because it does not have a type annotation."),
        The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: diag(2684, ts.DiagnosticCategory.Error, "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'."),
        The_this_types_of_each_signature_are_incompatible: diag(2685, ts.DiagnosticCategory.Error, "The_this_types_of_each_signature_are_incompatible_2685", "The 'this' types of each signature are incompatible."),
        _0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead: diag(2686, ts.DiagnosticCategory.Error, "_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686", "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead."),
        All_declarations_of_0_must_have_identical_modifiers: diag(2687, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_modifiers_2687", "All declarations of '{0}' must have identical modifiers."),
        Cannot_find_type_definition_file_for_0: diag(2688, ts.DiagnosticCategory.Error, "Cannot_find_type_definition_file_for_0_2688", "Cannot find type definition file for '{0}'."),
        Cannot_extend_an_interface_0_Did_you_mean_implements: diag(2689, ts.DiagnosticCategory.Error, "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", "Cannot extend an interface '{0}'. Did you mean 'implements'?"),
        An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: diag(2691, ts.DiagnosticCategory.Error, "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead."),
        _0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible: diag(2692, ts.DiagnosticCategory.Error, "_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible_2692", "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_value_here: diag(2693, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_2693", "'{0}' only refers to a type, but is being used as a value here."),
        Namespace_0_has_no_exported_member_1: diag(2694, ts.DiagnosticCategory.Error, "Namespace_0_has_no_exported_member_1_2694", "Namespace '{0}' has no exported member '{1}'."),
        Left_side_of_comma_operator_is_unused_and_has_no_side_effects: diag(2695, ts.DiagnosticCategory.Error, "Left_side_of_comma_operator_is_unused_and_has_no_side_effects_2695", "Left side of comma operator is unused and has no side effects.", /*reportsUnnecessary*/ true),
        The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead: diag(2696, ts.DiagnosticCategory.Error, "The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead_2696", "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?"),
        An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2697, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_in_2697", "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
        Spread_types_may_only_be_created_from_object_types: diag(2698, ts.DiagnosticCategory.Error, "Spread_types_may_only_be_created_from_object_types_2698", "Spread types may only be created from object types."),
        Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1: diag(2699, ts.DiagnosticCategory.Error, "Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1_2699", "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'."),
        Rest_types_may_only_be_created_from_object_types: diag(2700, ts.DiagnosticCategory.Error, "Rest_types_may_only_be_created_from_object_types_2700", "Rest types may only be created from object types."),
        The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access: diag(2701, ts.DiagnosticCategory.Error, "The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access_2701", "The target of an object rest assignment must be a variable or a property access."),
        _0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here: diag(2702, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here_2702", "'{0}' only refers to a type, but is being used as a namespace here."),
        The_operand_of_a_delete_operator_must_be_a_property_reference: diag(2703, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_must_be_a_property_reference_2703", "The operand of a 'delete' operator must be a property reference."),
        The_operand_of_a_delete_operator_cannot_be_a_read_only_property: diag(2704, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_read_only_property_2704", "The operand of a 'delete' operator cannot be a read-only property."),
        An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2705, ts.DiagnosticCategory.Error, "An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_de_2705", "An async function or method in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
        Required_type_parameters_may_not_follow_optional_type_parameters: diag(2706, ts.DiagnosticCategory.Error, "Required_type_parameters_may_not_follow_optional_type_parameters_2706", "Required type parameters may not follow optional type parameters."),
        Generic_type_0_requires_between_1_and_2_type_arguments: diag(2707, ts.DiagnosticCategory.Error, "Generic_type_0_requires_between_1_and_2_type_arguments_2707", "Generic type '{0}' requires between {1} and {2} type arguments."),
        Cannot_use_namespace_0_as_a_value: diag(2708, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_value_2708", "Cannot use namespace '{0}' as a value."),
        Cannot_use_namespace_0_as_a_type: diag(2709, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_type_2709", "Cannot use namespace '{0}' as a type."),
        _0_are_specified_twice_The_attribute_named_0_will_be_overwritten: diag(2710, ts.DiagnosticCategory.Error, "_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710", "'{0}' are specified twice. The attribute named '{0}' will be overwritten."),
        A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2711, ts.DiagnosticCategory.Error, "A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES20_2711", "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."),
        A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2712, ts.DiagnosticCategory.Error, "A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declarat_2712", "A dynamic import call in ES5/ES3 requires the 'Promise' constructor.  Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."),
        Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1: diag(2713, ts.DiagnosticCategory.Error, "Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_p_2713", "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?"),
        The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context: diag(2714, ts.DiagnosticCategory.Error, "The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context_2714", "The expression of an export assignment must be an identifier or qualified name in an ambient context."),
        Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor: diag(2715, ts.DiagnosticCategory.Error, "Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715", "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor."),
        Type_parameter_0_has_a_circular_default: diag(2716, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_default_2716", "Type parameter '{0}' has a circular default."),
        Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2: diag(2717, ts.DiagnosticCategory.Error, "Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_t_2717", "Subsequent property declarations must have the same type.  Property '{0}' must be of type '{1}', but here has type '{2}'."),
        Duplicate_property_0: diag(2718, ts.DiagnosticCategory.Error, "Duplicate_property_0_2718", "Duplicate property '{0}'."),
        Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated: diag(2719, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_2719", "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated."),
        Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass: diag(2720, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclas_2720", "Class '{0}' incorrectly implements class '{1}'. Did you mean to extend '{1}' and inherit its members as a subclass?"),
        Cannot_invoke_an_object_which_is_possibly_null: diag(2721, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_null_2721", "Cannot invoke an object which is possibly 'null'."),
        Cannot_invoke_an_object_which_is_possibly_undefined: diag(2722, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_undefined_2722", "Cannot invoke an object which is possibly 'undefined'."),
        Cannot_invoke_an_object_which_is_possibly_null_or_undefined: diag(2723, ts.DiagnosticCategory.Error, "Cannot_invoke_an_object_which_is_possibly_null_or_undefined_2723", "Cannot invoke an object which is possibly 'null' or 'undefined'."),
        Module_0_has_no_exported_member_1_Did_you_mean_2: diag(2724, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_Did_you_mean_2_2724", "Module '{0}' has no exported member '{1}'. Did you mean '{2}'?"),
        Class_name_cannot_be_Object_when_targeting_ES5_with_module_0: diag(2725, ts.DiagnosticCategory.Error, "Class_name_cannot_be_Object_when_targeting_ES5_with_module_0_2725", "Class name cannot be 'Object' when targeting ES5 with module {0}."),
        Cannot_find_lib_definition_for_0: diag(2726, ts.DiagnosticCategory.Error, "Cannot_find_lib_definition_for_0_2726", "Cannot find lib definition for '{0}'."),
        Cannot_find_lib_definition_for_0_Did_you_mean_1: diag(2727, ts.DiagnosticCategory.Error, "Cannot_find_lib_definition_for_0_Did_you_mean_1_2727", "Cannot find lib definition for '{0}'. Did you mean '{1}'?"),
        _0_is_declared_here: diag(2728, ts.DiagnosticCategory.Message, "_0_is_declared_here_2728", "'{0}' is declared here."),
        Property_0_is_used_before_its_initialization: diag(2729, ts.DiagnosticCategory.Error, "Property_0_is_used_before_its_initialization_2729", "Property '{0}' is used before its initialization."),
        An_arrow_function_cannot_have_a_this_parameter: diag(2730, ts.DiagnosticCategory.Error, "An_arrow_function_cannot_have_a_this_parameter_2730", "An arrow function cannot have a 'this' parameter."),
        Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String: diag(2731, ts.DiagnosticCategory.Error, "Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_i_2731", "Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'."),
        Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension: diag(2732, ts.DiagnosticCategory.Error, "Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension_2732", "Cannot find module '{0}'. Consider using '--resolveJsonModule' to import module with '.json' extension"),
        Property_0_was_also_declared_here: diag(2733, ts.DiagnosticCategory.Error, "Property_0_was_also_declared_here_2733", "Property '{0}' was also declared here."),
        Are_you_missing_a_semicolon: diag(2734, ts.DiagnosticCategory.Error, "Are_you_missing_a_semicolon_2734", "Are you missing a semicolon?"),
        Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1: diag(2735, ts.DiagnosticCategory.Error, "Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1_2735", "Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?"),
        Operator_0_cannot_be_applied_to_type_1: diag(2736, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_type_1_2736", "Operator '{0}' cannot be applied to type '{1}'."),
        BigInt_literals_are_not_available_when_targeting_lower_than_ES2020: diag(2737, ts.DiagnosticCategory.Error, "BigInt_literals_are_not_available_when_targeting_lower_than_ES2020_2737", "BigInt literals are not available when targeting lower than ES2020."),
        An_outer_value_of_this_is_shadowed_by_this_container: diag(2738, ts.DiagnosticCategory.Message, "An_outer_value_of_this_is_shadowed_by_this_container_2738", "An outer value of 'this' is shadowed by this container."),
        Type_0_is_missing_the_following_properties_from_type_1_Colon_2: diag(2739, ts.DiagnosticCategory.Error, "Type_0_is_missing_the_following_properties_from_type_1_Colon_2_2739", "Type '{0}' is missing the following properties from type '{1}': {2}"),
        Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more: diag(2740, ts.DiagnosticCategory.Error, "Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more_2740", "Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more."),
        Property_0_is_missing_in_type_1_but_required_in_type_2: diag(2741, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_but_required_in_type_2_2741", "Property '{0}' is missing in type '{1}' but required in type '{2}'."),
        The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary: diag(2742, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_a_2742", "The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary."),
        No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments: diag(2743, ts.DiagnosticCategory.Error, "No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments_2743", "No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments."),
        Type_parameter_defaults_can_only_reference_previously_declared_type_parameters: diag(2744, ts.DiagnosticCategory.Error, "Type_parameter_defaults_can_only_reference_previously_declared_type_parameters_2744", "Type parameter defaults can only reference previously declared type parameters."),
        This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided: diag(2745, ts.DiagnosticCategory.Error, "This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_pr_2745", "This JSX tag's '{0}' prop expects type '{1}' which requires multiple children, but only a single child was provided."),
        This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided: diag(2746, ts.DiagnosticCategory.Error, "This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided_2746", "This JSX tag's '{0}' prop expects a single child of type '{1}', but multiple children were provided."),
        _0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2: diag(2747, ts.DiagnosticCategory.Error, "_0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_t_2747", "'{0}' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of '{1}' is '{2}'."),
        Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided: diag(2748, ts.DiagnosticCategory.Error, "Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided_2748", "Cannot access ambient const enums when the '--isolatedModules' flag is provided."),
        _0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0: diag(2749, ts.DiagnosticCategory.Error, "_0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0_2749", "'{0}' refers to a value, but is being used as a type here. Did you mean 'typeof {0}'?"),
        The_implementation_signature_is_declared_here: diag(2750, ts.DiagnosticCategory.Error, "The_implementation_signature_is_declared_here_2750", "The implementation signature is declared here."),
        Circularity_originates_in_type_at_this_location: diag(2751, ts.DiagnosticCategory.Error, "Circularity_originates_in_type_at_this_location_2751", "Circularity originates in type at this location."),
        The_first_export_default_is_here: diag(2752, ts.DiagnosticCategory.Error, "The_first_export_default_is_here_2752", "The first export default is here."),
        Another_export_default_is_here: diag(2753, ts.DiagnosticCategory.Error, "Another_export_default_is_here_2753", "Another export default is here."),
        super_may_not_use_type_arguments: diag(2754, ts.DiagnosticCategory.Error, "super_may_not_use_type_arguments_2754", "'super' may not use type arguments."),
        No_constituent_of_type_0_is_callable: diag(2755, ts.DiagnosticCategory.Error, "No_constituent_of_type_0_is_callable_2755", "No constituent of type '{0}' is callable."),
        Not_all_constituents_of_type_0_are_callable: diag(2756, ts.DiagnosticCategory.Error, "Not_all_constituents_of_type_0_are_callable_2756", "Not all constituents of type '{0}' are callable."),
        Type_0_has_no_call_signatures: diag(2757, ts.DiagnosticCategory.Error, "Type_0_has_no_call_signatures_2757", "Type '{0}' has no call signatures."),
        Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_other: diag(2758, ts.DiagnosticCategory.Error, "Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_2758", "Each member of the union type '{0}' has signatures, but none of those signatures are compatible with each other."),
        No_constituent_of_type_0_is_constructable: diag(2759, ts.DiagnosticCategory.Error, "No_constituent_of_type_0_is_constructable_2759", "No constituent of type '{0}' is constructable."),
        Not_all_constituents_of_type_0_are_constructable: diag(2760, ts.DiagnosticCategory.Error, "Not_all_constituents_of_type_0_are_constructable_2760", "Not all constituents of type '{0}' are constructable."),
        Type_0_has_no_construct_signatures: diag(2761, ts.DiagnosticCategory.Error, "Type_0_has_no_construct_signatures_2761", "Type '{0}' has no construct signatures."),
        Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_with_each_other: diag(2762, ts.DiagnosticCategory.Error, "Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_2762", "Each member of the union type '{0}' has construct signatures, but none of those signatures are compatible with each other."),
        Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_send_0: diag(2763, ts.DiagnosticCategory.Error, "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_s_2763", "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but for-of will always send '{0}'."),
        Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_always_send_0: diag(2764, ts.DiagnosticCategory.Error, "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_al_2764", "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array spread will always send '{0}'."),
        Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring_will_always_send_0: diag(2765, ts.DiagnosticCategory.Error, "Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring__2765", "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array destructuring will always send '{0}'."),
        Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_containing_generator_will_always_send_0: diag(2766, ts.DiagnosticCategory.Error, "Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_co_2766", "Cannot delegate iteration to value because the 'next' method of its iterator expects type '{1}', but the containing generator will always send '{0}'."),
        The_0_property_of_an_iterator_must_be_a_method: diag(2767, ts.DiagnosticCategory.Error, "The_0_property_of_an_iterator_must_be_a_method_2767", "The '{0}' property of an iterator must be a method."),
        The_0_property_of_an_async_iterator_must_be_a_method: diag(2768, ts.DiagnosticCategory.Error, "The_0_property_of_an_async_iterator_must_be_a_method_2768", "The '{0}' property of an async iterator must be a method."),
        No_overload_matches_this_call: diag(2769, ts.DiagnosticCategory.Error, "No_overload_matches_this_call_2769", "No overload matches this call."),
        The_last_overload_gave_the_following_error: diag(2770, ts.DiagnosticCategory.Error, "The_last_overload_gave_the_following_error_2770", "The last overload gave the following error."),
        The_last_overload_is_declared_here: diag(2771, ts.DiagnosticCategory.Error, "The_last_overload_is_declared_here_2771", "The last overload is declared here."),
        Overload_0_of_1_2_gave_the_following_error: diag(2772, ts.DiagnosticCategory.Error, "Overload_0_of_1_2_gave_the_following_error_2772", "Overload {0} of {1}, '{2}', gave the following error."),
        Did_you_forget_to_use_await: diag(2773, ts.DiagnosticCategory.Error, "Did_you_forget_to_use_await_2773", "Did you forget to use 'await'?"),
        This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead: diag(2774, ts.DiagnosticCategory.Error, "This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it__2774", "This condition will always return true since the function is always defined. Did you mean to call it instead?"),
        Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation: diag(2775, ts.DiagnosticCategory.Error, "Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation_2775", "Assertions require every name in the call target to be declared with an explicit type annotation."),
        Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name: diag(2776, ts.DiagnosticCategory.Error, "Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name_2776", "Assertions require the call target to be an identifier or qualified name."),
        The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access: diag(2777, ts.DiagnosticCategory.Error, "The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access_2777", "The operand of an increment or decrement operator may not be an optional property access."),
        The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access: diag(2778, ts.DiagnosticCategory.Error, "The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access_2778", "The target of an object rest assignment may not be an optional property access."),
        The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access: diag(2779, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access_2779", "The left-hand side of an assignment expression may not be an optional property access."),
        The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access: diag(2780, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access_2780", "The left-hand side of a 'for...in' statement may not be an optional property access."),
        The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access: diag(2781, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access_2781", "The left-hand side of a 'for...of' statement may not be an optional property access."),
        _0_needs_an_explicit_type_annotation: diag(2782, ts.DiagnosticCategory.Message, "_0_needs_an_explicit_type_annotation_2782", "'{0}' needs an explicit type annotation."),
        _0_is_specified_more_than_once_so_this_usage_will_be_overwritten: diag(2783, ts.DiagnosticCategory.Error, "_0_is_specified_more_than_once_so_this_usage_will_be_overwritten_2783", "'{0}' is specified more than once, so this usage will be overwritten."),
        get_and_set_accessors_cannot_declare_this_parameters: diag(2784, ts.DiagnosticCategory.Error, "get_and_set_accessors_cannot_declare_this_parameters_2784", "'get' and 'set' accessors cannot declare 'this' parameters."),
        This_spread_always_overwrites_this_property: diag(2785, ts.DiagnosticCategory.Error, "This_spread_always_overwrites_this_property_2785", "This spread always overwrites this property."),
        _0_cannot_be_used_as_a_JSX_component: diag(2786, ts.DiagnosticCategory.Error, "_0_cannot_be_used_as_a_JSX_component_2786", "'{0}' cannot be used as a JSX component."),
        Its_return_type_0_is_not_a_valid_JSX_element: diag(2787, ts.DiagnosticCategory.Error, "Its_return_type_0_is_not_a_valid_JSX_element_2787", "Its return type '{0}' is not a valid JSX element."),
        Its_instance_type_0_is_not_a_valid_JSX_element: diag(2788, ts.DiagnosticCategory.Error, "Its_instance_type_0_is_not_a_valid_JSX_element_2788", "Its instance type '{0}' is not a valid JSX element."),
        Its_element_type_0_is_not_a_valid_JSX_element: diag(2789, ts.DiagnosticCategory.Error, "Its_element_type_0_is_not_a_valid_JSX_element_2789", "Its element type '{0}' is not a valid JSX element."),
        Import_declaration_0_is_using_private_name_1: diag(4000, ts.DiagnosticCategory.Error, "Import_declaration_0_is_using_private_name_1_4000", "Import declaration '{0}' is using private name '{1}'."),
        Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: diag(4002, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", "Type parameter '{0}' of exported class has or is using private name '{1}'."),
        Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: diag(4004, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", "Type parameter '{0}' of exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4006, ts.DiagnosticCategory.Error, "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006", "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4008, ts.DiagnosticCategory.Error, "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008", "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4010, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010", "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
        Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4012, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012", "Type parameter '{0}' of public method from exported class has or is using private name '{1}'."),
        Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4014, ts.DiagnosticCategory.Error, "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014", "Type parameter '{0}' of method from exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4016, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016", "Type parameter '{0}' of exported function has or is using private name '{1}'."),
        Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4019, ts.DiagnosticCategory.Error, "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019", "Implements clause of exported class '{0}' has or is using private name '{1}'."),
        extends_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4020, ts.DiagnosticCategory.Error, "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020", "'extends' clause of exported class '{0}' has or is using private name '{1}'."),
        extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: diag(4022, ts.DiagnosticCategory.Error, "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022", "'extends' clause of exported interface '{0}' has or is using private name '{1}'."),
        Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4023, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023", "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named."),
        Exported_variable_0_has_or_is_using_name_1_from_private_module_2: diag(4024, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024", "Exported variable '{0}' has or is using name '{1}' from private module '{2}'."),
        Exported_variable_0_has_or_is_using_private_name_1: diag(4025, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_private_name_1_4025", "Exported variable '{0}' has or is using private name '{1}'."),
        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4026, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026", "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4027, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027", "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_static_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4028, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028", "Public static property '{0}' of exported class has or is using private name '{1}'."),
        Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4029, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029", "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4030, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030", "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4031, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031", "Public property '{0}' of exported class has or is using private name '{1}'."),
        Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4032, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032", "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'."),
        Property_0_of_exported_interface_has_or_is_using_private_name_1: diag(4033, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033", "Property '{0}' of exported interface has or is using private name '{1}'."),
        Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4034, ts.DiagnosticCategory.Error, "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_mod_4034", "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1: diag(4035, ts.DiagnosticCategory.Error, "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1_4035", "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'."),
        Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4036, ts.DiagnosticCategory.Error, "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036", "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1: diag(4037, ts.DiagnosticCategory.Error, "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1_4037", "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4038, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_modul_4038", "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4039, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_4039", "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1: diag(4040, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1_4040", "Return type of public static getter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4041, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_4041", "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4042, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4042", "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."),
        Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1: diag(4043, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1_4043", "Return type of public getter '{0}' from exported class has or is using private name '{1}'."),
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4044, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044", "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4045, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045", "Return type of constructor signature from exported interface has or is using private name '{0}'."),
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4046, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046", "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4047, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047", "Return type of call signature from exported interface has or is using private name '{0}'."),
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4048, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048", "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4049, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049", "Return type of index signature from exported interface has or is using private name '{0}'."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4050, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050", "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4051, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051", "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0: diag(4052, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052", "Return type of public static method from exported class has or is using private name '{0}'."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4053, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053", "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4054, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054", "Return type of public method from exported class has or is using name '{0}' from private module '{1}'."),
        Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0: diag(4055, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055", "Return type of public method from exported class has or is using private name '{0}'."),
        Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4056, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056", "Return type of method from exported interface has or is using name '{0}' from private module '{1}'."),
        Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0: diag(4057, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057", "Return type of method from exported interface has or is using private name '{0}'."),
        Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4058, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058", "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named."),
        Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1: diag(4059, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059", "Return type of exported function has or is using name '{0}' from private module '{1}'."),
        Return_type_of_exported_function_has_or_is_using_private_name_0: diag(4060, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_private_name_0_4060", "Return type of exported function has or is using private name '{0}'."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4061, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4062, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1: diag(4063, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063", "Parameter '{0}' of constructor from exported class has or is using private name '{1}'."),
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4064, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064", "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4065, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065", "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."),
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4066, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066", "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4067, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067", "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4068, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4069, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4070, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070", "Parameter '{0}' of public static method from exported class has or is using private name '{1}'."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4071, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071", "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4072, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072", "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4073, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073", "Parameter '{0}' of public method from exported class has or is using private name '{1}'."),
        Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4074, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074", "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4075, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075", "Parameter '{0}' of method from exported interface has or is using private name '{1}'."),
        Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4076, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076", "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named."),
        Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: diag(4077, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077", "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4078, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078", "Parameter '{0}' of exported function has or is using private name '{1}'."),
        Exported_type_alias_0_has_or_is_using_private_name_1: diag(4081, ts.DiagnosticCategory.Error, "Exported_type_alias_0_has_or_is_using_private_name_1_4081", "Exported type alias '{0}' has or is using private name '{1}'."),
        Default_export_of_the_module_has_or_is_using_private_name_0: diag(4082, ts.DiagnosticCategory.Error, "Default_export_of_the_module_has_or_is_using_private_name_0_4082", "Default export of the module has or is using private name '{0}'."),
        Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1: diag(4083, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083", "Type parameter '{0}' of exported type alias has or is using private name '{1}'."),
        Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict: diag(4090, ts.DiagnosticCategory.Error, "Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_librar_4090", "Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict."),
        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4091, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091", "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4092, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092", "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'."),
        Property_0_of_exported_class_expression_may_not_be_private_or_protected: diag(4094, ts.DiagnosticCategory.Error, "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094", "Property '{0}' of exported class expression may not be private or protected."),
        Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4095, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095", "Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4096, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096", "Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_static_method_0_of_exported_class_has_or_is_using_private_name_1: diag(4097, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097", "Public static method '{0}' of exported class has or is using private name '{1}'."),
        Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4098, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098", "Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."),
        Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4099, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099", "Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'."),
        Public_method_0_of_exported_class_has_or_is_using_private_name_1: diag(4100, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100", "Public method '{0}' of exported class has or is using private name '{1}'."),
        Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4101, ts.DiagnosticCategory.Error, "Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101", "Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'."),
        Method_0_of_exported_interface_has_or_is_using_private_name_1: diag(4102, ts.DiagnosticCategory.Error, "Method_0_of_exported_interface_has_or_is_using_private_name_1_4102", "Method '{0}' of exported interface has or is using private name '{1}'."),
        Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1: diag(4103, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1_4103", "Type parameter '{0}' of exported mapped object type is using private name '{1}'."),
        The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1: diag(4104, ts.DiagnosticCategory.Error, "The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1_4104", "The type '{0}' is 'readonly' and cannot be assigned to the mutable type '{1}'."),
        Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter: diag(4105, ts.DiagnosticCategory.Error, "Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter_4105", "Private or protected member '{0}' cannot be accessed on a type parameter."),
        Parameter_0_of_accessor_has_or_is_using_private_name_1: diag(4106, ts.DiagnosticCategory.Error, "Parameter_0_of_accessor_has_or_is_using_private_name_1_4106", "Parameter '{0}' of accessor has or is using private name '{1}'."),
        Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2: diag(4107, ts.DiagnosticCategory.Error, "Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2_4107", "Parameter '{0}' of accessor has or is using name '{1}' from private module '{2}'."),
        Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4108, ts.DiagnosticCategory.Error, "Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4108", "Parameter '{0}' of accessor has or is using name '{1}' from external module '{2}' but cannot be named."),
        Type_arguments_for_0_circularly_reference_themselves: diag(4109, ts.DiagnosticCategory.Error, "Type_arguments_for_0_circularly_reference_themselves_4109", "Type arguments for '{0}' circularly reference themselves."),
        Tuple_type_arguments_circularly_reference_themselves: diag(4110, ts.DiagnosticCategory.Error, "Tuple_type_arguments_circularly_reference_themselves_4110", "Tuple type arguments circularly reference themselves."),
        The_current_host_does_not_support_the_0_option: diag(5001, ts.DiagnosticCategory.Error, "The_current_host_does_not_support_the_0_option_5001", "The current host does not support the '{0}' option."),
        Cannot_find_the_common_subdirectory_path_for_the_input_files: diag(5009, ts.DiagnosticCategory.Error, "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009", "Cannot find the common subdirectory path for the input files."),
        File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5010, ts.DiagnosticCategory.Error, "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010", "File specification cannot end in a recursive directory wildcard ('**'): '{0}'."),
        Cannot_read_file_0_Colon_1: diag(5012, ts.DiagnosticCategory.Error, "Cannot_read_file_0_Colon_1_5012", "Cannot read file '{0}': {1}."),
        Failed_to_parse_file_0_Colon_1: diag(5014, ts.DiagnosticCategory.Error, "Failed_to_parse_file_0_Colon_1_5014", "Failed to parse file '{0}': {1}."),
        Unknown_compiler_option_0: diag(5023, ts.DiagnosticCategory.Error, "Unknown_compiler_option_0_5023", "Unknown compiler option '{0}'."),
        Compiler_option_0_requires_a_value_of_type_1: diag(5024, ts.DiagnosticCategory.Error, "Compiler_option_0_requires_a_value_of_type_1_5024", "Compiler option '{0}' requires a value of type {1}."),
        Unknown_compiler_option_0_Did_you_mean_1: diag(5025, ts.DiagnosticCategory.Error, "Unknown_compiler_option_0_Did_you_mean_1_5025", "Unknown compiler option '{0}'. Did you mean '{1}'?"),
        Could_not_write_file_0_Colon_1: diag(5033, ts.DiagnosticCategory.Error, "Could_not_write_file_0_Colon_1_5033", "Could not write file '{0}': {1}."),
        Option_project_cannot_be_mixed_with_source_files_on_a_command_line: diag(5042, ts.DiagnosticCategory.Error, "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042", "Option 'project' cannot be mixed with source files on a command line."),
        Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher: diag(5047, ts.DiagnosticCategory.Error, "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047", "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher."),
        Option_0_cannot_be_specified_when_option_target_is_ES3: diag(5048, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_when_option_target_is_ES3_5048", "Option '{0}' cannot be specified when option 'target' is 'ES3'."),
        Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: diag(5051, ts.DiagnosticCategory.Error, "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051", "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided."),
        Option_0_cannot_be_specified_without_specifying_option_1: diag(5052, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_5052", "Option '{0}' cannot be specified without specifying option '{1}'."),
        Option_0_cannot_be_specified_with_option_1: diag(5053, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_with_option_1_5053", "Option '{0}' cannot be specified with option '{1}'."),
        A_tsconfig_json_file_is_already_defined_at_Colon_0: diag(5054, ts.DiagnosticCategory.Error, "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054", "A 'tsconfig.json' file is already defined at: '{0}'."),
        Cannot_write_file_0_because_it_would_overwrite_input_file: diag(5055, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_overwrite_input_file_5055", "Cannot write file '{0}' because it would overwrite input file."),
        Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files: diag(5056, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056", "Cannot write file '{0}' because it would be overwritten by multiple input files."),
        Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0: diag(5057, ts.DiagnosticCategory.Error, "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057", "Cannot find a tsconfig.json file at the specified directory: '{0}'."),
        The_specified_path_does_not_exist_Colon_0: diag(5058, ts.DiagnosticCategory.Error, "The_specified_path_does_not_exist_Colon_0_5058", "The specified path does not exist: '{0}'."),
        Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier: diag(5059, ts.DiagnosticCategory.Error, "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059", "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier."),
        Option_paths_cannot_be_used_without_specifying_baseUrl_option: diag(5060, ts.DiagnosticCategory.Error, "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", "Option 'paths' cannot be used without specifying '--baseUrl' option."),
        Pattern_0_can_have_at_most_one_Asterisk_character: diag(5061, ts.DiagnosticCategory.Error, "Pattern_0_can_have_at_most_one_Asterisk_character_5061", "Pattern '{0}' can have at most one '*' character."),
        Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character: diag(5062, ts.DiagnosticCategory.Error, "Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character_5062", "Substitution '{0}' in pattern '{1}' can have at most one '*' character."),
        Substitutions_for_pattern_0_should_be_an_array: diag(5063, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_should_be_an_array_5063", "Substitutions for pattern '{0}' should be an array."),
        Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: diag(5064, ts.DiagnosticCategory.Error, "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'."),
        File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5065, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065", "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'."),
        Substitutions_for_pattern_0_shouldn_t_be_an_empty_array: diag(5066, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_shouldn_t_be_an_empty_array_5066", "Substitutions for pattern '{0}' shouldn't be an empty array."),
        Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name: diag(5067, ts.DiagnosticCategory.Error, "Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name_5067", "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name."),
        Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig: diag(5068, ts.DiagnosticCategory.Error, "Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068", "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig."),
        Option_0_cannot_be_specified_without_specifying_option_1_or_option_2: diag(5069, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_or_option_2_5069", "Option '{0}' cannot be specified without specifying option '{1}' or option '{2}'."),
        Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy: diag(5070, ts.DiagnosticCategory.Error, "Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070", "Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy."),
        Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext: diag(5071, ts.DiagnosticCategory.Error, "Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_5071", "Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'."),
        Unknown_build_option_0: diag(5072, ts.DiagnosticCategory.Error, "Unknown_build_option_0_5072", "Unknown build option '{0}'."),
        Build_option_0_requires_a_value_of_type_1: diag(5073, ts.DiagnosticCategory.Error, "Build_option_0_requires_a_value_of_type_1_5073", "Build option '{0}' requires a value of type {1}."),
        Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified: diag(5074, ts.DiagnosticCategory.Error, "Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBui_5074", "Option '--incremental' can only be specified using tsconfig, emitting to single file or when option `--tsBuildInfoFile` is specified."),
        _0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2: diag(5075, ts.DiagnosticCategory.Error, "_0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_5075", "'{0}' is assignable to the constraint of type '{1}', but '{1}' could be instantiated with a different subtype of constraint '{2}'."),
        _0_and_1_operations_cannot_be_mixed_without_parentheses: diag(5076, ts.DiagnosticCategory.Error, "_0_and_1_operations_cannot_be_mixed_without_parentheses_5076", "'{0}' and '{1}' operations cannot be mixed without parentheses."),
        Unknown_build_option_0_Did_you_mean_1: diag(5077, ts.DiagnosticCategory.Error, "Unknown_build_option_0_Did_you_mean_1_5077", "Unknown build option '{0}'. Did you mean '{1}'?"),
        Unknown_watch_option_0: diag(5078, ts.DiagnosticCategory.Error, "Unknown_watch_option_0_5078", "Unknown watch option '{0}'."),
        Unknown_watch_option_0_Did_you_mean_1: diag(5079, ts.DiagnosticCategory.Error, "Unknown_watch_option_0_Did_you_mean_1_5079", "Unknown watch option '{0}'. Did you mean '{1}'?"),
        Watch_option_0_requires_a_value_of_type_1: diag(5080, ts.DiagnosticCategory.Error, "Watch_option_0_requires_a_value_of_type_1_5080", "Watch option '{0}' requires a value of type {1}."),
        Cannot_find_a_tsconfig_json_file_at_the_current_directory_Colon_0: diag(5081, ts.DiagnosticCategory.Error, "Cannot_find_a_tsconfig_json_file_at_the_current_directory_Colon_0_5081", "Cannot find a tsconfig.json file at the current directory: {0}."),
        _0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1: diag(5082, ts.DiagnosticCategory.Error, "_0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1_5082", "'{0}' could be instantiated with an arbitrary type which could be unrelated to '{1}'."),
        Cannot_read_file_0: diag(5083, ts.DiagnosticCategory.Error, "Cannot_read_file_0_5083", "Cannot read file '{0}'."),
        The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary: diag(5088, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialize_5088", "The inferred type of '{0}' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary."),
        Generates_a_sourcemap_for_each_corresponding_d_ts_file: diag(6000, ts.DiagnosticCategory.Message, "Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000", "Generates a sourcemap for each corresponding '.d.ts' file."),
        Concatenate_and_emit_output_to_single_file: diag(6001, ts.DiagnosticCategory.Message, "Concatenate_and_emit_output_to_single_file_6001", "Concatenate and emit output to single file."),
        Generates_corresponding_d_ts_file: diag(6002, ts.DiagnosticCategory.Message, "Generates_corresponding_d_ts_file_6002", "Generates corresponding '.d.ts' file."),
        Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: diag(6003, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6003", "Specify the location where debugger should locate map files instead of generated locations."),
        Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: diag(6004, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004", "Specify the location where debugger should locate TypeScript files instead of source locations."),
        Watch_input_files: diag(6005, ts.DiagnosticCategory.Message, "Watch_input_files_6005", "Watch input files."),
        Redirect_output_structure_to_the_directory: diag(6006, ts.DiagnosticCategory.Message, "Redirect_output_structure_to_the_directory_6006", "Redirect output structure to the directory."),
        Do_not_erase_const_enum_declarations_in_generated_code: diag(6007, ts.DiagnosticCategory.Message, "Do_not_erase_const_enum_declarations_in_generated_code_6007", "Do not erase const enum declarations in generated code."),
        Do_not_emit_outputs_if_any_errors_were_reported: diag(6008, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_if_any_errors_were_reported_6008", "Do not emit outputs if any errors were reported."),
        Do_not_emit_comments_to_output: diag(6009, ts.DiagnosticCategory.Message, "Do_not_emit_comments_to_output_6009", "Do not emit comments to output."),
        Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."),
        Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."),
        Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."),
        Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."),
        Only_emit_d_ts_declaration_files: diag(6014, ts.DiagnosticCategory.Message, "Only_emit_d_ts_declaration_files_6014", "Only emit '.d.ts' declaration files."),
        Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_ES2020_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_ES2020_or_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'."),
        Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_es2020_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_es2020_or_ESNext_6016", "Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'."),
        Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."),
        Print_the_compiler_s_version: diag(6019, ts.DiagnosticCategory.Message, "Print_the_compiler_s_version_6019", "Print the compiler's version."),
        Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json: diag(6020, ts.DiagnosticCategory.Message, "Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020", "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."),
        Syntax_Colon_0: diag(6023, ts.DiagnosticCategory.Message, "Syntax_Colon_0_6023", "Syntax: {0}"),
        options: diag(6024, ts.DiagnosticCategory.Message, "options_6024", "options"),
        file: diag(6025, ts.DiagnosticCategory.Message, "file_6025", "file"),
        Examples_Colon_0: diag(6026, ts.DiagnosticCategory.Message, "Examples_Colon_0_6026", "Examples: {0}"),
        Options_Colon: diag(6027, ts.DiagnosticCategory.Message, "Options_Colon_6027", "Options:"),
        Version_0: diag(6029, ts.DiagnosticCategory.Message, "Version_0_6029", "Version {0}"),
        Insert_command_line_options_and_files_from_a_file: diag(6030, ts.DiagnosticCategory.Message, "Insert_command_line_options_and_files_from_a_file_6030", "Insert command line options and files from a file."),
        Starting_compilation_in_watch_mode: diag(6031, ts.DiagnosticCategory.Message, "Starting_compilation_in_watch_mode_6031", "Starting compilation in watch mode..."),
        File_change_detected_Starting_incremental_compilation: diag(6032, ts.DiagnosticCategory.Message, "File_change_detected_Starting_incremental_compilation_6032", "File change detected. Starting incremental compilation..."),
        KIND: diag(6034, ts.DiagnosticCategory.Message, "KIND_6034", "KIND"),
        FILE: diag(6035, ts.DiagnosticCategory.Message, "FILE_6035", "FILE"),
        VERSION: diag(6036, ts.DiagnosticCategory.Message, "VERSION_6036", "VERSION"),
        LOCATION: diag(6037, ts.DiagnosticCategory.Message, "LOCATION_6037", "LOCATION"),
        DIRECTORY: diag(6038, ts.DiagnosticCategory.Message, "DIRECTORY_6038", "DIRECTORY"),
        STRATEGY: diag(6039, ts.DiagnosticCategory.Message, "STRATEGY_6039", "STRATEGY"),
        FILE_OR_DIRECTORY: diag(6040, ts.DiagnosticCategory.Message, "FILE_OR_DIRECTORY_6040", "FILE OR DIRECTORY"),
        Generates_corresponding_map_file: diag(6043, ts.DiagnosticCategory.Message, "Generates_corresponding_map_file_6043", "Generates corresponding '.map' file."),
        Compiler_option_0_expects_an_argument: diag(6044, ts.DiagnosticCategory.Error, "Compiler_option_0_expects_an_argument_6044", "Compiler option '{0}' expects an argument."),
        Unterminated_quoted_string_in_response_file_0: diag(6045, ts.DiagnosticCategory.Error, "Unterminated_quoted_string_in_response_file_0_6045", "Unterminated quoted string in response file '{0}'."),
        Argument_for_0_option_must_be_Colon_1: diag(6046, ts.DiagnosticCategory.Error, "Argument_for_0_option_must_be_Colon_1_6046", "Argument for '{0}' option must be: {1}."),
        Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: diag(6048, ts.DiagnosticCategory.Error, "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048", "Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'."),
        Unsupported_locale_0: diag(6049, ts.DiagnosticCategory.Error, "Unsupported_locale_0_6049", "Unsupported locale '{0}'."),
        Unable_to_open_file_0: diag(6050, ts.DiagnosticCategory.Error, "Unable_to_open_file_0_6050", "Unable to open file '{0}'."),
        Corrupted_locale_file_0: diag(6051, ts.DiagnosticCategory.Error, "Corrupted_locale_file_0_6051", "Corrupted locale file {0}."),
        Raise_error_on_expressions_and_declarations_with_an_implied_any_type: diag(6052, ts.DiagnosticCategory.Message, "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052", "Raise error on expressions and declarations with an implied 'any' type."),
        File_0_not_found: diag(6053, ts.DiagnosticCategory.Error, "File_0_not_found_6053", "File '{0}' not found."),
        File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1: diag(6054, ts.DiagnosticCategory.Error, "File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1_6054", "File '{0}' has an unsupported extension. The only supported extensions are {1}."),
        Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: diag(6055, ts.DiagnosticCategory.Message, "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055", "Suppress noImplicitAny errors for indexing objects lacking index signatures."),
        Do_not_emit_declarations_for_code_that_has_an_internal_annotation: diag(6056, ts.DiagnosticCategory.Message, "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056", "Do not emit declarations for code that has an '@internal' annotation."),
        Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir: diag(6058, ts.DiagnosticCategory.Message, "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058", "Specify the root directory of input files. Use to control the output directory structure with --outDir."),
        File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files: diag(6059, ts.DiagnosticCategory.Error, "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059", "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files."),
        Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: diag(6060, ts.DiagnosticCategory.Message, "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060", "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)."),
        NEWLINE: diag(6061, ts.DiagnosticCategory.Message, "NEWLINE_6061", "NEWLINE"),
        Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line: diag(6064, ts.DiagnosticCategory.Error, "Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line_6064", "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'null' on command line."),
        Enables_experimental_support_for_ES7_decorators: diag(6065, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_decorators_6065", "Enables experimental support for ES7 decorators."),
        Enables_experimental_support_for_emitting_type_metadata_for_decorators: diag(6066, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066", "Enables experimental support for emitting type metadata for decorators."),
        Enables_experimental_support_for_ES7_async_functions: diag(6068, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_async_functions_6068", "Enables experimental support for ES7 async functions."),
        Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6: diag(6069, ts.DiagnosticCategory.Message, "Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6_6069", "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)."),
        Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: diag(6070, ts.DiagnosticCategory.Message, "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070", "Initializes a TypeScript project and creates a tsconfig.json file."),
        Successfully_created_a_tsconfig_json_file: diag(6071, ts.DiagnosticCategory.Message, "Successfully_created_a_tsconfig_json_file_6071", "Successfully created a tsconfig.json file."),
        Suppress_excess_property_checks_for_object_literals: diag(6072, ts.DiagnosticCategory.Message, "Suppress_excess_property_checks_for_object_literals_6072", "Suppress excess property checks for object literals."),
        Stylize_errors_and_messages_using_color_and_context_experimental: diag(6073, ts.DiagnosticCategory.Message, "Stylize_errors_and_messages_using_color_and_context_experimental_6073", "Stylize errors and messages using color and context (experimental)."),
        Do_not_report_errors_on_unused_labels: diag(6074, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unused_labels_6074", "Do not report errors on unused labels."),
        Report_error_when_not_all_code_paths_in_function_return_a_value: diag(6075, ts.DiagnosticCategory.Message, "Report_error_when_not_all_code_paths_in_function_return_a_value_6075", "Report error when not all code paths in function return a value."),
        Report_errors_for_fallthrough_cases_in_switch_statement: diag(6076, ts.DiagnosticCategory.Message, "Report_errors_for_fallthrough_cases_in_switch_statement_6076", "Report errors for fallthrough cases in switch statement."),
        Do_not_report_errors_on_unreachable_code: diag(6077, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unreachable_code_6077", "Do not report errors on unreachable code."),
        Disallow_inconsistently_cased_references_to_the_same_file: diag(6078, ts.DiagnosticCategory.Message, "Disallow_inconsistently_cased_references_to_the_same_file_6078", "Disallow inconsistently-cased references to the same file."),
        Specify_library_files_to_be_included_in_the_compilation: diag(6079, ts.DiagnosticCategory.Message, "Specify_library_files_to_be_included_in_the_compilation_6079", "Specify library files to be included in the compilation."),
        Specify_JSX_code_generation_Colon_preserve_react_native_or_react: diag(6080, ts.DiagnosticCategory.Message, "Specify_JSX_code_generation_Colon_preserve_react_native_or_react_6080", "Specify JSX code generation: 'preserve', 'react-native', or 'react'."),
        File_0_has_an_unsupported_extension_so_skipping_it: diag(6081, ts.DiagnosticCategory.Message, "File_0_has_an_unsupported_extension_so_skipping_it_6081", "File '{0}' has an unsupported extension, so skipping it."),
        Only_amd_and_system_modules_are_supported_alongside_0: diag(6082, ts.DiagnosticCategory.Error, "Only_amd_and_system_modules_are_supported_alongside_0_6082", "Only 'amd' and 'system' modules are supported alongside --{0}."),
        Base_directory_to_resolve_non_absolute_module_names: diag(6083, ts.DiagnosticCategory.Message, "Base_directory_to_resolve_non_absolute_module_names_6083", "Base directory to resolve non-absolute module names."),
        Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit: diag(6084, ts.DiagnosticCategory.Message, "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084", "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit"),
        Enable_tracing_of_the_name_resolution_process: diag(6085, ts.DiagnosticCategory.Message, "Enable_tracing_of_the_name_resolution_process_6085", "Enable tracing of the name resolution process."),
        Resolving_module_0_from_1: diag(6086, ts.DiagnosticCategory.Message, "Resolving_module_0_from_1_6086", "======== Resolving module '{0}' from '{1}'. ========"),
        Explicitly_specified_module_resolution_kind_Colon_0: diag(6087, ts.DiagnosticCategory.Message, "Explicitly_specified_module_resolution_kind_Colon_0_6087", "Explicitly specified module resolution kind: '{0}'."),
        Module_resolution_kind_is_not_specified_using_0: diag(6088, ts.DiagnosticCategory.Message, "Module_resolution_kind_is_not_specified_using_0_6088", "Module resolution kind is not specified, using '{0}'."),
        Module_name_0_was_successfully_resolved_to_1: diag(6089, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_6089", "======== Module name '{0}' was successfully resolved to '{1}'. ========"),
        Module_name_0_was_not_resolved: diag(6090, ts.DiagnosticCategory.Message, "Module_name_0_was_not_resolved_6090", "======== Module name '{0}' was not resolved. ========"),
        paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0: diag(6091, ts.DiagnosticCategory.Message, "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091", "'paths' option is specified, looking for a pattern to match module name '{0}'."),
        Module_name_0_matched_pattern_1: diag(6092, ts.DiagnosticCategory.Message, "Module_name_0_matched_pattern_1_6092", "Module name '{0}', matched pattern '{1}'."),
        Trying_substitution_0_candidate_module_location_Colon_1: diag(6093, ts.DiagnosticCategory.Message, "Trying_substitution_0_candidate_module_location_Colon_1_6093", "Trying substitution '{0}', candidate module location: '{1}'."),
        Resolving_module_name_0_relative_to_base_url_1_2: diag(6094, ts.DiagnosticCategory.Message, "Resolving_module_name_0_relative_to_base_url_1_2_6094", "Resolving module name '{0}' relative to base url '{1}' - '{2}'."),
        Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1: diag(6095, ts.DiagnosticCategory.Message, "Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1_6095", "Loading module as file / folder, candidate module location '{0}', target file type '{1}'."),
        File_0_does_not_exist: diag(6096, ts.DiagnosticCategory.Message, "File_0_does_not_exist_6096", "File '{0}' does not exist."),
        File_0_exist_use_it_as_a_name_resolution_result: diag(6097, ts.DiagnosticCategory.Message, "File_0_exist_use_it_as_a_name_resolution_result_6097", "File '{0}' exist - use it as a name resolution result."),
        Loading_module_0_from_node_modules_folder_target_file_type_1: diag(6098, ts.DiagnosticCategory.Message, "Loading_module_0_from_node_modules_folder_target_file_type_1_6098", "Loading module '{0}' from 'node_modules' folder, target file type '{1}'."),
        Found_package_json_at_0: diag(6099, ts.DiagnosticCategory.Message, "Found_package_json_at_0_6099", "Found 'package.json' at '{0}'."),
        package_json_does_not_have_a_0_field: diag(6100, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_0_field_6100", "'package.json' does not have a '{0}' field."),
        package_json_has_0_field_1_that_references_2: diag(6101, ts.DiagnosticCategory.Message, "package_json_has_0_field_1_that_references_2_6101", "'package.json' has '{0}' field '{1}' that references '{2}'."),
        Allow_javascript_files_to_be_compiled: diag(6102, ts.DiagnosticCategory.Message, "Allow_javascript_files_to_be_compiled_6102", "Allow javascript files to be compiled."),
        Option_0_should_have_array_of_strings_as_a_value: diag(6103, ts.DiagnosticCategory.Error, "Option_0_should_have_array_of_strings_as_a_value_6103", "Option '{0}' should have array of strings as a value."),
        Checking_if_0_is_the_longest_matching_prefix_for_1_2: diag(6104, ts.DiagnosticCategory.Message, "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104", "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'."),
        Expected_type_of_0_field_in_package_json_to_be_1_got_2: diag(6105, ts.DiagnosticCategory.Message, "Expected_type_of_0_field_in_package_json_to_be_1_got_2_6105", "Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'."),
        baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1: diag(6106, ts.DiagnosticCategory.Message, "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106", "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'."),
        rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0: diag(6107, ts.DiagnosticCategory.Message, "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107", "'rootDirs' option is set, using it to resolve relative module name '{0}'."),
        Longest_matching_prefix_for_0_is_1: diag(6108, ts.DiagnosticCategory.Message, "Longest_matching_prefix_for_0_is_1_6108", "Longest matching prefix for '{0}' is '{1}'."),
        Loading_0_from_the_root_dir_1_candidate_location_2: diag(6109, ts.DiagnosticCategory.Message, "Loading_0_from_the_root_dir_1_candidate_location_2_6109", "Loading '{0}' from the root dir '{1}', candidate location '{2}'."),
        Trying_other_entries_in_rootDirs: diag(6110, ts.DiagnosticCategory.Message, "Trying_other_entries_in_rootDirs_6110", "Trying other entries in 'rootDirs'."),
        Module_resolution_using_rootDirs_has_failed: diag(6111, ts.DiagnosticCategory.Message, "Module_resolution_using_rootDirs_has_failed_6111", "Module resolution using 'rootDirs' has failed."),
        Do_not_emit_use_strict_directives_in_module_output: diag(6112, ts.DiagnosticCategory.Message, "Do_not_emit_use_strict_directives_in_module_output_6112", "Do not emit 'use strict' directives in module output."),
        Enable_strict_null_checks: diag(6113, ts.DiagnosticCategory.Message, "Enable_strict_null_checks_6113", "Enable strict null checks."),
        Unknown_option_excludes_Did_you_mean_exclude: diag(6114, ts.DiagnosticCategory.Error, "Unknown_option_excludes_Did_you_mean_exclude_6114", "Unknown option 'excludes'. Did you mean 'exclude'?"),
        Raise_error_on_this_expressions_with_an_implied_any_type: diag(6115, ts.DiagnosticCategory.Message, "Raise_error_on_this_expressions_with_an_implied_any_type_6115", "Raise error on 'this' expressions with an implied 'any' type."),
        Resolving_type_reference_directive_0_containing_file_1_root_directory_2: diag(6116, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116", "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========"),
        Resolving_using_primary_search_paths: diag(6117, ts.DiagnosticCategory.Message, "Resolving_using_primary_search_paths_6117", "Resolving using primary search paths..."),
        Resolving_from_node_modules_folder: diag(6118, ts.DiagnosticCategory.Message, "Resolving_from_node_modules_folder_6118", "Resolving from node_modules folder..."),
        Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2: diag(6119, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119", "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========"),
        Type_reference_directive_0_was_not_resolved: diag(6120, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_not_resolved_6120", "======== Type reference directive '{0}' was not resolved. ========"),
        Resolving_with_primary_search_path_0: diag(6121, ts.DiagnosticCategory.Message, "Resolving_with_primary_search_path_0_6121", "Resolving with primary search path '{0}'."),
        Root_directory_cannot_be_determined_skipping_primary_search_paths: diag(6122, ts.DiagnosticCategory.Message, "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122", "Root directory cannot be determined, skipping primary search paths."),
        Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set: diag(6123, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123", "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========"),
        Type_declaration_files_to_be_included_in_compilation: diag(6124, ts.DiagnosticCategory.Message, "Type_declaration_files_to_be_included_in_compilation_6124", "Type declaration files to be included in compilation."),
        Looking_up_in_node_modules_folder_initial_location_0: diag(6125, ts.DiagnosticCategory.Message, "Looking_up_in_node_modules_folder_initial_location_0_6125", "Looking up in 'node_modules' folder, initial location '{0}'."),
        Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder: diag(6126, ts.DiagnosticCategory.Message, "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126", "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder."),
        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1: diag(6127, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127", "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========"),
        Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: diag(6128, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========"),
        Resolving_real_path_for_0_result_1: diag(6130, ts.DiagnosticCategory.Message, "Resolving_real_path_for_0_result_1_6130", "Resolving real path for '{0}', result '{1}'."),
        Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: diag(6131, ts.DiagnosticCategory.Error, "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'."),
        File_name_0_has_a_1_extension_stripping_it: diag(6132, ts.DiagnosticCategory.Message, "File_name_0_has_a_1_extension_stripping_it_6132", "File name '{0}' has a '{1}' extension - stripping it."),
        _0_is_declared_but_its_value_is_never_read: diag(6133, ts.DiagnosticCategory.Error, "_0_is_declared_but_its_value_is_never_read_6133", "'{0}' is declared but its value is never read.", /*reportsUnnecessary*/ true),
        Report_errors_on_unused_locals: diag(6134, ts.DiagnosticCategory.Message, "Report_errors_on_unused_locals_6134", "Report errors on unused locals."),
        Report_errors_on_unused_parameters: diag(6135, ts.DiagnosticCategory.Message, "Report_errors_on_unused_parameters_6135", "Report errors on unused parameters."),
        The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: diag(6136, ts.DiagnosticCategory.Message, "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", "The maximum dependency depth to search under node_modules and load JavaScript files."),
        Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1: diag(6137, ts.DiagnosticCategory.Error, "Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1_6137", "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'."),
        Property_0_is_declared_but_its_value_is_never_read: diag(6138, ts.DiagnosticCategory.Error, "Property_0_is_declared_but_its_value_is_never_read_6138", "Property '{0}' is declared but its value is never read.", /*reportsUnnecessary*/ true),
        Import_emit_helpers_from_tslib: diag(6139, ts.DiagnosticCategory.Message, "Import_emit_helpers_from_tslib_6139", "Import emit helpers from 'tslib'."),
        Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2: diag(6140, ts.DiagnosticCategory.Error, "Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using__6140", "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'."),
        Parse_in_strict_mode_and_emit_use_strict_for_each_source_file: diag(6141, ts.DiagnosticCategory.Message, "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141", "Parse in strict mode and emit \"use strict\" for each source file."),
        Module_0_was_resolved_to_1_but_jsx_is_not_set: diag(6142, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_jsx_is_not_set_6142", "Module '{0}' was resolved to '{1}', but '--jsx' is not set."),
        Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1: diag(6144, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1_6144", "Module '{0}' was resolved as locally declared ambient module in file '{1}'."),
        Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified: diag(6145, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified_6145", "Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified."),
        Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h: diag(6146, ts.DiagnosticCategory.Message, "Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h_6146", "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'."),
        Resolution_for_module_0_was_found_in_cache_from_location_1: diag(6147, ts.DiagnosticCategory.Message, "Resolution_for_module_0_was_found_in_cache_from_location_1_6147", "Resolution for module '{0}' was found in cache from location '{1}'."),
        Directory_0_does_not_exist_skipping_all_lookups_in_it: diag(6148, ts.DiagnosticCategory.Message, "Directory_0_does_not_exist_skipping_all_lookups_in_it_6148", "Directory '{0}' does not exist, skipping all lookups in it."),
        Show_diagnostic_information: diag(6149, ts.DiagnosticCategory.Message, "Show_diagnostic_information_6149", "Show diagnostic information."),
        Show_verbose_diagnostic_information: diag(6150, ts.DiagnosticCategory.Message, "Show_verbose_diagnostic_information_6150", "Show verbose diagnostic information."),
        Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file: diag(6151, ts.DiagnosticCategory.Message, "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151", "Emit a single file with source maps instead of having a separate file."),
        Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set: diag(6152, ts.DiagnosticCategory.Message, "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152", "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set."),
        Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule: diag(6153, ts.DiagnosticCategory.Message, "Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153", "Transpile each file as a separate module (similar to 'ts.transpileModule')."),
        Print_names_of_generated_files_part_of_the_compilation: diag(6154, ts.DiagnosticCategory.Message, "Print_names_of_generated_files_part_of_the_compilation_6154", "Print names of generated files part of the compilation."),
        Print_names_of_files_part_of_the_compilation: diag(6155, ts.DiagnosticCategory.Message, "Print_names_of_files_part_of_the_compilation_6155", "Print names of files part of the compilation."),
        The_locale_used_when_displaying_messages_to_the_user_e_g_en_us: diag(6156, ts.DiagnosticCategory.Message, "The_locale_used_when_displaying_messages_to_the_user_e_g_en_us_6156", "The locale used when displaying messages to the user (e.g. 'en-us')"),
        Do_not_generate_custom_helper_functions_like_extends_in_compiled_output: diag(6157, ts.DiagnosticCategory.Message, "Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157", "Do not generate custom helper functions like '__extends' in compiled output."),
        Do_not_include_the_default_library_file_lib_d_ts: diag(6158, ts.DiagnosticCategory.Message, "Do_not_include_the_default_library_file_lib_d_ts_6158", "Do not include the default library file (lib.d.ts)."),
        Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files: diag(6159, ts.DiagnosticCategory.Message, "Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files_6159", "Do not add triple-slash references or imported modules to the list of compiled files."),
        Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files: diag(6160, ts.DiagnosticCategory.Message, "Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160", "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files."),
        List_of_folders_to_include_type_definitions_from: diag(6161, ts.DiagnosticCategory.Message, "List_of_folders_to_include_type_definitions_from_6161", "List of folders to include type definitions from."),
        Disable_size_limitations_on_JavaScript_projects: diag(6162, ts.DiagnosticCategory.Message, "Disable_size_limitations_on_JavaScript_projects_6162", "Disable size limitations on JavaScript projects."),
        The_character_set_of_the_input_files: diag(6163, ts.DiagnosticCategory.Message, "The_character_set_of_the_input_files_6163", "The character set of the input files."),
        Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files: diag(6164, ts.DiagnosticCategory.Message, "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164", "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files."),
        Do_not_truncate_error_messages: diag(6165, ts.DiagnosticCategory.Message, "Do_not_truncate_error_messages_6165", "Do not truncate error messages."),
        Output_directory_for_generated_declaration_files: diag(6166, ts.DiagnosticCategory.Message, "Output_directory_for_generated_declaration_files_6166", "Output directory for generated declaration files."),
        A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl: diag(6167, ts.DiagnosticCategory.Message, "A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167", "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'."),
        List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime: diag(6168, ts.DiagnosticCategory.Message, "List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime_6168", "List of root folders whose combined content represents the structure of the project at runtime."),
        Show_all_compiler_options: diag(6169, ts.DiagnosticCategory.Message, "Show_all_compiler_options_6169", "Show all compiler options."),
        Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file: diag(6170, ts.DiagnosticCategory.Message, "Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170", "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file"),
        Command_line_Options: diag(6171, ts.DiagnosticCategory.Message, "Command_line_Options_6171", "Command-line Options"),
        Basic_Options: diag(6172, ts.DiagnosticCategory.Message, "Basic_Options_6172", "Basic Options"),
        Strict_Type_Checking_Options: diag(6173, ts.DiagnosticCategory.Message, "Strict_Type_Checking_Options_6173", "Strict Type-Checking Options"),
        Module_Resolution_Options: diag(6174, ts.DiagnosticCategory.Message, "Module_Resolution_Options_6174", "Module Resolution Options"),
        Source_Map_Options: diag(6175, ts.DiagnosticCategory.Message, "Source_Map_Options_6175", "Source Map Options"),
        Additional_Checks: diag(6176, ts.DiagnosticCategory.Message, "Additional_Checks_6176", "Additional Checks"),
        Experimental_Options: diag(6177, ts.DiagnosticCategory.Message, "Experimental_Options_6177", "Experimental Options"),
        Advanced_Options: diag(6178, ts.DiagnosticCategory.Message, "Advanced_Options_6178", "Advanced Options"),
        Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3: diag(6179, ts.DiagnosticCategory.Message, "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3_6179", "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'."),
        Enable_all_strict_type_checking_options: diag(6180, ts.DiagnosticCategory.Message, "Enable_all_strict_type_checking_options_6180", "Enable all strict type-checking options."),
        List_of_language_service_plugins: diag(6181, ts.DiagnosticCategory.Message, "List_of_language_service_plugins_6181", "List of language service plugins."),
        Scoped_package_detected_looking_in_0: diag(6182, ts.DiagnosticCategory.Message, "Scoped_package_detected_looking_in_0_6182", "Scoped package detected, looking in '{0}'"),
        Reusing_resolution_of_module_0_to_file_1_from_old_program: diag(6183, ts.DiagnosticCategory.Message, "Reusing_resolution_of_module_0_to_file_1_from_old_program_6183", "Reusing resolution of module '{0}' to file '{1}' from old program."),
        Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program: diag(6184, ts.DiagnosticCategory.Message, "Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program_6184", "Reusing module resolutions originating in '{0}' since resolutions are unchanged from old program."),
        Disable_strict_checking_of_generic_signatures_in_function_types: diag(6185, ts.DiagnosticCategory.Message, "Disable_strict_checking_of_generic_signatures_in_function_types_6185", "Disable strict checking of generic signatures in function types."),
        Enable_strict_checking_of_function_types: diag(6186, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_function_types_6186", "Enable strict checking of function types."),
        Enable_strict_checking_of_property_initialization_in_classes: diag(6187, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_property_initialization_in_classes_6187", "Enable strict checking of property initialization in classes."),
        Numeric_separators_are_not_allowed_here: diag(6188, ts.DiagnosticCategory.Error, "Numeric_separators_are_not_allowed_here_6188", "Numeric separators are not allowed here."),
        Multiple_consecutive_numeric_separators_are_not_permitted: diag(6189, ts.DiagnosticCategory.Error, "Multiple_consecutive_numeric_separators_are_not_permitted_6189", "Multiple consecutive numeric separators are not permitted."),
        Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen: diag(6191, ts.DiagnosticCategory.Message, "Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen_6191", "Whether to keep outdated console output in watch mode instead of clearing the screen."),
        All_imports_in_import_declaration_are_unused: diag(6192, ts.DiagnosticCategory.Error, "All_imports_in_import_declaration_are_unused_6192", "All imports in import declaration are unused.", /*reportsUnnecessary*/ true),
        Found_1_error_Watching_for_file_changes: diag(6193, ts.DiagnosticCategory.Message, "Found_1_error_Watching_for_file_changes_6193", "Found 1 error. Watching for file changes."),
        Found_0_errors_Watching_for_file_changes: diag(6194, ts.DiagnosticCategory.Message, "Found_0_errors_Watching_for_file_changes_6194", "Found {0} errors. Watching for file changes."),
        Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols: diag(6195, ts.DiagnosticCategory.Message, "Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195", "Resolve 'keyof' to string valued property names only (no numbers or symbols)."),
        _0_is_declared_but_never_used: diag(6196, ts.DiagnosticCategory.Error, "_0_is_declared_but_never_used_6196", "'{0}' is declared but never used.", /*reportsUnnecessary*/ true),
        Include_modules_imported_with_json_extension: diag(6197, ts.DiagnosticCategory.Message, "Include_modules_imported_with_json_extension_6197", "Include modules imported with '.json' extension"),
        All_destructured_elements_are_unused: diag(6198, ts.DiagnosticCategory.Error, "All_destructured_elements_are_unused_6198", "All destructured elements are unused.", /*reportsUnnecessary*/ true),
        All_variables_are_unused: diag(6199, ts.DiagnosticCategory.Error, "All_variables_are_unused_6199", "All variables are unused.", /*reportsUnnecessary*/ true),
        Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0: diag(6200, ts.DiagnosticCategory.Error, "Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0_6200", "Definitions of the following identifiers conflict with those in another file: {0}"),
        Conflicts_are_in_this_file: diag(6201, ts.DiagnosticCategory.Message, "Conflicts_are_in_this_file_6201", "Conflicts are in this file."),
        Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0: diag(6202, ts.DiagnosticCategory.Error, "Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0_6202", "Project references may not form a circular graph. Cycle detected: {0}"),
        _0_was_also_declared_here: diag(6203, ts.DiagnosticCategory.Message, "_0_was_also_declared_here_6203", "'{0}' was also declared here."),
        and_here: diag(6204, ts.DiagnosticCategory.Message, "and_here_6204", "and here."),
        All_type_parameters_are_unused: diag(6205, ts.DiagnosticCategory.Error, "All_type_parameters_are_unused_6205", "All type parameters are unused"),
        package_json_has_a_typesVersions_field_with_version_specific_path_mappings: diag(6206, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_field_with_version_specific_path_mappings_6206", "'package.json' has a 'typesVersions' field with version-specific path mappings."),
        package_json_does_not_have_a_typesVersions_entry_that_matches_version_0: diag(6207, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_typesVersions_entry_that_matches_version_0_6207", "'package.json' does not have a 'typesVersions' entry that matches version '{0}'."),
        package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2: diag(6208, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_ma_6208", "'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'."),
        package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range: diag(6209, ts.DiagnosticCategory.Message, "package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range_6209", "'package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range."),
        An_argument_for_0_was_not_provided: diag(6210, ts.DiagnosticCategory.Message, "An_argument_for_0_was_not_provided_6210", "An argument for '{0}' was not provided."),
        An_argument_matching_this_binding_pattern_was_not_provided: diag(6211, ts.DiagnosticCategory.Message, "An_argument_matching_this_binding_pattern_was_not_provided_6211", "An argument matching this binding pattern was not provided."),
        Did_you_mean_to_call_this_expression: diag(6212, ts.DiagnosticCategory.Message, "Did_you_mean_to_call_this_expression_6212", "Did you mean to call this expression?"),
        Did_you_mean_to_use_new_with_this_expression: diag(6213, ts.DiagnosticCategory.Message, "Did_you_mean_to_use_new_with_this_expression_6213", "Did you mean to use 'new' with this expression?"),
        Enable_strict_bind_call_and_apply_methods_on_functions: diag(6214, ts.DiagnosticCategory.Message, "Enable_strict_bind_call_and_apply_methods_on_functions_6214", "Enable strict 'bind', 'call', and 'apply' methods on functions."),
        Using_compiler_options_of_project_reference_redirect_0: diag(6215, ts.DiagnosticCategory.Message, "Using_compiler_options_of_project_reference_redirect_0_6215", "Using compiler options of project reference redirect '{0}'."),
        Found_1_error: diag(6216, ts.DiagnosticCategory.Message, "Found_1_error_6216", "Found 1 error."),
        Found_0_errors: diag(6217, ts.DiagnosticCategory.Message, "Found_0_errors_6217", "Found {0} errors."),
        Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2: diag(6218, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2_6218", "======== Module name '{0}' was successfully resolved to '{1}' with Package ID '{2}'. ========"),
        Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3: diag(6219, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3_6219", "======== Type reference directive '{0}' was successfully resolved to '{1}' with Package ID '{2}', primary: {3}. ========"),
        package_json_had_a_falsy_0_field: diag(6220, ts.DiagnosticCategory.Message, "package_json_had_a_falsy_0_field_6220", "'package.json' had a falsy '{0}' field."),
        Disable_use_of_source_files_instead_of_declaration_files_from_referenced_projects: diag(6221, ts.DiagnosticCategory.Message, "Disable_use_of_source_files_instead_of_declaration_files_from_referenced_projects_6221", "Disable use of source files instead of declaration files from referenced projects."),
        Emit_class_fields_with_Define_instead_of_Set: diag(6222, ts.DiagnosticCategory.Message, "Emit_class_fields_with_Define_instead_of_Set_6222", "Emit class fields with Define instead of Set."),
        Generates_a_CPU_profile: diag(6223, ts.DiagnosticCategory.Message, "Generates_a_CPU_profile_6223", "Generates a CPU profile."),
        Disable_solution_searching_for_this_project: diag(6224, ts.DiagnosticCategory.Message, "Disable_solution_searching_for_this_project_6224", "Disable solution searching for this project."),
        Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_DynamicPriorityPolling_UseFsEvents_UseFsEventsOnParentDirectory: diag(6225, ts.DiagnosticCategory.Message, "Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_Dynami_6225", "Specify strategy for watching file: 'FixedPollingInterval' (default), 'PriorityPollingInterval', 'DynamicPriorityPolling', 'UseFsEvents', 'UseFsEventsOnParentDirectory'."),
        Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively_Colon_UseFsEvents_default_FixedPollingInterval_DynamicPriorityPolling: diag(6226, ts.DiagnosticCategory.Message, "Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively__6226", "Specify strategy for watching directory on platforms that don't support recursive watching natively: 'UseFsEvents' (default), 'FixedPollingInterval', 'DynamicPriorityPolling'."),
        Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_FixedInterval_default_PriorityInterval_DynamicPriority: diag(6227, ts.DiagnosticCategory.Message, "Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_6227", "Specify strategy for creating a polling watch when it fails to create using file system events: 'FixedInterval' (default), 'PriorityInterval', 'DynamicPriority'."),
        Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively: diag(6228, ts.DiagnosticCategory.Message, "Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_supp_6228", "Synchronously call callbacks and update the state of directory watchers on platforms that don't support recursive watching natively."),
        Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3: diag(6229, ts.DiagnosticCategory.Error, "Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3_6229", "Tag '{0}' expects at least '{1}' arguments, but the JSX factory '{2}' provides at most '{3}'."),
        Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line: diag(6230, ts.DiagnosticCategory.Error, "Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line_6230", "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'false' or 'null' on command line."),
        Could_not_resolve_the_path_0_with_the_extensions_Colon_1: diag(6231, ts.DiagnosticCategory.Error, "Could_not_resolve_the_path_0_with_the_extensions_Colon_1_6231", "Could not resolve the path '{0}' with the extensions: {1}."),
        Declaration_augments_declaration_in_another_file_This_cannot_be_serialized: diag(6232, ts.DiagnosticCategory.Error, "Declaration_augments_declaration_in_another_file_This_cannot_be_serialized_6232", "Declaration augments declaration in another file. This cannot be serialized."),
        This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file: diag(6233, ts.DiagnosticCategory.Error, "This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_fil_6233", "This is the declaration being augmented. Consider moving the augmenting declaration into the same file."),
        Projects_to_reference: diag(6300, ts.DiagnosticCategory.Message, "Projects_to_reference_6300", "Projects to reference"),
        Enable_project_compilation: diag(6302, ts.DiagnosticCategory.Message, "Enable_project_compilation_6302", "Enable project compilation"),
        Composite_projects_may_not_disable_declaration_emit: diag(6304, ts.DiagnosticCategory.Error, "Composite_projects_may_not_disable_declaration_emit_6304", "Composite projects may not disable declaration emit."),
        Output_file_0_has_not_been_built_from_source_file_1: diag(6305, ts.DiagnosticCategory.Error, "Output_file_0_has_not_been_built_from_source_file_1_6305", "Output file '{0}' has not been built from source file '{1}'."),
        Referenced_project_0_must_have_setting_composite_Colon_true: diag(6306, ts.DiagnosticCategory.Error, "Referenced_project_0_must_have_setting_composite_Colon_true_6306", "Referenced project '{0}' must have setting \"composite\": true."),
        File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern: diag(6307, ts.DiagnosticCategory.Error, "File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_includ_6307", "File '{0}' is not listed within the file list of project '{1}'. Projects must list all files or use an 'include' pattern."),
        Cannot_prepend_project_0_because_it_does_not_have_outFile_set: diag(6308, ts.DiagnosticCategory.Error, "Cannot_prepend_project_0_because_it_does_not_have_outFile_set_6308", "Cannot prepend project '{0}' because it does not have 'outFile' set"),
        Output_file_0_from_project_1_does_not_exist: diag(6309, ts.DiagnosticCategory.Error, "Output_file_0_from_project_1_does_not_exist_6309", "Output file '{0}' from project '{1}' does not exist"),
        Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2: diag(6350, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2_6350", "Project '{0}' is out of date because oldest output '{1}' is older than newest input '{2}'"),
        Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2: diag(6351, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2_6351", "Project '{0}' is up to date because newest input '{1}' is older than oldest output '{2}'"),
        Project_0_is_out_of_date_because_output_file_1_does_not_exist: diag(6352, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_file_1_does_not_exist_6352", "Project '{0}' is out of date because output file '{1}' does not exist"),
        Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date: diag(6353, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date_6353", "Project '{0}' is out of date because its dependency '{1}' is out of date"),
        Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies: diag(6354, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies_6354", "Project '{0}' is up to date with .d.ts files from its dependencies"),
        Projects_in_this_build_Colon_0: diag(6355, ts.DiagnosticCategory.Message, "Projects_in_this_build_Colon_0_6355", "Projects in this build: {0}"),
        A_non_dry_build_would_delete_the_following_files_Colon_0: diag(6356, ts.DiagnosticCategory.Message, "A_non_dry_build_would_delete_the_following_files_Colon_0_6356", "A non-dry build would delete the following files: {0}"),
        A_non_dry_build_would_build_project_0: diag(6357, ts.DiagnosticCategory.Message, "A_non_dry_build_would_build_project_0_6357", "A non-dry build would build project '{0}'"),
        Building_project_0: diag(6358, ts.DiagnosticCategory.Message, "Building_project_0_6358", "Building project '{0}'..."),
        Updating_output_timestamps_of_project_0: diag(6359, ts.DiagnosticCategory.Message, "Updating_output_timestamps_of_project_0_6359", "Updating output timestamps of project '{0}'..."),
        delete_this_Project_0_is_up_to_date_because_it_was_previously_built: diag(6360, ts.DiagnosticCategory.Message, "delete_this_Project_0_is_up_to_date_because_it_was_previously_built_6360", "delete this - Project '{0}' is up to date because it was previously built"),
        Project_0_is_up_to_date: diag(6361, ts.DiagnosticCategory.Message, "Project_0_is_up_to_date_6361", "Project '{0}' is up to date"),
        Skipping_build_of_project_0_because_its_dependency_1_has_errors: diag(6362, ts.DiagnosticCategory.Message, "Skipping_build_of_project_0_because_its_dependency_1_has_errors_6362", "Skipping build of project '{0}' because its dependency '{1}' has errors"),
        Project_0_can_t_be_built_because_its_dependency_1_has_errors: diag(6363, ts.DiagnosticCategory.Message, "Project_0_can_t_be_built_because_its_dependency_1_has_errors_6363", "Project '{0}' can't be built because its dependency '{1}' has errors"),
        Build_one_or_more_projects_and_their_dependencies_if_out_of_date: diag(6364, ts.DiagnosticCategory.Message, "Build_one_or_more_projects_and_their_dependencies_if_out_of_date_6364", "Build one or more projects and their dependencies, if out of date"),
        Delete_the_outputs_of_all_projects: diag(6365, ts.DiagnosticCategory.Message, "Delete_the_outputs_of_all_projects_6365", "Delete the outputs of all projects"),
        Enable_verbose_logging: diag(6366, ts.DiagnosticCategory.Message, "Enable_verbose_logging_6366", "Enable verbose logging"),
        Show_what_would_be_built_or_deleted_if_specified_with_clean: diag(6367, ts.DiagnosticCategory.Message, "Show_what_would_be_built_or_deleted_if_specified_with_clean_6367", "Show what would be built (or deleted, if specified with '--clean')"),
        Build_all_projects_including_those_that_appear_to_be_up_to_date: diag(6368, ts.DiagnosticCategory.Message, "Build_all_projects_including_those_that_appear_to_be_up_to_date_6368", "Build all projects, including those that appear to be up to date"),
        Option_build_must_be_the_first_command_line_argument: diag(6369, ts.DiagnosticCategory.Error, "Option_build_must_be_the_first_command_line_argument_6369", "Option '--build' must be the first command line argument."),
        Options_0_and_1_cannot_be_combined: diag(6370, ts.DiagnosticCategory.Error, "Options_0_and_1_cannot_be_combined_6370", "Options '{0}' and '{1}' cannot be combined."),
        Updating_unchanged_output_timestamps_of_project_0: diag(6371, ts.DiagnosticCategory.Message, "Updating_unchanged_output_timestamps_of_project_0_6371", "Updating unchanged output timestamps of project '{0}'..."),
        Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed: diag(6372, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed_6372", "Project '{0}' is out of date because output of its dependency '{1}' has changed"),
        Updating_output_of_project_0: diag(6373, ts.DiagnosticCategory.Message, "Updating_output_of_project_0_6373", "Updating output of project '{0}'..."),
        A_non_dry_build_would_update_timestamps_for_output_of_project_0: diag(6374, ts.DiagnosticCategory.Message, "A_non_dry_build_would_update_timestamps_for_output_of_project_0_6374", "A non-dry build would update timestamps for output of project '{0}'"),
        A_non_dry_build_would_update_output_of_project_0: diag(6375, ts.DiagnosticCategory.Message, "A_non_dry_build_would_update_output_of_project_0_6375", "A non-dry build would update output of project '{0}'"),
        Cannot_update_output_of_project_0_because_there_was_error_reading_file_1: diag(6376, ts.DiagnosticCategory.Message, "Cannot_update_output_of_project_0_because_there_was_error_reading_file_1_6376", "Cannot update output of project '{0}' because there was error reading file '{1}'"),
        Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1: diag(6377, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1_6377", "Cannot write file '{0}' because it will overwrite '.tsbuildinfo' file generated by referenced project '{1}'"),
        Enable_incremental_compilation: diag(6378, ts.DiagnosticCategory.Message, "Enable_incremental_compilation_6378", "Enable incremental compilation"),
        Composite_projects_may_not_disable_incremental_compilation: diag(6379, ts.DiagnosticCategory.Error, "Composite_projects_may_not_disable_incremental_compilation_6379", "Composite projects may not disable incremental compilation."),
        Specify_file_to_store_incremental_compilation_information: diag(6380, ts.DiagnosticCategory.Message, "Specify_file_to_store_incremental_compilation_information_6380", "Specify file to store incremental compilation information"),
        Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2: diag(6381, ts.DiagnosticCategory.Message, "Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_curren_6381", "Project '{0}' is out of date because output for it was generated with version '{1}' that differs with current version '{2}'"),
        Skipping_build_of_project_0_because_its_dependency_1_was_not_built: diag(6382, ts.DiagnosticCategory.Message, "Skipping_build_of_project_0_because_its_dependency_1_was_not_built_6382", "Skipping build of project '{0}' because its dependency '{1}' was not built"),
        Project_0_can_t_be_built_because_its_dependency_1_was_not_built: diag(6383, ts.DiagnosticCategory.Message, "Project_0_can_t_be_built_because_its_dependency_1_was_not_built_6383", "Project '{0}' can't be built because its dependency '{1}' was not built"),
        Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it: diag(6384, ts.DiagnosticCategory.Message, "Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_di_6384", "Have recompiles in '--incremental' and '--watch' assume that changes within a file will only affect files directly depending on it."),
        The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1: diag(6500, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1_6500", "The expected type comes from property '{0}' which is declared here on type '{1}'"),
        The_expected_type_comes_from_this_index_signature: diag(6501, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_this_index_signature_6501", "The expected type comes from this index signature."),
        The_expected_type_comes_from_the_return_type_of_this_signature: diag(6502, ts.DiagnosticCategory.Message, "The_expected_type_comes_from_the_return_type_of_this_signature_6502", "The expected type comes from the return type of this signature."),
        Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing: diag(6503, ts.DiagnosticCategory.Message, "Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing_6503", "Print names of files that are part of the compilation and then stop processing."),
        File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option: diag(6504, ts.DiagnosticCategory.Error, "File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option_6504", "File '{0}' is a JavaScript file. Did you mean to enable the 'allowJs' option?"),
        Variable_0_implicitly_has_an_1_type: diag(7005, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_an_1_type_7005", "Variable '{0}' implicitly has an '{1}' type."),
        Parameter_0_implicitly_has_an_1_type: diag(7006, ts.DiagnosticCategory.Error, "Parameter_0_implicitly_has_an_1_type_7006", "Parameter '{0}' implicitly has an '{1}' type."),
        Member_0_implicitly_has_an_1_type: diag(7008, ts.DiagnosticCategory.Error, "Member_0_implicitly_has_an_1_type_7008", "Member '{0}' implicitly has an '{1}' type."),
        new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: diag(7009, ts.DiagnosticCategory.Error, "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009", "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type."),
        _0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: diag(7010, ts.DiagnosticCategory.Error, "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010", "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type."),
        Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7011, ts.DiagnosticCategory.Error, "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011", "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type."),
        Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7013, ts.DiagnosticCategory.Error, "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013", "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type."),
        Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7014, ts.DiagnosticCategory.Error, "Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7014", "Function type, which lacks return-type annotation, implicitly has an '{0}' return type."),
        Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number: diag(7015, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015", "Element implicitly has an 'any' type because index expression is not of type 'number'."),
        Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type: diag(7016, ts.DiagnosticCategory.Error, "Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type_7016", "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type."),
        Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature: diag(7017, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017", "Element implicitly has an 'any' type because type '{0}' has no index signature."),
        Object_literal_s_property_0_implicitly_has_an_1_type: diag(7018, ts.DiagnosticCategory.Error, "Object_literal_s_property_0_implicitly_has_an_1_type_7018", "Object literal's property '{0}' implicitly has an '{1}' type."),
        Rest_parameter_0_implicitly_has_an_any_type: diag(7019, ts.DiagnosticCategory.Error, "Rest_parameter_0_implicitly_has_an_any_type_7019", "Rest parameter '{0}' implicitly has an 'any[]' type."),
        Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7020, ts.DiagnosticCategory.Error, "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020", "Call signature, which lacks return-type annotation, implicitly has an 'any' return type."),
        _0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: diag(7022, ts.DiagnosticCategory.Error, "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022", "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer."),
        _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7023, ts.DiagnosticCategory.Error, "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023", "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
        Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7024, ts.DiagnosticCategory.Error, "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024", "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."),
        Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type_annotation: diag(7025, ts.DiagnosticCategory.Error, "Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_retu_7025", "Generator implicitly has yield type '{0}' because it does not yield any values. Consider supplying a return type annotation."),
        JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: diag(7026, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026", "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists."),
        Unreachable_code_detected: diag(7027, ts.DiagnosticCategory.Error, "Unreachable_code_detected_7027", "Unreachable code detected.", /*reportsUnnecessary*/ true),
        Unused_label: diag(7028, ts.DiagnosticCategory.Error, "Unused_label_7028", "Unused label.", /*reportsUnnecessary*/ true),
        Fallthrough_case_in_switch: diag(7029, ts.DiagnosticCategory.Error, "Fallthrough_case_in_switch_7029", "Fallthrough case in switch."),
        Not_all_code_paths_return_a_value: diag(7030, ts.DiagnosticCategory.Error, "Not_all_code_paths_return_a_value_7030", "Not all code paths return a value."),
        Binding_element_0_implicitly_has_an_1_type: diag(7031, ts.DiagnosticCategory.Error, "Binding_element_0_implicitly_has_an_1_type_7031", "Binding element '{0}' implicitly has an '{1}' type."),
        Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation: diag(7032, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation_7032", "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation."),
        Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation: diag(7033, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation_7033", "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation."),
        Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined: diag(7034, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034", "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined."),
        Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0: diag(7035, ts.DiagnosticCategory.Error, "Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035", "Try `npm install @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`"),
        Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0: diag(7036, ts.DiagnosticCategory.Error, "Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036", "Dynamic import's specifier must be of type 'string', but here has type '{0}'."),
        Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports: diag(7037, ts.DiagnosticCategory.Message, "Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for__7037", "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'."),
        Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead: diag(7038, ts.DiagnosticCategory.Message, "Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cau_7038", "Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead."),
        Mapped_object_type_implicitly_has_an_any_template_type: diag(7039, ts.DiagnosticCategory.Error, "Mapped_object_type_implicitly_has_an_any_template_type_7039", "Mapped object type implicitly has an 'any' template type."),
        If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1: diag(7040, ts.DiagnosticCategory.Error, "If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_S_7040", "If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}`"),
        The_containing_arrow_function_captures_the_global_value_of_this: diag(7041, ts.DiagnosticCategory.Error, "The_containing_arrow_function_captures_the_global_value_of_this_7041", "The containing arrow function captures the global value of 'this'."),
        Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used: diag(7042, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used_7042", "Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used."),
        Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7043, ts.DiagnosticCategory.Suggestion, "Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7043", "Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7044, ts.DiagnosticCategory.Suggestion, "Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7044", "Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage: diag(7045, ts.DiagnosticCategory.Suggestion, "Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage_7045", "Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage."),
        Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage: diag(7046, ts.DiagnosticCategory.Suggestion, "Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage_7046", "Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage."),
        Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage: diag(7047, ts.DiagnosticCategory.Suggestion, "Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage_7047", "Rest parameter '{0}' implicitly has an 'any[]' type, but a better type may be inferred from usage."),
        Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage: diag(7048, ts.DiagnosticCategory.Suggestion, "Property_0_implicitly_has_type_any_but_a_better_type_for_its_get_accessor_may_be_inferred_from_usage_7048", "Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage."),
        Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage: diag(7049, ts.DiagnosticCategory.Suggestion, "Property_0_implicitly_has_type_any_but_a_better_type_for_its_set_accessor_may_be_inferred_from_usage_7049", "Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage."),
        _0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage: diag(7050, ts.DiagnosticCategory.Suggestion, "_0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage_7050", "'{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage."),
        Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1: diag(7051, ts.DiagnosticCategory.Error, "Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1_7051", "Parameter has a name but no type. Did you mean '{0}: {1}'?"),
        Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1: diag(7052, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1_7052", "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}'?"),
        Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1: diag(7053, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1_7053", "Element implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'."),
        No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1: diag(7054, ts.DiagnosticCategory.Error, "No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1_7054", "No index signature with a parameter of type '{0}' was found on type '{1}'."),
        _0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type: diag(7055, ts.DiagnosticCategory.Error, "_0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type_7055", "'{0}', which lacks return-type annotation, implicitly has an '{1}' yield type."),
        You_cannot_rename_this_element: diag(8000, ts.DiagnosticCategory.Error, "You_cannot_rename_this_element_8000", "You cannot rename this element."),
        You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: diag(8001, ts.DiagnosticCategory.Error, "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001", "You cannot rename elements that are defined in the standard TypeScript library."),
        import_can_only_be_used_in_TypeScript_files: diag(8002, ts.DiagnosticCategory.Error, "import_can_only_be_used_in_TypeScript_files_8002", "'import ... =' can only be used in TypeScript files."),
        export_can_only_be_used_in_TypeScript_files: diag(8003, ts.DiagnosticCategory.Error, "export_can_only_be_used_in_TypeScript_files_8003", "'export =' can only be used in TypeScript files."),
        Type_parameter_declarations_can_only_be_used_in_TypeScript_files: diag(8004, ts.DiagnosticCategory.Error, "Type_parameter_declarations_can_only_be_used_in_TypeScript_files_8004", "Type parameter declarations can only be used in TypeScript files."),
        implements_clauses_can_only_be_used_in_TypeScript_files: diag(8005, ts.DiagnosticCategory.Error, "implements_clauses_can_only_be_used_in_TypeScript_files_8005", "'implements' clauses can only be used in TypeScript files."),
        _0_declarations_can_only_be_used_in_TypeScript_files: diag(8006, ts.DiagnosticCategory.Error, "_0_declarations_can_only_be_used_in_TypeScript_files_8006", "'{0}' declarations can only be used in TypeScript files."),
        Type_aliases_can_only_be_used_in_TypeScript_files: diag(8008, ts.DiagnosticCategory.Error, "Type_aliases_can_only_be_used_in_TypeScript_files_8008", "Type aliases can only be used in TypeScript files."),
        The_0_modifier_can_only_be_used_in_TypeScript_files: diag(8009, ts.DiagnosticCategory.Error, "The_0_modifier_can_only_be_used_in_TypeScript_files_8009", "The '{0}' modifier can only be used in TypeScript files."),
        Type_annotations_can_only_be_used_in_TypeScript_files: diag(8010, ts.DiagnosticCategory.Error, "Type_annotations_can_only_be_used_in_TypeScript_files_8010", "Type annotations can only be used in TypeScript files."),
        Type_arguments_can_only_be_used_in_TypeScript_files: diag(8011, ts.DiagnosticCategory.Error, "Type_arguments_can_only_be_used_in_TypeScript_files_8011", "Type arguments can only be used in TypeScript files."),
        Parameter_modifiers_can_only_be_used_in_TypeScript_files: diag(8012, ts.DiagnosticCategory.Error, "Parameter_modifiers_can_only_be_used_in_TypeScript_files_8012", "Parameter modifiers can only be used in TypeScript files."),
        Non_null_assertions_can_only_be_used_in_TypeScript_files: diag(8013, ts.DiagnosticCategory.Error, "Non_null_assertions_can_only_be_used_in_TypeScript_files_8013", "Non-null assertions can only be used in TypeScript files."),
        Type_assertion_expressions_can_only_be_used_in_TypeScript_files: diag(8016, ts.DiagnosticCategory.Error, "Type_assertion_expressions_can_only_be_used_in_TypeScript_files_8016", "Type assertion expressions can only be used in TypeScript files."),
        Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0: diag(8017, ts.DiagnosticCategory.Error, "Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0_8017", "Octal literal types must use ES2015 syntax. Use the syntax '{0}'."),
        Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0: diag(8018, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0_8018", "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'."),
        Report_errors_in_js_files: diag(8019, ts.DiagnosticCategory.Message, "Report_errors_in_js_files_8019", "Report errors in .js files."),
        JSDoc_types_can_only_be_used_inside_documentation_comments: diag(8020, ts.DiagnosticCategory.Error, "JSDoc_types_can_only_be_used_inside_documentation_comments_8020", "JSDoc types can only be used inside documentation comments."),
        JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags: diag(8021, ts.DiagnosticCategory.Error, "JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021", "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags."),
        JSDoc_0_is_not_attached_to_a_class: diag(8022, ts.DiagnosticCategory.Error, "JSDoc_0_is_not_attached_to_a_class_8022", "JSDoc '@{0}' is not attached to a class."),
        JSDoc_0_1_does_not_match_the_extends_2_clause: diag(8023, ts.DiagnosticCategory.Error, "JSDoc_0_1_does_not_match_the_extends_2_clause_8023", "JSDoc '@{0} {1}' does not match the 'extends {2}' clause."),
        JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name: diag(8024, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name."),
        Class_declarations_cannot_have_more_than_one_augments_or_extends_tag: diag(8025, ts.DiagnosticCategory.Error, "Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025", "Class declarations cannot have more than one `@augments` or `@extends` tag."),
        Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."),
        Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."),
        JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."),
        JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type: diag(8029, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_h_8029", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type."),
        The_type_of_a_function_declaration_must_match_the_function_s_signature: diag(8030, ts.DiagnosticCategory.Error, "The_type_of_a_function_declaration_must_match_the_function_s_signature_8030", "The type of a function declaration must match the function's signature."),
        You_cannot_rename_a_module_via_a_global_import: diag(8031, ts.DiagnosticCategory.Error, "You_cannot_rename_a_module_via_a_global_import_8031", "You cannot rename a module via a global import."),
        Qualified_name_0_is_not_allowed_without_a_leading_param_object_1: diag(8032, ts.DiagnosticCategory.Error, "Qualified_name_0_is_not_allowed_without_a_leading_param_object_1_8032", "Qualified name '{0}' is not allowed without a leading '@param {object} {1}'."),
        Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."),
        class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."),
        Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."),
        Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit: diag(9005, ts.DiagnosticCategory.Error, "Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_9005", "Declaration emit for this file requires using private name '{0}'. An explicit type annotation may unblock declaration emit."),
        Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit: diag(9006, ts.DiagnosticCategory.Error, "Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotati_9006", "Declaration emit for this file requires using private name '{0}' from module '{1}'. An explicit type annotation may unblock declaration emit."),
        JSX_attributes_must_only_be_assigned_a_non_empty_expression: diag(17000, ts.DiagnosticCategory.Error, "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000", "JSX attributes must only be assigned a non-empty 'expression'."),
        JSX_elements_cannot_have_multiple_attributes_with_the_same_name: diag(17001, ts.DiagnosticCategory.Error, "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001", "JSX elements cannot have multiple attributes with the same name."),
        Expected_corresponding_JSX_closing_tag_for_0: diag(17002, ts.DiagnosticCategory.Error, "Expected_corresponding_JSX_closing_tag_for_0_17002", "Expected corresponding JSX closing tag for '{0}'."),
        JSX_attribute_expected: diag(17003, ts.DiagnosticCategory.Error, "JSX_attribute_expected_17003", "JSX attribute expected."),
        Cannot_use_JSX_unless_the_jsx_flag_is_provided: diag(17004, ts.DiagnosticCategory.Error, "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004", "Cannot use JSX unless the '--jsx' flag is provided."),
        A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: diag(17005, ts.DiagnosticCategory.Error, "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005", "A constructor cannot contain a 'super' call when its class extends 'null'."),
        An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17006, ts.DiagnosticCategory.Error, "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006", "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
        A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17007, ts.DiagnosticCategory.Error, "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007", "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."),
        JSX_element_0_has_no_corresponding_closing_tag: diag(17008, ts.DiagnosticCategory.Error, "JSX_element_0_has_no_corresponding_closing_tag_17008", "JSX element '{0}' has no corresponding closing tag."),
        super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class: diag(17009, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009", "'super' must be called before accessing 'this' in the constructor of a derived class."),
        Unknown_type_acquisition_option_0: diag(17010, ts.DiagnosticCategory.Error, "Unknown_type_acquisition_option_0_17010", "Unknown type acquisition option '{0}'."),
        super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class: diag(17011, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class_17011", "'super' must be called before accessing a property of 'super' in the constructor of a derived class."),
        _0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2: diag(17012, ts.DiagnosticCategory.Error, "_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012", "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?"),
        Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor: diag(17013, ts.DiagnosticCategory.Error, "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013", "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor."),
        JSX_fragment_has_no_corresponding_closing_tag: diag(17014, ts.DiagnosticCategory.Error, "JSX_fragment_has_no_corresponding_closing_tag_17014", "JSX fragment has no corresponding closing tag."),
        Expected_corresponding_closing_tag_for_JSX_fragment: diag(17015, ts.DiagnosticCategory.Error, "Expected_corresponding_closing_tag_for_JSX_fragment_17015", "Expected corresponding closing tag for JSX fragment."),
        JSX_fragment_is_not_supported_when_using_jsxFactory: diag(17016, ts.DiagnosticCategory.Error, "JSX_fragment_is_not_supported_when_using_jsxFactory_17016", "JSX fragment is not supported when using --jsxFactory"),
        JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma: diag(17017, ts.DiagnosticCategory.Error, "JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma_17017", "JSX fragment is not supported when using an inline JSX factory pragma"),
        Unknown_type_acquisition_option_0_Did_you_mean_1: diag(17018, ts.DiagnosticCategory.Error, "Unknown_type_acquisition_option_0_Did_you_mean_1_17018", "Unknown type acquisition option '{0}'. Did you mean '{1}'?"),
        Circularity_detected_while_resolving_configuration_Colon_0: diag(18000, ts.DiagnosticCategory.Error, "Circularity_detected_while_resolving_configuration_Colon_0_18000", "Circularity detected while resolving configuration: {0}"),
        A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not: diag(18001, ts.DiagnosticCategory.Error, "A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not_18001", "A path in an 'extends' option must be relative or rooted, but '{0}' is not."),
        The_files_list_in_config_file_0_is_empty: diag(18002, ts.DiagnosticCategory.Error, "The_files_list_in_config_file_0_is_empty_18002", "The 'files' list in config file '{0}' is empty."),
        No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2: diag(18003, ts.DiagnosticCategory.Error, "No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2_18003", "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'."),
        File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module: diag(80001, ts.DiagnosticCategory.Suggestion, "File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module_80001", "File is a CommonJS module; it may be converted to an ES6 module."),
        This_constructor_function_may_be_converted_to_a_class_declaration: diag(80002, ts.DiagnosticCategory.Suggestion, "This_constructor_function_may_be_converted_to_a_class_declaration_80002", "This constructor function may be converted to a class declaration."),
        Import_may_be_converted_to_a_default_import: diag(80003, ts.DiagnosticCategory.Suggestion, "Import_may_be_converted_to_a_default_import_80003", "Import may be converted to a default import."),
        JSDoc_types_may_be_moved_to_TypeScript_types: diag(80004, ts.DiagnosticCategory.Suggestion, "JSDoc_types_may_be_moved_to_TypeScript_types_80004", "JSDoc types may be moved to TypeScript types."),
        require_call_may_be_converted_to_an_import: diag(80005, ts.DiagnosticCategory.Suggestion, "require_call_may_be_converted_to_an_import_80005", "'require' call may be converted to an import."),
        This_may_be_converted_to_an_async_function: diag(80006, ts.DiagnosticCategory.Suggestion, "This_may_be_converted_to_an_async_function_80006", "This may be converted to an async function."),
        await_has_no_effect_on_the_type_of_this_expression: diag(80007, ts.DiagnosticCategory.Suggestion, "await_has_no_effect_on_the_type_of_this_expression_80007", "'await' has no effect on the type of this expression."),
        Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers: diag(80008, ts.DiagnosticCategory.Suggestion, "Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accur_80008", "Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as integers."),
        Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"),
        Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"),
        Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"),
        Remove_unused_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_unused_declaration_for_Colon_0_90004", "Remove unused declaration for: '{0}'"),
        Remove_import_from_0: diag(90005, ts.DiagnosticCategory.Message, "Remove_import_from_0_90005", "Remove import from '{0}'"),
        Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"),
        Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"),
        Add_0_to_unresolved_variable: diag(90008, ts.DiagnosticCategory.Message, "Add_0_to_unresolved_variable_90008", "Add '{0}.' to unresolved variable"),
        Remove_destructuring: diag(90009, ts.DiagnosticCategory.Message, "Remove_destructuring_90009", "Remove destructuring"),
        Remove_variable_statement: diag(90010, ts.DiagnosticCategory.Message, "Remove_variable_statement_90010", "Remove variable statement"),
        Remove_template_tag: diag(90011, ts.DiagnosticCategory.Message, "Remove_template_tag_90011", "Remove template tag"),
        Remove_type_parameters: diag(90012, ts.DiagnosticCategory.Message, "Remove_type_parameters_90012", "Remove type parameters"),
        Import_0_from_module_1: diag(90013, ts.DiagnosticCategory.Message, "Import_0_from_module_1_90013", "Import '{0}' from module \"{1}\""),
        Change_0_to_1: diag(90014, ts.DiagnosticCategory.Message, "Change_0_to_1_90014", "Change '{0}' to '{1}'"),
        Add_0_to_existing_import_declaration_from_1: diag(90015, ts.DiagnosticCategory.Message, "Add_0_to_existing_import_declaration_from_1_90015", "Add '{0}' to existing import declaration from \"{1}\""),
        Declare_property_0: diag(90016, ts.DiagnosticCategory.Message, "Declare_property_0_90016", "Declare property '{0}'"),
        Add_index_signature_for_property_0: diag(90017, ts.DiagnosticCategory.Message, "Add_index_signature_for_property_0_90017", "Add index signature for property '{0}'"),
        Disable_checking_for_this_file: diag(90018, ts.DiagnosticCategory.Message, "Disable_checking_for_this_file_90018", "Disable checking for this file"),
        Ignore_this_error_message: diag(90019, ts.DiagnosticCategory.Message, "Ignore_this_error_message_90019", "Ignore this error message"),
        Initialize_property_0_in_the_constructor: diag(90020, ts.DiagnosticCategory.Message, "Initialize_property_0_in_the_constructor_90020", "Initialize property '{0}' in the constructor"),
        Initialize_static_property_0: diag(90021, ts.DiagnosticCategory.Message, "Initialize_static_property_0_90021", "Initialize static property '{0}'"),
        Change_spelling_to_0: diag(90022, ts.DiagnosticCategory.Message, "Change_spelling_to_0_90022", "Change spelling to '{0}'"),
        Declare_method_0: diag(90023, ts.DiagnosticCategory.Message, "Declare_method_0_90023", "Declare method '{0}'"),
        Declare_static_method_0: diag(90024, ts.DiagnosticCategory.Message, "Declare_static_method_0_90024", "Declare static method '{0}'"),
        Prefix_0_with_an_underscore: diag(90025, ts.DiagnosticCategory.Message, "Prefix_0_with_an_underscore_90025", "Prefix '{0}' with an underscore"),
        Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'"),
        Declare_static_property_0: diag(90027, ts.DiagnosticCategory.Message, "Declare_static_property_0_90027", "Declare static property '{0}'"),
        Call_decorator_expression: diag(90028, ts.DiagnosticCategory.Message, "Call_decorator_expression_90028", "Call decorator expression"),
        Add_async_modifier_to_containing_function: diag(90029, ts.DiagnosticCategory.Message, "Add_async_modifier_to_containing_function_90029", "Add async modifier to containing function"),
        Replace_infer_0_with_unknown: diag(90030, ts.DiagnosticCategory.Message, "Replace_infer_0_with_unknown_90030", "Replace 'infer {0}' with 'unknown'"),
        Replace_all_unused_infer_with_unknown: diag(90031, ts.DiagnosticCategory.Message, "Replace_all_unused_infer_with_unknown_90031", "Replace all unused 'infer' with 'unknown'"),
        Import_default_0_from_module_1: diag(90032, ts.DiagnosticCategory.Message, "Import_default_0_from_module_1_90032", "Import default '{0}' from module \"{1}\""),
        Add_default_import_0_to_existing_import_declaration_from_1: diag(90033, ts.DiagnosticCategory.Message, "Add_default_import_0_to_existing_import_declaration_from_1_90033", "Add default import '{0}' to existing import declaration from \"{1}\""),
        Add_parameter_name: diag(90034, ts.DiagnosticCategory.Message, "Add_parameter_name_90034", "Add parameter name"),
        Declare_private_property_0: diag(90035, ts.DiagnosticCategory.Message, "Declare_private_property_0_90035", "Declare private property '{0}'"),
        Declare_a_private_field_named_0: diag(90053, ts.DiagnosticCategory.Message, "Declare_a_private_field_named_0_90053", "Declare a private field named '{0}'."),
        Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"),
        Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"),
        Extract_to_0_in_1: diag(95004, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_95004", "Extract to {0} in {1}"),
        Extract_function: diag(95005, ts.DiagnosticCategory.Message, "Extract_function_95005", "Extract function"),
        Extract_constant: diag(95006, ts.DiagnosticCategory.Message, "Extract_constant_95006", "Extract constant"),
        Extract_to_0_in_enclosing_scope: diag(95007, ts.DiagnosticCategory.Message, "Extract_to_0_in_enclosing_scope_95007", "Extract to {0} in enclosing scope"),
        Extract_to_0_in_1_scope: diag(95008, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_scope_95008", "Extract to {0} in {1} scope"),
        Annotate_with_type_from_JSDoc: diag(95009, ts.DiagnosticCategory.Message, "Annotate_with_type_from_JSDoc_95009", "Annotate with type from JSDoc"),
        Annotate_with_types_from_JSDoc: diag(95010, ts.DiagnosticCategory.Message, "Annotate_with_types_from_JSDoc_95010", "Annotate with types from JSDoc"),
        Infer_type_of_0_from_usage: diag(95011, ts.DiagnosticCategory.Message, "Infer_type_of_0_from_usage_95011", "Infer type of '{0}' from usage"),
        Infer_parameter_types_from_usage: diag(95012, ts.DiagnosticCategory.Message, "Infer_parameter_types_from_usage_95012", "Infer parameter types from usage"),
        Convert_to_default_import: diag(95013, ts.DiagnosticCategory.Message, "Convert_to_default_import_95013", "Convert to default import"),
        Install_0: diag(95014, ts.DiagnosticCategory.Message, "Install_0_95014", "Install '{0}'"),
        Replace_import_with_0: diag(95015, ts.DiagnosticCategory.Message, "Replace_import_with_0_95015", "Replace import with '{0}'."),
        Use_synthetic_default_member: diag(95016, ts.DiagnosticCategory.Message, "Use_synthetic_default_member_95016", "Use synthetic 'default' member."),
        Convert_to_ES6_module: diag(95017, ts.DiagnosticCategory.Message, "Convert_to_ES6_module_95017", "Convert to ES6 module"),
        Add_undefined_type_to_property_0: diag(95018, ts.DiagnosticCategory.Message, "Add_undefined_type_to_property_0_95018", "Add 'undefined' type to property '{0}'"),
        Add_initializer_to_property_0: diag(95019, ts.DiagnosticCategory.Message, "Add_initializer_to_property_0_95019", "Add initializer to property '{0}'"),
        Add_definite_assignment_assertion_to_property_0: diag(95020, ts.DiagnosticCategory.Message, "Add_definite_assignment_assertion_to_property_0_95020", "Add definite assignment assertion to property '{0}'"),
        Add_all_missing_members: diag(95022, ts.DiagnosticCategory.Message, "Add_all_missing_members_95022", "Add all missing members"),
        Infer_all_types_from_usage: diag(95023, ts.DiagnosticCategory.Message, "Infer_all_types_from_usage_95023", "Infer all types from usage"),
        Delete_all_unused_declarations: diag(95024, ts.DiagnosticCategory.Message, "Delete_all_unused_declarations_95024", "Delete all unused declarations"),
        Prefix_all_unused_declarations_with_where_possible: diag(95025, ts.DiagnosticCategory.Message, "Prefix_all_unused_declarations_with_where_possible_95025", "Prefix all unused declarations with '_' where possible"),
        Fix_all_detected_spelling_errors: diag(95026, ts.DiagnosticCategory.Message, "Fix_all_detected_spelling_errors_95026", "Fix all detected spelling errors"),
        Add_initializers_to_all_uninitialized_properties: diag(95027, ts.DiagnosticCategory.Message, "Add_initializers_to_all_uninitialized_properties_95027", "Add initializers to all uninitialized properties"),
        Add_definite_assignment_assertions_to_all_uninitialized_properties: diag(95028, ts.DiagnosticCategory.Message, "Add_definite_assignment_assertions_to_all_uninitialized_properties_95028", "Add definite assignment assertions to all uninitialized properties"),
        Add_undefined_type_to_all_uninitialized_properties: diag(95029, ts.DiagnosticCategory.Message, "Add_undefined_type_to_all_uninitialized_properties_95029", "Add undefined type to all uninitialized properties"),
        Change_all_jsdoc_style_types_to_TypeScript: diag(95030, ts.DiagnosticCategory.Message, "Change_all_jsdoc_style_types_to_TypeScript_95030", "Change all jsdoc-style types to TypeScript"),
        Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types: diag(95031, ts.DiagnosticCategory.Message, "Change_all_jsdoc_style_types_to_TypeScript_and_add_undefined_to_nullable_types_95031", "Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)"),
        Implement_all_unimplemented_interfaces: diag(95032, ts.DiagnosticCategory.Message, "Implement_all_unimplemented_interfaces_95032", "Implement all unimplemented interfaces"),
        Install_all_missing_types_packages: diag(95033, ts.DiagnosticCategory.Message, "Install_all_missing_types_packages_95033", "Install all missing types packages"),
        Rewrite_all_as_indexed_access_types: diag(95034, ts.DiagnosticCategory.Message, "Rewrite_all_as_indexed_access_types_95034", "Rewrite all as indexed access types"),
        Convert_all_to_default_imports: diag(95035, ts.DiagnosticCategory.Message, "Convert_all_to_default_imports_95035", "Convert all to default imports"),
        Make_all_super_calls_the_first_statement_in_their_constructor: diag(95036, ts.DiagnosticCategory.Message, "Make_all_super_calls_the_first_statement_in_their_constructor_95036", "Make all 'super()' calls the first statement in their constructor"),
        Add_qualifier_to_all_unresolved_variables_matching_a_member_name: diag(95037, ts.DiagnosticCategory.Message, "Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037", "Add qualifier to all unresolved variables matching a member name"),
        Change_all_extended_interfaces_to_implements: diag(95038, ts.DiagnosticCategory.Message, "Change_all_extended_interfaces_to_implements_95038", "Change all extended interfaces to 'implements'"),
        Add_all_missing_super_calls: diag(95039, ts.DiagnosticCategory.Message, "Add_all_missing_super_calls_95039", "Add all missing super calls"),
        Implement_all_inherited_abstract_classes: diag(95040, ts.DiagnosticCategory.Message, "Implement_all_inherited_abstract_classes_95040", "Implement all inherited abstract classes"),
        Add_all_missing_async_modifiers: diag(95041, ts.DiagnosticCategory.Message, "Add_all_missing_async_modifiers_95041", "Add all missing 'async' modifiers"),
        Add_ts_ignore_to_all_error_messages: diag(95042, ts.DiagnosticCategory.Message, "Add_ts_ignore_to_all_error_messages_95042", "Add '@ts-ignore' to all error messages"),
        Annotate_everything_with_types_from_JSDoc: diag(95043, ts.DiagnosticCategory.Message, "Annotate_everything_with_types_from_JSDoc_95043", "Annotate everything with types from JSDoc"),
        Add_to_all_uncalled_decorators: diag(95044, ts.DiagnosticCategory.Message, "Add_to_all_uncalled_decorators_95044", "Add '()' to all uncalled decorators"),
        Convert_all_constructor_functions_to_classes: diag(95045, ts.DiagnosticCategory.Message, "Convert_all_constructor_functions_to_classes_95045", "Convert all constructor functions to classes"),
        Generate_get_and_set_accessors: diag(95046, ts.DiagnosticCategory.Message, "Generate_get_and_set_accessors_95046", "Generate 'get' and 'set' accessors"),
        Convert_require_to_import: diag(95047, ts.DiagnosticCategory.Message, "Convert_require_to_import_95047", "Convert 'require' to 'import'"),
        Convert_all_require_to_import: diag(95048, ts.DiagnosticCategory.Message, "Convert_all_require_to_import_95048", "Convert all 'require' to 'import'"),
        Move_to_a_new_file: diag(95049, ts.DiagnosticCategory.Message, "Move_to_a_new_file_95049", "Move to a new file"),
        Remove_unreachable_code: diag(95050, ts.DiagnosticCategory.Message, "Remove_unreachable_code_95050", "Remove unreachable code"),
        Remove_all_unreachable_code: diag(95051, ts.DiagnosticCategory.Message, "Remove_all_unreachable_code_95051", "Remove all unreachable code"),
        Add_missing_typeof: diag(95052, ts.DiagnosticCategory.Message, "Add_missing_typeof_95052", "Add missing 'typeof'"),
        Remove_unused_label: diag(95053, ts.DiagnosticCategory.Message, "Remove_unused_label_95053", "Remove unused label"),
        Remove_all_unused_labels: diag(95054, ts.DiagnosticCategory.Message, "Remove_all_unused_labels_95054", "Remove all unused labels"),
        Convert_0_to_mapped_object_type: diag(95055, ts.DiagnosticCategory.Message, "Convert_0_to_mapped_object_type_95055", "Convert '{0}' to mapped object type"),
        Convert_namespace_import_to_named_imports: diag(95056, ts.DiagnosticCategory.Message, "Convert_namespace_import_to_named_imports_95056", "Convert namespace import to named imports"),
        Convert_named_imports_to_namespace_import: diag(95057, ts.DiagnosticCategory.Message, "Convert_named_imports_to_namespace_import_95057", "Convert named imports to namespace import"),
        Add_or_remove_braces_in_an_arrow_function: diag(95058, ts.DiagnosticCategory.Message, "Add_or_remove_braces_in_an_arrow_function_95058", "Add or remove braces in an arrow function"),
        Add_braces_to_arrow_function: diag(95059, ts.DiagnosticCategory.Message, "Add_braces_to_arrow_function_95059", "Add braces to arrow function"),
        Remove_braces_from_arrow_function: diag(95060, ts.DiagnosticCategory.Message, "Remove_braces_from_arrow_function_95060", "Remove braces from arrow function"),
        Convert_default_export_to_named_export: diag(95061, ts.DiagnosticCategory.Message, "Convert_default_export_to_named_export_95061", "Convert default export to named export"),
        Convert_named_export_to_default_export: diag(95062, ts.DiagnosticCategory.Message, "Convert_named_export_to_default_export_95062", "Convert named export to default export"),
        Add_missing_enum_member_0: diag(95063, ts.DiagnosticCategory.Message, "Add_missing_enum_member_0_95063", "Add missing enum member '{0}'"),
        Add_all_missing_imports: diag(95064, ts.DiagnosticCategory.Message, "Add_all_missing_imports_95064", "Add all missing imports"),
        Convert_to_async_function: diag(95065, ts.DiagnosticCategory.Message, "Convert_to_async_function_95065", "Convert to async function"),
        Convert_all_to_async_functions: diag(95066, ts.DiagnosticCategory.Message, "Convert_all_to_async_functions_95066", "Convert all to async functions"),
        Add_missing_call_parentheses: diag(95067, ts.DiagnosticCategory.Message, "Add_missing_call_parentheses_95067", "Add missing call parentheses"),
        Add_all_missing_call_parentheses: diag(95068, ts.DiagnosticCategory.Message, "Add_all_missing_call_parentheses_95068", "Add all missing call parentheses"),
        Add_unknown_conversion_for_non_overlapping_types: diag(95069, ts.DiagnosticCategory.Message, "Add_unknown_conversion_for_non_overlapping_types_95069", "Add 'unknown' conversion for non-overlapping types"),
        Add_unknown_to_all_conversions_of_non_overlapping_types: diag(95070, ts.DiagnosticCategory.Message, "Add_unknown_to_all_conversions_of_non_overlapping_types_95070", "Add 'unknown' to all conversions of non-overlapping types"),
        Add_missing_new_operator_to_call: diag(95071, ts.DiagnosticCategory.Message, "Add_missing_new_operator_to_call_95071", "Add missing 'new' operator to call"),
        Add_missing_new_operator_to_all_calls: diag(95072, ts.DiagnosticCategory.Message, "Add_missing_new_operator_to_all_calls_95072", "Add missing 'new' operator to all calls"),
        Add_names_to_all_parameters_without_names: diag(95073, ts.DiagnosticCategory.Message, "Add_names_to_all_parameters_without_names_95073", "Add names to all parameters without names"),
        Enable_the_experimentalDecorators_option_in_your_configuration_file: diag(95074, ts.DiagnosticCategory.Message, "Enable_the_experimentalDecorators_option_in_your_configuration_file_95074", "Enable the 'experimentalDecorators' option in your configuration file"),
        Convert_parameters_to_destructured_object: diag(95075, ts.DiagnosticCategory.Message, "Convert_parameters_to_destructured_object_95075", "Convert parameters to destructured object"),
        Allow_accessing_UMD_globals_from_modules: diag(95076, ts.DiagnosticCategory.Message, "Allow_accessing_UMD_globals_from_modules_95076", "Allow accessing UMD globals from modules."),
        Extract_type: diag(95077, ts.DiagnosticCategory.Message, "Extract_type_95077", "Extract type"),
        Extract_to_type_alias: diag(95078, ts.DiagnosticCategory.Message, "Extract_to_type_alias_95078", "Extract to type alias"),
        Extract_to_typedef: diag(95079, ts.DiagnosticCategory.Message, "Extract_to_typedef_95079", "Extract to typedef"),
        Infer_this_type_of_0_from_usage: diag(95080, ts.DiagnosticCategory.Message, "Infer_this_type_of_0_from_usage_95080", "Infer 'this' type of '{0}' from usage"),
        Add_const_to_unresolved_variable: diag(95081, ts.DiagnosticCategory.Message, "Add_const_to_unresolved_variable_95081", "Add 'const' to unresolved variable"),
        Add_const_to_all_unresolved_variables: diag(95082, ts.DiagnosticCategory.Message, "Add_const_to_all_unresolved_variables_95082", "Add 'const' to all unresolved variables"),
        Add_await: diag(95083, ts.DiagnosticCategory.Message, "Add_await_95083", "Add 'await'"),
        Add_await_to_initializer_for_0: diag(95084, ts.DiagnosticCategory.Message, "Add_await_to_initializer_for_0_95084", "Add 'await' to initializer for '{0}'"),
        Fix_all_expressions_possibly_missing_await: diag(95085, ts.DiagnosticCategory.Message, "Fix_all_expressions_possibly_missing_await_95085", "Fix all expressions possibly missing 'await'"),
        Remove_unnecessary_await: diag(95086, ts.DiagnosticCategory.Message, "Remove_unnecessary_await_95086", "Remove unnecessary 'await'"),
        Remove_all_unnecessary_uses_of_await: diag(95087, ts.DiagnosticCategory.Message, "Remove_all_unnecessary_uses_of_await_95087", "Remove all unnecessary uses of 'await'"),
        Enable_the_jsx_flag_in_your_configuration_file: diag(95088, ts.DiagnosticCategory.Message, "Enable_the_jsx_flag_in_your_configuration_file_95088", "Enable the '--jsx' flag in your configuration file"),
        Add_await_to_initializers: diag(95089, ts.DiagnosticCategory.Message, "Add_await_to_initializers_95089", "Add 'await' to initializers"),
        Extract_to_interface: diag(95090, ts.DiagnosticCategory.Message, "Extract_to_interface_95090", "Extract to interface"),
        Convert_to_a_bigint_numeric_literal: diag(95091, ts.DiagnosticCategory.Message, "Convert_to_a_bigint_numeric_literal_95091", "Convert to a bigint numeric literal"),
        Convert_all_to_bigint_numeric_literals: diag(95092, ts.DiagnosticCategory.Message, "Convert_all_to_bigint_numeric_literals_95092", "Convert all to bigint numeric literals"),
        Convert_const_to_let: diag(95093, ts.DiagnosticCategory.Message, "Convert_const_to_let_95093", "Convert 'const' to 'let'"),
        Prefix_with_declare: diag(95094, ts.DiagnosticCategory.Message, "Prefix_with_declare_95094", "Prefix with 'declare'"),
        Prefix_all_incorrect_property_declarations_with_declare: diag(95095, ts.DiagnosticCategory.Message, "Prefix_all_incorrect_property_declarations_with_declare_95095", "Prefix all incorrect property declarations with 'declare'"),
        Convert_to_template_string: diag(95096, ts.DiagnosticCategory.Message, "Convert_to_template_string_95096", "Convert to template string"),
        Add_export_to_make_this_file_into_a_module: diag(95097, ts.DiagnosticCategory.Message, "Add_export_to_make_this_file_into_a_module_95097", "Add 'export {}' to make this file into a module"),
        Set_the_target_option_in_your_configuration_file_to_0: diag(95098, ts.DiagnosticCategory.Message, "Set_the_target_option_in_your_configuration_file_to_0_95098", "Set the 'target' option in your configuration file to '{0}'"),
        Set_the_module_option_in_your_configuration_file_to_0: diag(95099, ts.DiagnosticCategory.Message, "Set_the_module_option_in_your_configuration_file_to_0_95099", "Set the 'module' option in your configuration file to '{0}'"),
        Convert_invalid_character_to_its_html_entity_code: diag(95100, ts.DiagnosticCategory.Message, "Convert_invalid_character_to_its_html_entity_code_95100", "Convert invalid character to its html entity code"),
        Convert_all_invalid_characters_to_HTML_entity_code: diag(95101, ts.DiagnosticCategory.Message, "Convert_all_invalid_characters_to_HTML_entity_code_95101", "Convert all invalid characters to HTML entity code"),
        Add_class_tag: diag(95102, ts.DiagnosticCategory.Message, "Add_class_tag_95102", "Add '@class' tag"),
        Add_this_tag: diag(95103, ts.DiagnosticCategory.Message, "Add_this_tag_95103", "Add '@this' tag"),
        Add_this_parameter: diag(95104, ts.DiagnosticCategory.Message, "Add_this_parameter_95104", "Add 'this' parameter."),
        Convert_function_expression_0_to_arrow_function: diag(95105, ts.DiagnosticCategory.Message, "Convert_function_expression_0_to_arrow_function_95105", "Convert function expression '{0}' to arrow function"),
        Convert_function_declaration_0_to_arrow_function: diag(95106, ts.DiagnosticCategory.Message, "Convert_function_declaration_0_to_arrow_function_95106", "Convert function declaration '{0}' to arrow function"),
        Fix_all_implicit_this_errors: diag(95107, ts.DiagnosticCategory.Message, "Fix_all_implicit_this_errors_95107", "Fix all implicit-'this' errors"),
        Wrap_invalid_character_in_an_expression_container: diag(95108, ts.DiagnosticCategory.Message, "Wrap_invalid_character_in_an_expression_container_95108", "Wrap invalid character in an expression container"),
        Wrap_all_invalid_characters_in_an_expression_container: diag(95109, ts.DiagnosticCategory.Message, "Wrap_all_invalid_characters_in_an_expression_container_95109", "Wrap all invalid characters in an expression container"),
        Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_json_to_read_more_about_this_file: diag(95110, ts.DiagnosticCategory.Message, "Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_json_to_read_more_about_this_file_95110", "Visit https://aka.ms/tsconfig.json to read more about this file"),
        Add_a_return_statement: diag(95111, ts.DiagnosticCategory.Message, "Add_a_return_statement_95111", "Add a return statement"),
        Remove_block_body_braces: diag(95112, ts.DiagnosticCategory.Message, "Remove_block_body_braces_95112", "Remove block body braces"),
        Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal: diag(95113, ts.DiagnosticCategory.Message, "Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal_95113", "Wrap the following body with parentheses which should be an object literal"),
        Add_all_missing_return_statement: diag(95114, ts.DiagnosticCategory.Message, "Add_all_missing_return_statement_95114", "Add all missing return statement"),
        Remove_all_incorrect_body_block_braces: diag(95115, ts.DiagnosticCategory.Message, "Remove_all_incorrect_body_block_braces_95115", "Remove all incorrect body block braces"),
        Wrap_all_object_literal_with_parentheses: diag(95116, ts.DiagnosticCategory.Message, "Wrap_all_object_literal_with_parentheses_95116", "Wrap all object literal with parentheses"),
        No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer: diag(18004, ts.DiagnosticCategory.Error, "No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer_18004", "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer."),
        Classes_may_not_have_a_field_named_constructor: diag(18006, ts.DiagnosticCategory.Error, "Classes_may_not_have_a_field_named_constructor_18006", "Classes may not have a field named 'constructor'."),
        JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array: diag(18007, ts.DiagnosticCategory.Error, "JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array_18007", "JSX expressions may not use the comma operator. Did you mean to write an array?"),
        Private_identifiers_cannot_be_used_as_parameters: diag(18009, ts.DiagnosticCategory.Error, "Private_identifiers_cannot_be_used_as_parameters_18009", "Private identifiers cannot be used as parameters"),
        An_accessibility_modifier_cannot_be_used_with_a_private_identifier: diag(18010, ts.DiagnosticCategory.Error, "An_accessibility_modifier_cannot_be_used_with_a_private_identifier_18010", "An accessibility modifier cannot be used with a private identifier."),
        The_operand_of_a_delete_operator_cannot_be_a_private_identifier: diag(18011, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_private_identifier_18011", "The operand of a 'delete' operator cannot be a private identifier."),
        constructor_is_a_reserved_word: diag(18012, ts.DiagnosticCategory.Error, "constructor_is_a_reserved_word_18012", "'#constructor' is a reserved word."),
        Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier: diag(18013, ts.DiagnosticCategory.Error, "Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier_18013", "Property '{0}' is not accessible outside class '{1}' because it has a private identifier."),
        The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_private_identifier_with_the_same_spelling: diag(18014, ts.DiagnosticCategory.Error, "The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_priv_18014", "The property '{0}' cannot be accessed on type '{1}' within this class because it is shadowed by another private identifier with the same spelling."),
        Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2: diag(18015, ts.DiagnosticCategory.Error, "Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2_18015", "Property '{0}' in type '{1}' refers to a different member that cannot be accessed from within type '{2}'."),
        Private_identifiers_are_not_allowed_outside_class_bodies: diag(18016, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_outside_class_bodies_18016", "Private identifiers are not allowed outside class bodies."),
        The_shadowing_declaration_of_0_is_defined_here: diag(18017, ts.DiagnosticCategory.Error, "The_shadowing_declaration_of_0_is_defined_here_18017", "The shadowing declaration of '{0}' is defined here"),
        The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here: diag(18018, ts.DiagnosticCategory.Error, "The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here_18018", "The declaration of '{0}' that you probably intended to use is defined here"),
        _0_modifier_cannot_be_used_with_a_private_identifier: diag(18019, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_a_private_identifier_18019", "'{0}' modifier cannot be used with a private identifier"),
        A_method_cannot_be_named_with_a_private_identifier: diag(18022, ts.DiagnosticCategory.Error, "A_method_cannot_be_named_with_a_private_identifier_18022", "A method cannot be named with a private identifier."),
        An_accessor_cannot_be_named_with_a_private_identifier: diag(18023, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_named_with_a_private_identifier_18023", "An accessor cannot be named with a private identifier."),
        An_enum_member_cannot_be_named_with_a_private_identifier: diag(18024, ts.DiagnosticCategory.Error, "An_enum_member_cannot_be_named_with_a_private_identifier_18024", "An enum member cannot be named with a private identifier."),
        can_only_be_used_at_the_start_of_a_file: diag(18026, ts.DiagnosticCategory.Error, "can_only_be_used_at_the_start_of_a_file_18026", "'#!' can only be used at the start of a file."),
        Compiler_reserves_name_0_when_emitting_private_identifier_downlevel: diag(18027, ts.DiagnosticCategory.Error, "Compiler_reserves_name_0_when_emitting_private_identifier_downlevel_18027", "Compiler reserves name '{0}' when emitting private identifier downlevel."),
        Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher: diag(18028, ts.DiagnosticCategory.Error, "Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher_18028", "Private identifiers are only available when targeting ECMAScript 2015 and higher."),
        Private_identifiers_are_not_allowed_in_variable_declarations: diag(18029, ts.DiagnosticCategory.Error, "Private_identifiers_are_not_allowed_in_variable_declarations_18029", "Private identifiers are not allowed in variable declarations."),
        An_optional_chain_cannot_contain_private_identifiers: diag(18030, ts.DiagnosticCategory.Error, "An_optional_chain_cannot_contain_private_identifiers_18030", "An optional chain cannot contain private identifiers."),
        The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents: diag(18031, ts.DiagnosticCategory.Error, "The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituent_18031", "The intersection '{0}' was reduced to 'never' because property '{1}' has conflicting types in some constituents."),
        The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some: diag(18032, ts.DiagnosticCategory.Error, "The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_pr_18032", "The intersection '{0}' was reduced to 'never' because property '{1}' exists in multiple constituents and is private in some."),
        Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhaustiveness_checks_consider_using_an_object_literal_instead: diag(18033, ts.DiagnosticCategory.Error, "Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhau_18033", "Only numeric enums can have computed members, but this expression has type '{0}'. If you do not need exhaustiveness checks, consider using an object literal instead."),
    };
})(ts || (ts = {}));
var ts;
(function (ts) {
    var _a;
    /* @internal */
    function tokenIsIdentifierOrKeyword(token) {
        return token >= 75 /* Identifier */;
    }
    ts.tokenIsIdentifierOrKeyword = tokenIsIdentifierOrKeyword;
    /* @internal */
    function tokenIsIdentifierOrKeywordOrGreaterThan(token) {
        return token === 31 /* GreaterThanToken */ || tokenIsIdentifierOrKeyword(token);
    }
    ts.tokenIsIdentifierOrKeywordOrGreaterThan = tokenIsIdentifierOrKeywordOrGreaterThan;
    var textToKeywordObj = (_a = {
            abstract: 122 /* AbstractKeyword */,
            any: 125 /* AnyKeyword */,
            as: 123 /* AsKeyword */,
            asserts: 124 /* AssertsKeyword */,
            bigint: 151 /* BigIntKeyword */,
            boolean: 128 /* BooleanKeyword */,
            break: 77 /* BreakKeyword */,
            case: 78 /* CaseKeyword */,
            catch: 79 /* CatchKeyword */,
            class: 80 /* ClassKeyword */,
            continue: 82 /* ContinueKeyword */,
            const: 81 /* ConstKeyword */
        },
        _a["" + "constructor"] = 129 /* ConstructorKeyword */,
        _a.debugger = 83 /* DebuggerKeyword */,
        _a.declare = 130 /* DeclareKeyword */,
        _a.default = 84 /* DefaultKeyword */,
        _a.delete = 85 /* DeleteKeyword */,
        _a.do = 86 /* DoKeyword */,
        _a.else = 87 /* ElseKeyword */,
        _a.enum = 88 /* EnumKeyword */,
        _a.export = 89 /* ExportKeyword */,
        _a.extends = 90 /* ExtendsKeyword */,
        _a.false = 91 /* FalseKeyword */,
        _a.finally = 92 /* FinallyKeyword */,
        _a.for = 93 /* ForKeyword */,
        _a.from = 149 /* FromKeyword */,
        _a.function = 94 /* FunctionKeyword */,
        _a.get = 131 /* GetKeyword */,
        _a.if = 95 /* IfKeyword */,
        _a.implements = 113 /* ImplementsKeyword */,
        _a.import = 96 /* ImportKeyword */,
        _a.in = 97 /* InKeyword */,
        _a.infer = 132 /* InferKeyword */,
        _a.instanceof = 98 /* InstanceOfKeyword */,
        _a.interface = 114 /* InterfaceKeyword */,
        _a.is = 133 /* IsKeyword */,
        _a.keyof = 134 /* KeyOfKeyword */,
        _a.let = 115 /* LetKeyword */,
        _a.module = 135 /* ModuleKeyword */,
        _a.namespace = 136 /* NamespaceKeyword */,
        _a.never = 137 /* NeverKeyword */,
        _a.new = 99 /* NewKeyword */,
        _a.null = 100 /* NullKeyword */,
        _a.number = 140 /* NumberKeyword */,
        _a.object = 141 /* ObjectKeyword */,
        _a.package = 116 /* PackageKeyword */,
        _a.private = 117 /* PrivateKeyword */,
        _a.protected = 118 /* ProtectedKeyword */,
        _a.public = 119 /* PublicKeyword */,
        _a.readonly = 138 /* ReadonlyKeyword */,
        _a.require = 139 /* RequireKeyword */,
        _a.global = 150 /* GlobalKeyword */,
        _a.return = 101 /* ReturnKeyword */,
        _a.set = 142 /* SetKeyword */,
        _a.static = 120 /* StaticKeyword */,
        _a.string = 143 /* StringKeyword */,
        _a.super = 102 /* SuperKeyword */,
        _a.switch = 103 /* SwitchKeyword */,
        _a.symbol = 144 /* SymbolKeyword */,
        _a.this = 104 /* ThisKeyword */,
        _a.throw = 105 /* ThrowKeyword */,
        _a.true = 106 /* TrueKeyword */,
        _a.try = 107 /* TryKeyword */,
        _a.type = 145 /* TypeKeyword */,
        _a.typeof = 108 /* TypeOfKeyword */,
        _a.undefined = 146 /* UndefinedKeyword */,
        _a.unique = 147 /* UniqueKeyword */,
        _a.unknown = 148 /* UnknownKeyword */,
        _a.var = 109 /* VarKeyword */,
        _a.void = 110 /* VoidKeyword */,
        _a.while = 111 /* WhileKeyword */,
        _a.with = 112 /* WithKeyword */,
        _a.yield = 121 /* YieldKeyword */,
        _a.async = 126 /* AsyncKeyword */,
        _a.await = 127 /* AwaitKeyword */,
        _a.of = 152 /* OfKeyword */,
        _a);
    var textToKeyword = ts.createMapFromTemplate(textToKeywordObj);
    var textToToken = ts.createMapFromTemplate(__assign(__assign({}, textToKeywordObj), { "{": 18 /* OpenBraceToken */, "}": 19 /* CloseBraceToken */, "(": 20 /* OpenParenToken */, ")": 21 /* CloseParenToken */, "[": 22 /* OpenBracketToken */, "]": 23 /* CloseBracketToken */, ".": 24 /* DotToken */, "...": 25 /* DotDotDotToken */, ";": 26 /* SemicolonToken */, ",": 27 /* CommaToken */, "<": 29 /* LessThanToken */, ">": 31 /* GreaterThanToken */, "<=": 32 /* LessThanEqualsToken */, ">=": 33 /* GreaterThanEqualsToken */, "==": 34 /* EqualsEqualsToken */, "!=": 35 /* ExclamationEqualsToken */, "===": 36 /* EqualsEqualsEqualsToken */, "!==": 37 /* ExclamationEqualsEqualsToken */, "=>": 38 /* EqualsGreaterThanToken */, "+": 39 /* PlusToken */, "-": 40 /* MinusToken */, "**": 42 /* AsteriskAsteriskToken */, "*": 41 /* AsteriskToken */, "/": 43 /* SlashToken */, "%": 44 /* PercentToken */, "++": 45 /* PlusPlusToken */, "--": 46 /* MinusMinusToken */, "<<": 47 /* LessThanLessThanToken */, "</": 30 /* LessThanSlashToken */, ">>": 48 /* GreaterThanGreaterThanToken */, ">>>": 49 /* GreaterThanGreaterThanGreaterThanToken */, "&": 50 /* AmpersandToken */, "|": 51 /* BarToken */, "^": 52 /* CaretToken */, "!": 53 /* ExclamationToken */, "~": 54 /* TildeToken */, "&&": 55 /* AmpersandAmpersandToken */, "||": 56 /* BarBarToken */, "?": 57 /* QuestionToken */, "??": 60 /* QuestionQuestionToken */, "?.": 28 /* QuestionDotToken */, ":": 58 /* ColonToken */, "=": 62 /* EqualsToken */, "+=": 63 /* PlusEqualsToken */, "-=": 64 /* MinusEqualsToken */, "*=": 65 /* AsteriskEqualsToken */, "**=": 66 /* AsteriskAsteriskEqualsToken */, "/=": 67 /* SlashEqualsToken */, "%=": 68 /* PercentEqualsToken */, "<<=": 69 /* LessThanLessThanEqualsToken */, ">>=": 70 /* GreaterThanGreaterThanEqualsToken */, ">>>=": 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */, "&=": 72 /* AmpersandEqualsToken */, "|=": 73 /* BarEqualsToken */, "^=": 74 /* CaretEqualsToken */, "@": 59 /* AtToken */, "`": 61 /* BacktickToken */ }));
    /*
        As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers
        IdentifierStart ::
            Can contain Unicode 3.0.0 categories:
            Uppercase letter (Lu),
            Lowercase letter (Ll),
            Titlecase letter (Lt),
            Modifier letter (Lm),
            Other letter (Lo), or
            Letter number (Nl).
        IdentifierPart :: =
            Can contain IdentifierStart + Unicode 3.0.0 categories:
            Non-spacing mark (Mn),
            Combining spacing mark (Mc),
            Decimal number (Nd), or
            Connector punctuation (Pc).

        Codepoint ranges for ES3 Identifiers are extracted from the Unicode 3.0.0 specification at:
        http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt
    */
    var unicodeES3IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    var unicodeES3IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    /*
        As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers
        IdentifierStart ::
            Can contain Unicode 6.2 categories:
            Uppercase letter (Lu),
            Lowercase letter (Ll),
            Titlecase letter (Lt),
            Modifier letter (Lm),
            Other letter (Lo), or
            Letter number (Nl).
        IdentifierPart ::
            Can contain IdentifierStart + Unicode 6.2 categories:
            Non-spacing mark (Mn),
            Combining spacing mark (Mc),
            Decimal number (Nd),
            Connector punctuation (Pc),
            <ZWNJ>, or
            <ZWJ>.

        Codepoint ranges for ES5 Identifiers are extracted from the Unicode 6.2 specification at:
        http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt
    */
    var unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2208, 2208, 2210, 2220, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7413, 7414, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    var unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,];
    /**
     * Generated by scripts/regenerate-unicode-identifier-parts.js on node v12.4.0 with unicode 12.1
     * based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords
     * unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and
     * unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start
     */
    var unicodeESNextIdentifierStart = [65, 90, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 895, 895, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1488, 1514, 1519, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2144, 2154, 2208, 2228, 2230, 2237, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2432, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2556, 2556, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2809, 2809, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3133, 3160, 3162, 3168, 3169, 3200, 3200, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3412, 3414, 3423, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6264, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6430, 6480, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7401, 7404, 7406, 7411, 7413, 7414, 7418, 7418, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40943, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42653, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42943, 42946, 42950, 42999, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43261, 43262, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43488, 43492, 43494, 43503, 43514, 43518, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43646, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43879, 43888, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66335, 66349, 66378, 66384, 66421, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 67072, 67382, 67392, 67413, 67424, 67431, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68096, 68112, 68115, 68117, 68119, 68121, 68149, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68324, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68899, 69376, 69404, 69415, 69415, 69424, 69445, 69600, 69622, 69635, 69687, 69763, 69807, 69840, 69864, 69891, 69926, 69956, 69956, 69968, 70002, 70006, 70006, 70019, 70066, 70081, 70084, 70106, 70106, 70108, 70108, 70144, 70161, 70163, 70187, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70366, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70461, 70461, 70480, 70480, 70493, 70497, 70656, 70708, 70727, 70730, 70751, 70751, 70784, 70831, 70852, 70853, 70855, 70855, 71040, 71086, 71128, 71131, 71168, 71215, 71236, 71236, 71296, 71338, 71352, 71352, 71424, 71450, 71680, 71723, 71840, 71903, 71935, 71935, 72096, 72103, 72106, 72144, 72161, 72161, 72163, 72163, 72192, 72192, 72203, 72242, 72250, 72250, 72272, 72272, 72284, 72329, 72349, 72349, 72384, 72440, 72704, 72712, 72714, 72750, 72768, 72768, 72818, 72847, 72960, 72966, 72968, 72969, 72971, 73008, 73030, 73030, 73056, 73061, 73063, 73064, 73066, 73097, 73112, 73112, 73440, 73458, 73728, 74649, 74752, 74862, 74880, 75075, 77824, 78894, 82944, 83526, 92160, 92728, 92736, 92766, 92880, 92909, 92928, 92975, 92992, 92995, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94032, 94032, 94099, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101106, 110592, 110878, 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 123136, 123180, 123191, 123197, 123214, 123214, 123584, 123627, 124928, 125124, 125184, 125251, 125259, 125259, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173782, 173824, 177972, 177984, 178205, 178208, 183969, 183984, 191456, 194560, 195101];
    var unicodeESNextIdentifierPart = [48, 57, 65, 90, 95, 95, 97, 122, 170, 170, 181, 181, 183, 183, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 895, 895, 902, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1519, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2045, 2045, 2048, 2093, 2112, 2139, 2144, 2154, 2208, 2228, 2230, 2237, 2259, 2273, 2275, 2403, 2406, 2415, 2417, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2556, 2556, 2558, 2558, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2809, 2815, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3072, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3162, 3168, 3171, 3174, 3183, 3200, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3328, 3331, 3333, 3340, 3342, 3344, 3346, 3396, 3398, 3400, 3402, 3406, 3412, 3415, 3423, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3558, 3567, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4969, 4977, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6264, 6272, 6314, 6320, 6389, 6400, 6430, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6618, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6832, 6845, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7376, 7378, 7380, 7418, 7424, 7673, 7675, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40943, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42737, 42775, 42783, 42786, 42888, 42891, 42943, 42946, 42950, 42999, 43047, 43072, 43123, 43136, 43205, 43216, 43225, 43232, 43255, 43259, 43259, 43261, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43488, 43518, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43879, 43888, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65071, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66045, 66045, 66176, 66204, 66208, 66256, 66272, 66272, 66304, 66335, 66349, 66378, 66384, 66426, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66720, 66729, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 67072, 67382, 67392, 67413, 67424, 67431, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68099, 68101, 68102, 68108, 68115, 68117, 68119, 68121, 68149, 68152, 68154, 68159, 68159, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68326, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68903, 68912, 68921, 69376, 69404, 69415, 69415, 69424, 69456, 69600, 69622, 69632, 69702, 69734, 69743, 69759, 69818, 69840, 69864, 69872, 69881, 69888, 69940, 69942, 69951, 69956, 69958, 69968, 70003, 70006, 70006, 70016, 70084, 70089, 70092, 70096, 70106, 70108, 70108, 70144, 70161, 70163, 70199, 70206, 70206, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70378, 70384, 70393, 70400, 70403, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70459, 70468, 70471, 70472, 70475, 70477, 70480, 70480, 70487, 70487, 70493, 70499, 70502, 70508, 70512, 70516, 70656, 70730, 70736, 70745, 70750, 70751, 70784, 70853, 70855, 70855, 70864, 70873, 71040, 71093, 71096, 71104, 71128, 71133, 71168, 71232, 71236, 71236, 71248, 71257, 71296, 71352, 71360, 71369, 71424, 71450, 71453, 71467, 71472, 71481, 71680, 71738, 71840, 71913, 71935, 71935, 72096, 72103, 72106, 72151, 72154, 72161, 72163, 72164, 72192, 72254, 72263, 72263, 72272, 72345, 72349, 72349, 72384, 72440, 72704, 72712, 72714, 72758, 72760, 72768, 72784, 72793, 72818, 72847, 72850, 72871, 72873, 72886, 72960, 72966, 72968, 72969, 72971, 73014, 73018, 73018, 73020, 73021, 73023, 73031, 73040, 73049, 73056, 73061, 73063, 73064, 73066, 73102, 73104, 73105, 73107, 73112, 73120, 73129, 73440, 73462, 73728, 74649, 74752, 74862, 74880, 75075, 77824, 78894, 82944, 83526, 92160, 92728, 92736, 92766, 92768, 92777, 92880, 92909, 92912, 92916, 92928, 92982, 92992, 92995, 93008, 93017, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94031, 94087, 94095, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101106, 110592, 110878, 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 113821, 113822, 119141, 119145, 119149, 119154, 119163, 119170, 119173, 119179, 119210, 119213, 119362, 119364, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 120782, 120831, 121344, 121398, 121403, 121452, 121461, 121461, 121476, 121476, 121499, 121503, 121505, 121519, 122880, 122886, 122888, 122904, 122907, 122913, 122915, 122916, 122918, 122922, 123136, 123180, 123184, 123197, 123200, 123209, 123214, 123214, 123584, 123641, 124928, 125124, 125136, 125142, 125184, 125259, 125264, 125273, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173782, 173824, 177972, 177984, 178205, 178208, 183969, 183984, 191456, 194560, 195101, 917760, 917999];
    /**
     * Test for whether a single line comment's text contains a directive.
     */
    var commentDirectiveRegExSingleLine = /^\s*\/\/\/?\s*@(ts-expect-error|ts-ignore)/;
    /**
     * Test for whether a multi-line comment's last line contains a directive.
     */
    var commentDirectiveRegExMultiLine = /^\s*(?:\/|\*)*\s*@(ts-expect-error|ts-ignore)/;
    function lookupInUnicodeMap(code, map) {
        // Bail out quickly if it couldn't possibly be in the map.
        if (code < map[0]) {
            return false;
        }
        // Perform binary search in one of the Unicode range maps
        var lo = 0;
        var hi = map.length;
        var mid;
        while (lo + 1 < hi) {
            mid = lo + (hi - lo) / 2;
            // mid has to be even to catch a range's beginning
            mid -= mid % 2;
            if (map[mid] <= code && code <= map[mid + 1]) {
                return true;
            }
            if (code < map[mid]) {
                hi = mid;
            }
            else {
                lo = mid + 2;
            }
        }
        return false;
    }
    /* @internal */ function isUnicodeIdentifierStart(code, languageVersion) {
        return languageVersion >= 2 /* ES2015 */ ?
            lookupInUnicodeMap(code, unicodeESNextIdentifierStart) :
            languageVersion === 1 /* ES5 */ ? lookupInUnicodeMap(code, unicodeES5IdentifierStart) :
                lookupInUnicodeMap(code, unicodeES3IdentifierStart);
    }
    ts.isUnicodeIdentifierStart = isUnicodeIdentifierStart;
    function isUnicodeIdentifierPart(code, languageVersion) {
        return languageVersion >= 2 /* ES2015 */ ?
            lookupInUnicodeMap(code, unicodeESNextIdentifierPart) :
            languageVersion === 1 /* ES5 */ ? lookupInUnicodeMap(code, unicodeES5IdentifierPart) :
                lookupInUnicodeMap(code, unicodeES3IdentifierPart);
    }
    function makeReverseMap(source) {
        var result = [];
        source.forEach(function (value, name) {
            result[value] = name;
        });
        return result;
    }
    var tokenStrings = makeReverseMap(textToToken);
    function tokenToString(t) {
        return tokenStrings[t];
    }
    ts.tokenToString = tokenToString;
    /* @internal */
    function stringToToken(s) {
        return textToToken.get(s);
    }
    ts.stringToToken = stringToToken;
    /* @internal */
    function computeLineStarts(text) {
        var result = new Array();
        var pos = 0;
        var lineStart = 0;
        while (pos < text.length) {
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    result.push(lineStart);
                    lineStart = pos;
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && isLineBreak(ch)) {
                        result.push(lineStart);
                        lineStart = pos;
                    }
                    break;
            }
        }
        result.push(lineStart);
        return result;
    }
    ts.computeLineStarts = computeLineStarts;
    function getPositionOfLineAndCharacter(sourceFile, line, character, allowEdits) {
        return sourceFile.getPositionOfLineAndCharacter ?
            sourceFile.getPositionOfLineAndCharacter(line, character, allowEdits) :
            computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text, allowEdits);
    }
    ts.getPositionOfLineAndCharacter = getPositionOfLineAndCharacter;
    /* @internal */
    function computePositionOfLineAndCharacter(lineStarts, line, character, debugText, allowEdits) {
        if (line < 0 || line >= lineStarts.length) {
            if (allowEdits) {
                // Clamp line to nearest allowable value
                line = line < 0 ? 0 : line >= lineStarts.length ? lineStarts.length - 1 : line;
            }
            else {
                ts.Debug.fail("Bad line number. Line: " + line + ", lineStarts.length: " + lineStarts.length + " , line map is correct? " + (debugText !== undefined ? ts.arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"));
            }
        }
        var res = lineStarts[line] + character;
        if (allowEdits) {
            // Clamp to nearest allowable values to allow the underlying to be edited without crashing (accuracy is lost, instead)
            // TODO: Somehow track edits between file as it was during the creation of sourcemap we have and the current file and
            // apply them to the computed position to improve accuracy
            return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res;
        }
        if (line < lineStarts.length - 1) {
            ts.Debug.assert(res < lineStarts[line + 1]);
        }
        else if (debugText !== undefined) {
            ts.Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline
        }
        return res;
    }
    ts.computePositionOfLineAndCharacter = computePositionOfLineAndCharacter;
    /* @internal */
    function getLineStarts(sourceFile) {
        return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text));
    }
    ts.getLineStarts = getLineStarts;
    /* @internal */
    function computeLineAndCharacterOfPosition(lineStarts, position) {
        var lineNumber = computeLineOfPosition(lineStarts, position);
        return {
            line: lineNumber,
            character: position - lineStarts[lineNumber]
        };
    }
    ts.computeLineAndCharacterOfPosition = computeLineAndCharacterOfPosition;
    /**
     * @internal
     * We assume the first line starts at position 0 and 'position' is non-negative.
     */
    function computeLineOfPosition(lineStarts, position, lowerBound) {
        var lineNumber = ts.binarySearch(lineStarts, position, ts.identity, ts.compareValues, lowerBound);
        if (lineNumber < 0) {
            // If the actual position was not found,
            // the binary search returns the 2's-complement of the next line start
            // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
            // then the search will return -2.
            //
            // We want the index of the previous line start, so we subtract 1.
            // Review 2's-complement if this is confusing.
            lineNumber = ~lineNumber - 1;
            ts.Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file");
        }
        return lineNumber;
    }
    ts.computeLineOfPosition = computeLineOfPosition;
    /** @internal */
    function getLinesBetweenPositions(sourceFile, pos1, pos2) {
        if (pos1 === pos2)
            return 0;
        var lineStarts = getLineStarts(sourceFile);
        var lower = Math.min(pos1, pos2);
        var isNegative = lower === pos2;
        var upper = isNegative ? pos1 : pos2;
        var lowerLine = computeLineOfPosition(lineStarts, lower);
        var upperLine = computeLineOfPosition(lineStarts, upper, lowerLine);
        return isNegative ? lowerLine - upperLine : upperLine - lowerLine;
    }
    ts.getLinesBetweenPositions = getLinesBetweenPositions;
    function getLineAndCharacterOfPosition(sourceFile, position) {
        return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position);
    }
    ts.getLineAndCharacterOfPosition = getLineAndCharacterOfPosition;
    function isWhiteSpaceLike(ch) {
        return isWhiteSpaceSingleLine(ch) || isLineBreak(ch);
    }
    ts.isWhiteSpaceLike = isWhiteSpaceLike;
    /** Does not include line breaks. For that, see isWhiteSpaceLike. */
    function isWhiteSpaceSingleLine(ch) {
        // Note: nextLine is in the Zs space, and should be considered to be a whitespace.
        // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript.
        return ch === 32 /* space */ ||
            ch === 9 /* tab */ ||
            ch === 11 /* verticalTab */ ||
            ch === 12 /* formFeed */ ||
            ch === 160 /* nonBreakingSpace */ ||
            ch === 133 /* nextLine */ ||
            ch === 5760 /* ogham */ ||
            ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ ||
            ch === 8239 /* narrowNoBreakSpace */ ||
            ch === 8287 /* mathematicalSpace */ ||
            ch === 12288 /* ideographicSpace */ ||
            ch === 65279 /* byteOrderMark */;
    }
    ts.isWhiteSpaceSingleLine = isWhiteSpaceSingleLine;
    function isLineBreak(ch) {
        // ES5 7.3:
        // The ECMAScript line terminator characters are listed in Table 3.
        //     Table 3: Line Terminator Characters
        //     Code Unit Value     Name                    Formal Name
        //     \u000A              Line Feed               <LF>
        //     \u000D              Carriage Return         <CR>
        //     \u2028              Line separator          <LS>
        //     \u2029              Paragraph separator     <PS>
        // Only the characters in Table 3 are treated as line terminators. Other new line or line
        // breaking characters are treated as white space but not as line terminators.
        return ch === 10 /* lineFeed */ ||
            ch === 13 /* carriageReturn */ ||
            ch === 8232 /* lineSeparator */ ||
            ch === 8233 /* paragraphSeparator */;
    }
    ts.isLineBreak = isLineBreak;
    function isDigit(ch) {
        return ch >= 48 /* _0 */ && ch <= 57 /* _9 */;
    }
    function isHexDigit(ch) {
        return isDigit(ch) || ch >= 65 /* A */ && ch <= 70 /* F */ || ch >= 97 /* a */ && ch <= 102 /* f */;
    }
    function isCodePoint(code) {
        return code <= 0x10FFFF;
    }
    /* @internal */
    function isOctalDigit(ch) {
        return ch >= 48 /* _0 */ && ch <= 55 /* _7 */;
    }
    ts.isOctalDigit = isOctalDigit;
    function couldStartTrivia(text, pos) {
        // Keep in sync with skipTrivia
        var ch = text.charCodeAt(pos);
        switch (ch) {
            case 13 /* carriageReturn */:
            case 10 /* lineFeed */:
            case 9 /* tab */:
            case 11 /* verticalTab */:
            case 12 /* formFeed */:
            case 32 /* space */:
            case 47 /* slash */:
            // starts of normal trivia
            // falls through
            case 60 /* lessThan */:
            case 124 /* bar */:
            case 61 /* equals */:
            case 62 /* greaterThan */:
                // Starts of conflict marker trivia
                return true;
            case 35 /* hash */:
                // Only if its the beginning can we have #! trivia
                return pos === 0;
            default:
                return ch > 127 /* maxAsciiCharacter */;
        }
    }
    ts.couldStartTrivia = couldStartTrivia;
    /* @internal */
    function skipTrivia(text, pos, stopAfterLineBreak, stopAtComments) {
        if (stopAtComments === void 0) { stopAtComments = false; }
        if (ts.positionIsSynthesized(pos)) {
            return pos;
        }
        // Keep in sync with couldStartTrivia
        while (true) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    pos++;
                    if (stopAfterLineBreak) {
                        return pos;
                    }
                    continue;
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    pos++;
                    continue;
                case 47 /* slash */:
                    if (stopAtComments) {
                        break;
                    }
                    if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                        pos += 2;
                        while (pos < text.length) {
                            if (isLineBreak(text.charCodeAt(pos))) {
                                break;
                            }
                            pos++;
                        }
                        continue;
                    }
                    if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                        pos += 2;
                        while (pos < text.length) {
                            if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                pos += 2;
                                break;
                            }
                            pos++;
                        }
                        continue;
                    }
                    break;
                case 60 /* lessThan */:
                case 124 /* bar */:
                case 61 /* equals */:
                case 62 /* greaterThan */:
                    if (isConflictMarkerTrivia(text, pos)) {
                        pos = scanConflictMarkerTrivia(text, pos);
                        continue;
                    }
                    break;
                case 35 /* hash */:
                    if (pos === 0 && isShebangTrivia(text, pos)) {
                        pos = scanShebangTrivia(text, pos);
                        continue;
                    }
                    break;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
                        pos++;
                        continue;
                    }
                    break;
            }
            return pos;
        }
    }
    ts.skipTrivia = skipTrivia;
    // All conflict markers consist of the same character repeated seven times.  If it is
    // a <<<<<<< or >>>>>>> marker then it is also followed by a space.
    var mergeConflictMarkerLength = "<<<<<<<".length;
    function isConflictMarkerTrivia(text, pos) {
        ts.Debug.assert(pos >= 0);
        // Conflict markers must be at the start of a line.
        if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) {
            var ch = text.charCodeAt(pos);
            if ((pos + mergeConflictMarkerLength) < text.length) {
                for (var i = 0; i < mergeConflictMarkerLength; i++) {
                    if (text.charCodeAt(pos + i) !== ch) {
                        return false;
                    }
                }
                return ch === 61 /* equals */ ||
                    text.charCodeAt(pos + mergeConflictMarkerLength) === 32 /* space */;
            }
        }
        return false;
    }
    function scanConflictMarkerTrivia(text, pos, error) {
        if (error) {
            error(ts.Diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength);
        }
        var ch = text.charCodeAt(pos);
        var len = text.length;
        if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) {
            while (pos < len && !isLineBreak(text.charCodeAt(pos))) {
                pos++;
            }
        }
        else {
            ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */);
            // Consume everything from the start of a ||||||| or ======= marker to the start
            // of the next ======= or >>>>>>> marker.
            while (pos < len) {
                var currentChar = text.charCodeAt(pos);
                if ((currentChar === 61 /* equals */ || currentChar === 62 /* greaterThan */) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) {
                    break;
                }
                pos++;
            }
        }
        return pos;
    }
    var shebangTriviaRegex = /^#!.*/;
    /*@internal*/
    function isShebangTrivia(text, pos) {
        // Shebangs check must only be done at the start of the file
        ts.Debug.assert(pos === 0);
        return shebangTriviaRegex.test(text);
    }
    ts.isShebangTrivia = isShebangTrivia;
    /*@internal*/
    function scanShebangTrivia(text, pos) {
        var shebang = shebangTriviaRegex.exec(text)[0];
        pos = pos + shebang.length;
        return pos;
    }
    ts.scanShebangTrivia = scanShebangTrivia;
    /**
     * Invokes a callback for each comment range following the provided position.
     *
     * Single-line comment ranges include the leading double-slash characters but not the ending
     * line break. Multi-line comment ranges include the leading slash-asterisk and trailing
     * asterisk-slash characters.
     *
     * @param reduce If true, accumulates the result of calling the callback in a fashion similar
     *      to reduceLeft. If false, iteration stops when the callback returns a truthy value.
     * @param text The source text to scan.
     * @param pos The position at which to start scanning.
     * @param trailing If false, whitespace is skipped until the first line break and comments
     *      between that location and the next token are returned. If true, comments occurring
     *      between the given position and the next line break are returned.
     * @param cb The callback to execute as each comment range is encountered.
     * @param state A state value to pass to each iteration of the callback.
     * @param initial An initial value to pass when accumulating results (when "reduce" is true).
     * @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
     *      return value of the callback.
     */
    function iterateCommentRanges(reduce, text, pos, trailing, cb, state, initial) {
        var pendingPos;
        var pendingEnd;
        var pendingKind;
        var pendingHasTrailingNewLine;
        var hasPendingCommentRange = false;
        var collecting = trailing;
        var accumulator = initial;
        if (pos === 0) {
            collecting = true;
            var shebang = getShebang(text);
            if (shebang) {
                pos = shebang.length;
            }
        }
        scan: while (pos >= 0 && pos < text.length) {
            var ch = text.charCodeAt(pos);
            switch (ch) {
                case 13 /* carriageReturn */:
                    if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                    pos++;
                    if (trailing) {
                        break scan;
                    }
                    collecting = true;
                    if (hasPendingCommentRange) {
                        pendingHasTrailingNewLine = true;
                    }
                    continue;
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    pos++;
                    continue;
                case 47 /* slash */:
                    var nextChar = text.charCodeAt(pos + 1);
                    var hasTrailingNewLine = false;
                    if (nextChar === 47 /* slash */ || nextChar === 42 /* asterisk */) {
                        var kind = nextChar === 47 /* slash */ ? 2 /* SingleLineCommentTrivia */ : 3 /* MultiLineCommentTrivia */;
                        var startPos = pos;
                        pos += 2;
                        if (nextChar === 47 /* slash */) {
                            while (pos < text.length) {
                                if (isLineBreak(text.charCodeAt(pos))) {
                                    hasTrailingNewLine = true;
                                    break;
                                }
                                pos++;
                            }
                        }
                        else {
                            while (pos < text.length) {
                                if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    break;
                                }
                                pos++;
                            }
                        }
                        if (collecting) {
                            if (hasPendingCommentRange) {
                                accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
                                if (!reduce && accumulator) {
                                    // If we are not reducing and we have a truthy result, return it.
                                    return accumulator;
                                }
                            }
                            pendingPos = startPos;
                            pendingEnd = pos;
                            pendingKind = kind;
                            pendingHasTrailingNewLine = hasTrailingNewLine;
                            hasPendingCommentRange = true;
                        }
                        continue;
                    }
                    break scan;
                default:
                    if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) {
                        if (hasPendingCommentRange && isLineBreak(ch)) {
                            pendingHasTrailingNewLine = true;
                        }
                        pos++;
                        continue;
                    }
                    break scan;
            }
        }
        if (hasPendingCommentRange) {
            accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator);
        }
        return accumulator;
    }
    function forEachLeadingCommentRange(text, pos, cb, state) {
        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
    }
    ts.forEachLeadingCommentRange = forEachLeadingCommentRange;
    function forEachTrailingCommentRange(text, pos, cb, state) {
        return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
    }
    ts.forEachTrailingCommentRange = forEachTrailingCommentRange;
    function reduceEachLeadingCommentRange(text, pos, cb, state, initial) {
        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
    }
    ts.reduceEachLeadingCommentRange = reduceEachLeadingCommentRange;
    function reduceEachTrailingCommentRange(text, pos, cb, state, initial) {
        return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
    }
    ts.reduceEachTrailingCommentRange = reduceEachTrailingCommentRange;
    function appendCommentRange(pos, end, kind, hasTrailingNewLine, _state, comments) {
        if (!comments) {
            comments = [];
        }
        comments.push({ kind: kind, pos: pos, end: end, hasTrailingNewLine: hasTrailingNewLine });
        return comments;
    }
    function getLeadingCommentRanges(text, pos) {
        return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
    }
    ts.getLeadingCommentRanges = getLeadingCommentRanges;
    function getTrailingCommentRanges(text, pos) {
        return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined);
    }
    ts.getTrailingCommentRanges = getTrailingCommentRanges;
    /** Optionally, get the shebang */
    function getShebang(text) {
        var match = shebangTriviaRegex.exec(text);
        if (match) {
            return match[0];
        }
    }
    ts.getShebang = getShebang;
    function isIdentifierStart(ch, languageVersion) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
            ch === 36 /* $ */ || ch === 95 /* _ */ ||
            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierStart(ch, languageVersion);
    }
    ts.isIdentifierStart = isIdentifierStart;
    function isIdentifierPart(ch, languageVersion, identifierVariant) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ ||
            ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch === 36 /* $ */ || ch === 95 /* _ */ ||
            // "-" and ":" are valid in JSX Identifiers
            (identifierVariant === 1 /* JSX */ ? (ch === 45 /* minus */ || ch === 58 /* colon */) : false) ||
            ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion);
    }
    ts.isIdentifierPart = isIdentifierPart;
    /* @internal */
    function isIdentifierText(name, languageVersion, identifierVariant) {
        var ch = codePointAt(name, 0);
        if (!isIdentifierStart(ch, languageVersion)) {
            return false;
        }
        for (var i = charSize(ch); i < name.length; i += charSize(ch)) {
            if (!isIdentifierPart(ch = codePointAt(name, i), languageVersion, identifierVariant)) {
                return false;
            }
        }
        return true;
    }
    ts.isIdentifierText = isIdentifierText;
    // Creates a scanner over a (possibly unspecified) range of a piece of text.
    function createScanner(languageVersion, skipTrivia, languageVariant, textInitial, onError, start, length) {
        if (languageVariant === void 0) { languageVariant = 0 /* Standard */; }
        var text = textInitial;
        // Current position (end position of text of current token)
        var pos;
        // end of text
        var end;
        // Start position of whitespace before current token
        var startPos;
        // Start position of text of current token
        var tokenPos;
        var token;
        var tokenValue;
        var tokenFlags;
        var commentDirectives;
        var inJSDocType = 0;
        setText(text, start, length);
        var scanner = {
            getStartPos: function () { return startPos; },
            getTextPos: function () { return pos; },
            getToken: function () { return token; },
            getTokenPos: function () { return tokenPos; },
            getTokenText: function () { return text.substring(tokenPos, pos); },
            getTokenValue: function () { return tokenValue; },
            hasUnicodeEscape: function () { return (tokenFlags & 1024 /* UnicodeEscape */) !== 0; },
            hasExtendedUnicodeEscape: function () { return (tokenFlags & 8 /* ExtendedUnicodeEscape */) !== 0; },
            hasPrecedingLineBreak: function () { return (tokenFlags & 1 /* PrecedingLineBreak */) !== 0; },
            isIdentifier: function () { return token === 75 /* Identifier */ || token > 112 /* LastReservedWord */; },
            isReservedWord: function () { return token >= 77 /* FirstReservedWord */ && token <= 112 /* LastReservedWord */; },
            isUnterminated: function () { return (tokenFlags & 4 /* Unterminated */) !== 0; },
            getCommentDirectives: function () { return commentDirectives; },
            getTokenFlags: function () { return tokenFlags; },
            reScanGreaterToken: reScanGreaterToken,
            reScanSlashToken: reScanSlashToken,
            reScanTemplateToken: reScanTemplateToken,
            reScanTemplateHeadOrNoSubstitutionTemplate: reScanTemplateHeadOrNoSubstitutionTemplate,
            scanJsxIdentifier: scanJsxIdentifier,
            scanJsxAttributeValue: scanJsxAttributeValue,
            reScanJsxAttributeValue: reScanJsxAttributeValue,
            reScanJsxToken: reScanJsxToken,
            reScanLessThanToken: reScanLessThanToken,
            reScanQuestionToken: reScanQuestionToken,
            scanJsxToken: scanJsxToken,
            scanJsDocToken: scanJsDocToken,
            scan: scan,
            getText: getText,
            clearCommentDirectives: clearCommentDirectives,
            setText: setText,
            setScriptTarget: setScriptTarget,
            setLanguageVariant: setLanguageVariant,
            setOnError: setOnError,
            setTextPos: setTextPos,
            setInJSDocType: setInJSDocType,
            tryScan: tryScan,
            lookAhead: lookAhead,
            scanRange: scanRange,
        };
        if (ts.Debug.isDebugging) {
            Object.defineProperty(scanner, "__debugShowCurrentPositionInText", {
                get: function () {
                    var text = scanner.getText();
                    return text.slice(0, scanner.getStartPos()) + "║" + text.slice(scanner.getStartPos());
                },
            });
        }
        return scanner;
        function error(message, errPos, length) {
            if (errPos === void 0) { errPos = pos; }
            if (onError) {
                var oldPos = pos;
                pos = errPos;
                onError(message, length || 0);
                pos = oldPos;
            }
        }
        function scanNumberFragment() {
            var start = pos;
            var allowSeparator = false;
            var isPreviousTokenSeparator = false;
            var result = "";
            while (true) {
                var ch = text.charCodeAt(pos);
                if (ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (allowSeparator) {
                        allowSeparator = false;
                        isPreviousTokenSeparator = true;
                        result += text.substring(start, pos);
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    start = pos;
                    continue;
                }
                if (isDigit(ch)) {
                    allowSeparator = true;
                    isPreviousTokenSeparator = false;
                    pos++;
                    continue;
                }
                break;
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return result + text.substring(start, pos);
        }
        function scanNumber() {
            var start = pos;
            var mainFragment = scanNumberFragment();
            var decimalFragment;
            var scientificFragment;
            if (text.charCodeAt(pos) === 46 /* dot */) {
                pos++;
                decimalFragment = scanNumberFragment();
            }
            var end = pos;
            if (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */) {
                pos++;
                tokenFlags |= 16 /* Scientific */;
                if (text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */)
                    pos++;
                var preNumericPart = pos;
                var finalFragment = scanNumberFragment();
                if (!finalFragment) {
                    error(ts.Diagnostics.Digit_expected);
                }
                else {
                    scientificFragment = text.substring(end, preNumericPart) + finalFragment;
                    end = pos;
                }
            }
            var result;
            if (tokenFlags & 512 /* ContainsSeparator */) {
                result = mainFragment;
                if (decimalFragment) {
                    result += "." + decimalFragment;
                }
                if (scientificFragment) {
                    result += scientificFragment;
                }
            }
            else {
                result = text.substring(start, end); // No need to use all the fragments; no _ removal needed
            }
            if (decimalFragment !== undefined || tokenFlags & 16 /* Scientific */) {
                checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & 16 /* Scientific */));
                return {
                    type: 8 /* NumericLiteral */,
                    value: "" + +result // if value is not an integer, it can be safely coerced to a number
                };
            }
            else {
                tokenValue = result;
                var type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
                checkForIdentifierStartAfterNumericLiteral(start);
                return { type: type, value: tokenValue };
            }
        }
        function checkForIdentifierStartAfterNumericLiteral(numericStart, isScientific) {
            if (!isIdentifierStart(codePointAt(text, pos), languageVersion)) {
                return;
            }
            var identifierStart = pos;
            var length = scanIdentifierParts().length;
            if (length === 1 && text[identifierStart] === "n") {
                if (isScientific) {
                    error(ts.Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1);
                }
                else {
                    error(ts.Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1);
                }
            }
            else {
                error(ts.Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length);
                pos = identifierStart;
            }
        }
        function scanOctalDigits() {
            var start = pos;
            while (isOctalDigit(text.charCodeAt(pos))) {
                pos++;
            }
            return +(text.substring(start, pos));
        }
        /**
         * Scans the given number of hexadecimal digits in the text,
         * returning -1 if the given number is unavailable.
         */
        function scanExactNumberOfHexDigits(count, canHaveSeparators) {
            var valueString = scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators);
            return valueString ? parseInt(valueString, 16) : -1;
        }
        /**
         * Scans as many hexadecimal digits as are available in the text,
         * returning "" if the given number of digits was unavailable.
         */
        function scanMinimumNumberOfHexDigits(count, canHaveSeparators) {
            return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true, canHaveSeparators);
        }
        function scanHexDigits(minCount, scanAsManyAsPossible, canHaveSeparators) {
            var valueChars = [];
            var allowSeparator = false;
            var isPreviousTokenSeparator = false;
            while (valueChars.length < minCount || scanAsManyAsPossible) {
                var ch = text.charCodeAt(pos);
                if (canHaveSeparators && ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (allowSeparator) {
                        allowSeparator = false;
                        isPreviousTokenSeparator = true;
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    continue;
                }
                allowSeparator = canHaveSeparators;
                if (ch >= 65 /* A */ && ch <= 70 /* F */) {
                    ch += 97 /* a */ - 65 /* A */; // standardize hex literals to lowercase
                }
                else if (!((ch >= 48 /* _0 */ && ch <= 57 /* _9 */) ||
                    (ch >= 97 /* a */ && ch <= 102 /* f */))) {
                    break;
                }
                valueChars.push(ch);
                pos++;
                isPreviousTokenSeparator = false;
            }
            if (valueChars.length < minCount) {
                valueChars = [];
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return String.fromCharCode.apply(String, valueChars);
        }
        function scanString(jsxAttributeString) {
            if (jsxAttributeString === void 0) { jsxAttributeString = false; }
            var quote = text.charCodeAt(pos);
            pos++;
            var result = "";
            var start = pos;
            while (true) {
                if (pos >= end) {
                    result += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_string_literal);
                    break;
                }
                var ch = text.charCodeAt(pos);
                if (ch === quote) {
                    result += text.substring(start, pos);
                    pos++;
                    break;
                }
                if (ch === 92 /* backslash */ && !jsxAttributeString) {
                    result += text.substring(start, pos);
                    result += scanEscapeSequence();
                    start = pos;
                    continue;
                }
                if (isLineBreak(ch) && !jsxAttributeString) {
                    result += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_string_literal);
                    break;
                }
                pos++;
            }
            return result;
        }
        /**
         * Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or
         * a literal component of a TemplateExpression.
         */
        function scanTemplateAndSetTokenValue(isTaggedTemplate) {
            var startedWithBacktick = text.charCodeAt(pos) === 96 /* backtick */;
            pos++;
            var start = pos;
            var contents = "";
            var resultingToken;
            while (true) {
                if (pos >= end) {
                    contents += text.substring(start, pos);
                    tokenFlags |= 4 /* Unterminated */;
                    error(ts.Diagnostics.Unterminated_template_literal);
                    resultingToken = startedWithBacktick ? 14 /* NoSubstitutionTemplateLiteral */ : 17 /* TemplateTail */;
                    break;
                }
                var currChar = text.charCodeAt(pos);
                // '`'
                if (currChar === 96 /* backtick */) {
                    contents += text.substring(start, pos);
                    pos++;
                    resultingToken = startedWithBacktick ? 14 /* NoSubstitutionTemplateLiteral */ : 17 /* TemplateTail */;
                    break;
                }
                // '${'
                if (currChar === 36 /* $ */ && pos + 1 < end && text.charCodeAt(pos + 1) === 123 /* openBrace */) {
                    contents += text.substring(start, pos);
                    pos += 2;
                    resultingToken = startedWithBacktick ? 15 /* TemplateHead */ : 16 /* TemplateMiddle */;
                    break;
                }
                // Escape character
                if (currChar === 92 /* backslash */) {
                    contents += text.substring(start, pos);
                    contents += scanEscapeSequence(isTaggedTemplate);
                    start = pos;
                    continue;
                }
                // Speculated ECMAScript 6 Spec 11.8.6.1:
                // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values
                if (currChar === 13 /* carriageReturn */) {
                    contents += text.substring(start, pos);
                    pos++;
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                    contents += "\n";
                    start = pos;
                    continue;
                }
                pos++;
            }
            ts.Debug.assert(resultingToken !== undefined);
            tokenValue = contents;
            return resultingToken;
        }
        function scanEscapeSequence(isTaggedTemplate) {
            var start = pos;
            pos++;
            if (pos >= end) {
                error(ts.Diagnostics.Unexpected_end_of_text);
                return "";
            }
            var ch = text.charCodeAt(pos);
            pos++;
            switch (ch) {
                case 48 /* _0 */:
                    // '\01'
                    if (isTaggedTemplate && pos < end && isDigit(text.charCodeAt(pos))) {
                        pos++;
                        tokenFlags |= 2048 /* ContainsInvalidEscape */;
                        return text.substring(start, pos);
                    }
                    return "\0";
                case 98 /* b */:
                    return "\b";
                case 116 /* t */:
                    return "\t";
                case 110 /* n */:
                    return "\n";
                case 118 /* v */:
                    return "\v";
                case 102 /* f */:
                    return "\f";
                case 114 /* r */:
                    return "\r";
                case 39 /* singleQuote */:
                    return "\'";
                case 34 /* doubleQuote */:
                    return "\"";
                case 117 /* u */:
                    if (isTaggedTemplate) {
                        // '\u' or '\u0' or '\u00' or '\u000'
                        for (var escapePos = pos; escapePos < pos + 4; escapePos++) {
                            if (escapePos < end && !isHexDigit(text.charCodeAt(escapePos)) && text.charCodeAt(escapePos) !== 123 /* openBrace */) {
                                pos = escapePos;
                                tokenFlags |= 2048 /* ContainsInvalidEscape */;
                                return text.substring(start, pos);
                            }
                        }
                    }
                    // '\u{DDDDDDDD}'
                    if (pos < end && text.charCodeAt(pos) === 123 /* openBrace */) {
                        pos++;
                        // '\u{'
                        if (isTaggedTemplate && !isHexDigit(text.charCodeAt(pos))) {
                            tokenFlags |= 2048 /* ContainsInvalidEscape */;
                            return text.substring(start, pos);
                        }
                        if (isTaggedTemplate) {
                            var savePos = pos;
                            var escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
                            var escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
                            // '\u{Not Code Point' or '\u{CodePoint'
                            if (!isCodePoint(escapedValue) || text.charCodeAt(pos) !== 125 /* closeBrace */) {
                                tokenFlags |= 2048 /* ContainsInvalidEscape */;
                                return text.substring(start, pos);
                            }
                            else {
                                pos = savePos;
                            }
                        }
                        tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                        return scanExtendedUnicodeEscape();
                    }
                    tokenFlags |= 1024 /* UnicodeEscape */;
                    // '\uDDDD'
                    return scanHexadecimalEscape(/*numDigits*/ 4);
                case 120 /* x */:
                    if (isTaggedTemplate) {
                        if (!isHexDigit(text.charCodeAt(pos))) {
                            tokenFlags |= 2048 /* ContainsInvalidEscape */;
                            return text.substring(start, pos);
                        }
                        else if (!isHexDigit(text.charCodeAt(pos + 1))) {
                            pos++;
                            tokenFlags |= 2048 /* ContainsInvalidEscape */;
                            return text.substring(start, pos);
                        }
                    }
                    // '\xDD'
                    return scanHexadecimalEscape(/*numDigits*/ 2);
                // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence),
                // the line terminator is interpreted to be "the empty code unit sequence".
                case 13 /* carriageReturn */:
                    if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) {
                        pos++;
                    }
                // falls through
                case 10 /* lineFeed */:
                case 8232 /* lineSeparator */:
                case 8233 /* paragraphSeparator */:
                    return "";
                default:
                    return String.fromCharCode(ch);
            }
        }
        function scanHexadecimalEscape(numDigits) {
            var escapedValue = scanExactNumberOfHexDigits(numDigits, /*canHaveSeparators*/ false);
            if (escapedValue >= 0) {
                return String.fromCharCode(escapedValue);
            }
            else {
                error(ts.Diagnostics.Hexadecimal_digit_expected);
                return "";
            }
        }
        function scanExtendedUnicodeEscape() {
            var escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
            var escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
            var isInvalidExtendedEscape = false;
            // Validate the value of the digit
            if (escapedValue < 0) {
                error(ts.Diagnostics.Hexadecimal_digit_expected);
                isInvalidExtendedEscape = true;
            }
            else if (escapedValue > 0x10FFFF) {
                error(ts.Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive);
                isInvalidExtendedEscape = true;
            }
            if (pos >= end) {
                error(ts.Diagnostics.Unexpected_end_of_text);
                isInvalidExtendedEscape = true;
            }
            else if (text.charCodeAt(pos) === 125 /* closeBrace */) {
                // Only swallow the following character up if it's a '}'.
                pos++;
            }
            else {
                error(ts.Diagnostics.Unterminated_Unicode_escape_sequence);
                isInvalidExtendedEscape = true;
            }
            if (isInvalidExtendedEscape) {
                return "";
            }
            return utf16EncodeAsString(escapedValue);
        }
        // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX'
        // and return code point value if valid Unicode escape is found. Otherwise return -1.
        function peekUnicodeEscape() {
            if (pos + 5 < end && text.charCodeAt(pos + 1) === 117 /* u */) {
                var start_1 = pos;
                pos += 2;
                var value = scanExactNumberOfHexDigits(4, /*canHaveSeparators*/ false);
                pos = start_1;
                return value;
            }
            return -1;
        }
        function peekExtendedUnicodeEscape() {
            if (languageVersion >= 2 /* ES2015 */ && codePointAt(text, pos + 1) === 117 /* u */ && codePointAt(text, pos + 2) === 123 /* openBrace */) {
                var start_2 = pos;
                pos += 3;
                var escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
                var escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
                pos = start_2;
                return escapedValue;
            }
            return -1;
        }
        function scanIdentifierParts() {
            var result = "";
            var start = pos;
            while (pos < end) {
                var ch = codePointAt(text, pos);
                if (isIdentifierPart(ch, languageVersion)) {
                    pos += charSize(ch);
                }
                else if (ch === 92 /* backslash */) {
                    ch = peekExtendedUnicodeEscape();
                    if (ch >= 0 && isIdentifierPart(ch, languageVersion)) {
                        pos += 3;
                        tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                        result += scanExtendedUnicodeEscape();
                        start = pos;
                        continue;
                    }
                    ch = peekUnicodeEscape();
                    if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) {
                        break;
                    }
                    tokenFlags |= 1024 /* UnicodeEscape */;
                    result += text.substring(start, pos);
                    result += utf16EncodeAsString(ch);
                    // Valid Unicode escape is always six characters
                    pos += 6;
                    start = pos;
                }
                else {
                    break;
                }
            }
            result += text.substring(start, pos);
            return result;
        }
        function getIdentifierToken() {
            // Reserved words are between 2 and 11 characters long and start with a lowercase letter
            var len = tokenValue.length;
            if (len >= 2 && len <= 11) {
                var ch = tokenValue.charCodeAt(0);
                if (ch >= 97 /* a */ && ch <= 122 /* z */) {
                    var keyword = textToKeyword.get(tokenValue);
                    if (keyword !== undefined) {
                        return token = keyword;
                    }
                }
            }
            return token = 75 /* Identifier */;
        }
        function scanBinaryOrOctalDigits(base) {
            var value = "";
            // For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
            // Similarly valid octalIntegerLiteral must have at least one octal digit following o or O.
            var separatorAllowed = false;
            var isPreviousTokenSeparator = false;
            while (true) {
                var ch = text.charCodeAt(pos);
                // Numeric separators are allowed anywhere within a numeric literal, except not at the beginning, or following another separator
                if (ch === 95 /* _ */) {
                    tokenFlags |= 512 /* ContainsSeparator */;
                    if (separatorAllowed) {
                        separatorAllowed = false;
                        isPreviousTokenSeparator = true;
                    }
                    else if (isPreviousTokenSeparator) {
                        error(ts.Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
                    }
                    else {
                        error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
                    }
                    pos++;
                    continue;
                }
                separatorAllowed = true;
                if (!isDigit(ch) || ch - 48 /* _0 */ >= base) {
                    break;
                }
                value += text[pos];
                pos++;
                isPreviousTokenSeparator = false;
            }
            if (text.charCodeAt(pos - 1) === 95 /* _ */) {
                // Literal ends with underscore - not allowed
                error(ts.Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
            }
            return value;
        }
        function checkBigIntSuffix() {
            if (text.charCodeAt(pos) === 110 /* n */) {
                tokenValue += "n";
                // Use base 10 instead of base 2 or base 8 for shorter literals
                if (tokenFlags & 384 /* BinaryOrOctalSpecifier */) {
                    tokenValue = ts.parsePseudoBigInt(tokenValue) + "n";
                }
                pos++;
                return 9 /* BigIntLiteral */;
            }
            else { // not a bigint, so can convert to number in simplified form
                // Number() may not support 0b or 0o, so use parseInt() instead
                var numericValue = tokenFlags & 128 /* BinarySpecifier */
                    ? parseInt(tokenValue.slice(2), 2) // skip "0b"
                    : tokenFlags & 256 /* OctalSpecifier */
                        ? parseInt(tokenValue.slice(2), 8) // skip "0o"
                        : +tokenValue;
                tokenValue = "" + numericValue;
                return 8 /* NumericLiteral */;
            }
        }
        function scan() {
            var _a;
            startPos = pos;
            tokenFlags = 0 /* None */;
            var asteriskSeen = false;
            while (true) {
                tokenPos = pos;
                if (pos >= end) {
                    return token = 1 /* EndOfFileToken */;
                }
                var ch = codePointAt(text, pos);
                // Special handling for shebang
                if (ch === 35 /* hash */ && pos === 0 && isShebangTrivia(text, pos)) {
                    pos = scanShebangTrivia(text, pos);
                    if (skipTrivia) {
                        continue;
                    }
                    else {
                        return token = 6 /* ShebangTrivia */;
                    }
                }
                switch (ch) {
                    case 10 /* lineFeed */:
                    case 13 /* carriageReturn */:
                        tokenFlags |= 1 /* PrecedingLineBreak */;
                        if (skipTrivia) {
                            pos++;
                            continue;
                        }
                        else {
                            if (ch === 13 /* carriageReturn */ && pos + 1 < end && text.charCodeAt(pos + 1) === 10 /* lineFeed */) {
                                // consume both CR and LF
                                pos += 2;
                            }
                            else {
                                pos++;
                            }
                            return token = 4 /* NewLineTrivia */;
                        }
                    case 9 /* tab */:
                    case 11 /* verticalTab */:
                    case 12 /* formFeed */:
                    case 32 /* space */:
                    case 160 /* nonBreakingSpace */:
                    case 5760 /* ogham */:
                    case 8192 /* enQuad */:
                    case 8193 /* emQuad */:
                    case 8194 /* enSpace */:
                    case 8195 /* emSpace */:
                    case 8196 /* threePerEmSpace */:
                    case 8197 /* fourPerEmSpace */:
                    case 8198 /* sixPerEmSpace */:
                    case 8199 /* figureSpace */:
                    case 8200 /* punctuationSpace */:
                    case 8201 /* thinSpace */:
                    case 8202 /* hairSpace */:
                    case 8203 /* zeroWidthSpace */:
                    case 8239 /* narrowNoBreakSpace */:
                    case 8287 /* mathematicalSpace */:
                    case 12288 /* ideographicSpace */:
                    case 65279 /* byteOrderMark */:
                        if (skipTrivia) {
                            pos++;
                            continue;
                        }
                        else {
                            while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
                                pos++;
                            }
                            return token = 5 /* WhitespaceTrivia */;
                        }
                    case 33 /* exclamation */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 37 /* ExclamationEqualsEqualsToken */;
                            }
                            return pos += 2, token = 35 /* ExclamationEqualsToken */;
                        }
                        pos++;
                        return token = 53 /* ExclamationToken */;
                    case 34 /* doubleQuote */:
                    case 39 /* singleQuote */:
                        tokenValue = scanString();
                        return token = 10 /* StringLiteral */;
                    case 96 /* backtick */:
                        return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ false);
                    case 37 /* percent */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 68 /* PercentEqualsToken */;
                        }
                        pos++;
                        return token = 44 /* PercentToken */;
                    case 38 /* ampersand */:
                        if (text.charCodeAt(pos + 1) === 38 /* ampersand */) {
                            return pos += 2, token = 55 /* AmpersandAmpersandToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 72 /* AmpersandEqualsToken */;
                        }
                        pos++;
                        return token = 50 /* AmpersandToken */;
                    case 40 /* openParen */:
                        pos++;
                        return token = 20 /* OpenParenToken */;
                    case 41 /* closeParen */:
                        pos++;
                        return token = 21 /* CloseParenToken */;
                    case 42 /* asterisk */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 65 /* AsteriskEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 66 /* AsteriskAsteriskEqualsToken */;
                            }
                            return pos += 2, token = 42 /* AsteriskAsteriskToken */;
                        }
                        pos++;
                        if (inJSDocType && !asteriskSeen && (tokenFlags & 1 /* PrecedingLineBreak */)) {
                            // decoration at the start of a JSDoc comment line
                            asteriskSeen = true;
                            continue;
                        }
                        return token = 41 /* AsteriskToken */;
                    case 43 /* plus */:
                        if (text.charCodeAt(pos + 1) === 43 /* plus */) {
                            return pos += 2, token = 45 /* PlusPlusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 63 /* PlusEqualsToken */;
                        }
                        pos++;
                        return token = 39 /* PlusToken */;
                    case 44 /* comma */:
                        pos++;
                        return token = 27 /* CommaToken */;
                    case 45 /* minus */:
                        if (text.charCodeAt(pos + 1) === 45 /* minus */) {
                            return pos += 2, token = 46 /* MinusMinusToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 64 /* MinusEqualsToken */;
                        }
                        pos++;
                        return token = 40 /* MinusToken */;
                    case 46 /* dot */:
                        if (isDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = scanNumber().value;
                            return token = 8 /* NumericLiteral */;
                        }
                        if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) {
                            return pos += 3, token = 25 /* DotDotDotToken */;
                        }
                        pos++;
                        return token = 24 /* DotToken */;
                    case 47 /* slash */:
                        // Single-line comment
                        if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                            pos += 2;
                            while (pos < end) {
                                if (isLineBreak(text.charCodeAt(pos))) {
                                    break;
                                }
                                pos++;
                            }
                            commentDirectives = appendIfCommentDirective(commentDirectives, text.slice(tokenPos, pos), commentDirectiveRegExSingleLine, tokenPos);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 2 /* SingleLineCommentTrivia */;
                            }
                        }
                        // Multi-line comment
                        if (text.charCodeAt(pos + 1) === 42 /* asterisk */) {
                            pos += 2;
                            if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) !== 47 /* slash */) {
                                tokenFlags |= 2 /* PrecedingJSDocComment */;
                            }
                            var commentClosed = false;
                            var lastLineStart = tokenPos;
                            while (pos < end) {
                                var ch_1 = text.charCodeAt(pos);
                                if (ch_1 === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) {
                                    pos += 2;
                                    commentClosed = true;
                                    break;
                                }
                                pos++;
                                if (isLineBreak(ch_1)) {
                                    lastLineStart = pos;
                                    tokenFlags |= 1 /* PrecedingLineBreak */;
                                }
                            }
                            commentDirectives = appendIfCommentDirective(commentDirectives, text.slice(lastLineStart, pos), commentDirectiveRegExMultiLine, lastLineStart);
                            if (!commentClosed) {
                                error(ts.Diagnostics.Asterisk_Slash_expected);
                            }
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                if (!commentClosed) {
                                    tokenFlags |= 4 /* Unterminated */;
                                }
                                return token = 3 /* MultiLineCommentTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 67 /* SlashEqualsToken */;
                        }
                        pos++;
                        return token = 43 /* SlashToken */;
                    case 48 /* _0 */:
                        if (pos + 2 < end && (text.charCodeAt(pos + 1) === 88 /* X */ || text.charCodeAt(pos + 1) === 120 /* x */)) {
                            pos += 2;
                            tokenValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Hexadecimal_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0x" + tokenValue;
                            tokenFlags |= 64 /* HexSpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 66 /* B */ || text.charCodeAt(pos + 1) === 98 /* b */)) {
                            pos += 2;
                            tokenValue = scanBinaryOrOctalDigits(/* base */ 2);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Binary_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0b" + tokenValue;
                            tokenFlags |= 128 /* BinarySpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 79 /* O */ || text.charCodeAt(pos + 1) === 111 /* o */)) {
                            pos += 2;
                            tokenValue = scanBinaryOrOctalDigits(/* base */ 8);
                            if (!tokenValue) {
                                error(ts.Diagnostics.Octal_digit_expected);
                                tokenValue = "0";
                            }
                            tokenValue = "0o" + tokenValue;
                            tokenFlags |= 256 /* OctalSpecifier */;
                            return token = checkBigIntSuffix();
                        }
                        // Try to parse as an octal
                        if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
                            tokenValue = "" + scanOctalDigits();
                            tokenFlags |= 32 /* Octal */;
                            return token = 8 /* NumericLiteral */;
                        }
                    // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero
                    // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being
                    // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do).
                    // falls through
                    case 49 /* _1 */:
                    case 50 /* _2 */:
                    case 51 /* _3 */:
                    case 52 /* _4 */:
                    case 53 /* _5 */:
                    case 54 /* _6 */:
                    case 55 /* _7 */:
                    case 56 /* _8 */:
                    case 57 /* _9 */:
                        (_a = scanNumber(), token = _a.type, tokenValue = _a.value);
                        return token;
                    case 58 /* colon */:
                        pos++;
                        return token = 58 /* ColonToken */;
                    case 59 /* semicolon */:
                        pos++;
                        return token = 26 /* SemicolonToken */;
                    case 60 /* lessThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 60 /* lessThan */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 69 /* LessThanLessThanEqualsToken */;
                            }
                            return pos += 2, token = 47 /* LessThanLessThanToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 32 /* LessThanEqualsToken */;
                        }
                        if (languageVariant === 1 /* JSX */ &&
                            text.charCodeAt(pos + 1) === 47 /* slash */ &&
                            text.charCodeAt(pos + 2) !== 42 /* asterisk */) {
                            return pos += 2, token = 30 /* LessThanSlashToken */;
                        }
                        pos++;
                        return token = 29 /* LessThanToken */;
                    case 61 /* equals */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                                return pos += 3, token = 36 /* EqualsEqualsEqualsToken */;
                            }
                            return pos += 2, token = 34 /* EqualsEqualsToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                            return pos += 2, token = 38 /* EqualsGreaterThanToken */;
                        }
                        pos++;
                        return token = 62 /* EqualsToken */;
                    case 62 /* greaterThan */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        pos++;
                        return token = 31 /* GreaterThanToken */;
                    case 63 /* question */:
                        pos++;
                        if (text.charCodeAt(pos) === 46 /* dot */ && !isDigit(text.charCodeAt(pos + 1))) {
                            pos++;
                            return token = 28 /* QuestionDotToken */;
                        }
                        if (text.charCodeAt(pos) === 63 /* question */) {
                            pos++;
                            return token = 60 /* QuestionQuestionToken */;
                        }
                        return token = 57 /* QuestionToken */;
                    case 91 /* openBracket */:
                        pos++;
                        return token = 22 /* OpenBracketToken */;
                    case 93 /* closeBracket */:
                        pos++;
                        return token = 23 /* CloseBracketToken */;
                    case 94 /* caret */:
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 74 /* CaretEqualsToken */;
                        }
                        pos++;
                        return token = 52 /* CaretToken */;
                    case 123 /* openBrace */:
                        pos++;
                        return token = 18 /* OpenBraceToken */;
                    case 124 /* bar */:
                        if (isConflictMarkerTrivia(text, pos)) {
                            pos = scanConflictMarkerTrivia(text, pos, error);
                            if (skipTrivia) {
                                continue;
                            }
                            else {
                                return token = 7 /* ConflictMarkerTrivia */;
                            }
                        }
                        if (text.charCodeAt(pos + 1) === 124 /* bar */) {
                            return pos += 2, token = 56 /* BarBarToken */;
                        }
                        if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                            return pos += 2, token = 73 /* BarEqualsToken */;
                        }
                        pos++;
                        return token = 51 /* BarToken */;
                    case 125 /* closeBrace */:
                        pos++;
                        return token = 19 /* CloseBraceToken */;
                    case 126 /* tilde */:
                        pos++;
                        return token = 54 /* TildeToken */;
                    case 64 /* at */:
                        pos++;
                        return token = 59 /* AtToken */;
                    case 92 /* backslash */:
                        var extendedCookedChar = peekExtendedUnicodeEscape();
                        if (extendedCookedChar >= 0 && isIdentifierStart(extendedCookedChar, languageVersion)) {
                            pos += 3;
                            tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                            tokenValue = scanExtendedUnicodeEscape() + scanIdentifierParts();
                            return token = getIdentifierToken();
                        }
                        var cookedChar = peekUnicodeEscape();
                        if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) {
                            pos += 6;
                            tokenFlags |= 1024 /* UnicodeEscape */;
                            tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts();
                            return token = getIdentifierToken();
                        }
                        error(ts.Diagnostics.Invalid_character);
                        pos++;
                        return token = 0 /* Unknown */;
                    case 35 /* hash */:
                        if (pos !== 0 && text[pos + 1] === "!") {
                            error(ts.Diagnostics.can_only_be_used_at_the_start_of_a_file);
                            pos++;
                            return token = 0 /* Unknown */;
                        }
                        pos++;
                        if (isIdentifierStart(ch = text.charCodeAt(pos), languageVersion)) {
                            pos++;
                            while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion))
                                pos++;
                            tokenValue = text.substring(tokenPos, pos);
                            if (ch === 92 /* backslash */) {
                                tokenValue += scanIdentifierParts();
                            }
                        }
                        else {
                            tokenValue = "#";
                            error(ts.Diagnostics.Invalid_character);
                        }
                        return token = 76 /* PrivateIdentifier */;
                    default:
                        if (isIdentifierStart(ch, languageVersion)) {
                            pos += charSize(ch);
                            while (pos < end && isIdentifierPart(ch = codePointAt(text, pos), languageVersion))
                                pos += charSize(ch);
                            tokenValue = text.substring(tokenPos, pos);
                            if (ch === 92 /* backslash */) {
                                tokenValue += scanIdentifierParts();
                            }
                            return token = getIdentifierToken();
                        }
                        else if (isWhiteSpaceSingleLine(ch)) {
                            pos += charSize(ch);
                            continue;
                        }
                        else if (isLineBreak(ch)) {
                            tokenFlags |= 1 /* PrecedingLineBreak */;
                            pos += charSize(ch);
                            continue;
                        }
                        error(ts.Diagnostics.Invalid_character);
                        pos += charSize(ch);
                        return token = 0 /* Unknown */;
                }
            }
        }
        function reScanGreaterToken() {
            if (token === 31 /* GreaterThanToken */) {
                if (text.charCodeAt(pos) === 62 /* greaterThan */) {
                    if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) {
                        if (text.charCodeAt(pos + 2) === 61 /* equals */) {
                            return pos += 3, token = 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */;
                        }
                        return pos += 2, token = 49 /* GreaterThanGreaterThanGreaterThanToken */;
                    }
                    if (text.charCodeAt(pos + 1) === 61 /* equals */) {
                        return pos += 2, token = 70 /* GreaterThanGreaterThanEqualsToken */;
                    }
                    pos++;
                    return token = 48 /* GreaterThanGreaterThanToken */;
                }
                if (text.charCodeAt(pos) === 61 /* equals */) {
                    pos++;
                    return token = 33 /* GreaterThanEqualsToken */;
                }
            }
            return token;
        }
        function reScanSlashToken() {
            if (token === 43 /* SlashToken */ || token === 67 /* SlashEqualsToken */) {
                var p = tokenPos + 1;
                var inEscape = false;
                var inCharacterClass = false;
                while (true) {
                    // If we reach the end of a file, or hit a newline, then this is an unterminated
                    // regex.  Report error and return what we have so far.
                    if (p >= end) {
                        tokenFlags |= 4 /* Unterminated */;
                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
                        break;
                    }
                    var ch = text.charCodeAt(p);
                    if (isLineBreak(ch)) {
                        tokenFlags |= 4 /* Unterminated */;
                        error(ts.Diagnostics.Unterminated_regular_expression_literal);
                        break;
                    }
                    if (inEscape) {
                        // Parsing an escape character;
                        // reset the flag and just advance to the next char.
                        inEscape = false;
                    }
                    else if (ch === 47 /* slash */ && !inCharacterClass) {
                        // A slash within a character class is permissible,
                        // but in general it signals the end of the regexp literal.
                        p++;
                        break;
                    }
                    else if (ch === 91 /* openBracket */) {
                        inCharacterClass = true;
                    }
                    else if (ch === 92 /* backslash */) {
                        inEscape = true;
                    }
                    else if (ch === 93 /* closeBracket */) {
                        inCharacterClass = false;
                    }
                    p++;
                }
                while (p < end && isIdentifierPart(text.charCodeAt(p), languageVersion)) {
                    p++;
                }
                pos = p;
                tokenValue = text.substring(tokenPos, pos);
                token = 13 /* RegularExpressionLiteral */;
            }
            return token;
        }
        function appendIfCommentDirective(commentDirectives, text, commentDirectiveRegEx, lineStart) {
            var type = getDirectiveFromComment(text, commentDirectiveRegEx);
            if (type === undefined) {
                return commentDirectives;
            }
            return ts.append(commentDirectives, {
                range: { pos: lineStart, end: pos },
                type: type,
            });
        }
        function getDirectiveFromComment(text, commentDirectiveRegEx) {
            var match = commentDirectiveRegEx.exec(text);
            if (!match) {
                return undefined;
            }
            switch (match[1]) {
                case "ts-expect-error":
                    return 0 /* ExpectError */;
                case "ts-ignore":
                    return 1 /* Ignore */;
            }
            return undefined;
        }
        /**
         * Unconditionally back up and scan a template expression portion.
         */
        function reScanTemplateToken(isTaggedTemplate) {
            ts.Debug.assert(token === 19 /* CloseBraceToken */, "'reScanTemplateToken' should only be called on a '}'");
            pos = tokenPos;
            return token = scanTemplateAndSetTokenValue(isTaggedTemplate);
        }
        function reScanTemplateHeadOrNoSubstitutionTemplate() {
            pos = tokenPos;
            return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ true);
        }
        function reScanJsxToken() {
            pos = tokenPos = startPos;
            return token = scanJsxToken();
        }
        function reScanLessThanToken() {
            if (token === 47 /* LessThanLessThanToken */) {
                pos = tokenPos + 1;
                return token = 29 /* LessThanToken */;
            }
            return token;
        }
        function reScanQuestionToken() {
            ts.Debug.assert(token === 60 /* QuestionQuestionToken */, "'reScanQuestionToken' should only be called on a '??'");
            pos = tokenPos + 1;
            return token = 57 /* QuestionToken */;
        }
        function scanJsxToken() {
            startPos = tokenPos = pos;
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            var char = text.charCodeAt(pos);
            if (char === 60 /* lessThan */) {
                if (text.charCodeAt(pos + 1) === 47 /* slash */) {
                    pos += 2;
                    return token = 30 /* LessThanSlashToken */;
                }
                pos++;
                return token = 29 /* LessThanToken */;
            }
            if (char === 123 /* openBrace */) {
                pos++;
                return token = 18 /* OpenBraceToken */;
            }
            // First non-whitespace character on this line.
            var firstNonWhitespace = 0;
            var lastNonWhitespace = -1;
            // These initial values are special because the first line is:
            // firstNonWhitespace = 0 to indicate that we want leading whitespace,
            while (pos < end) {
                // We want to keep track of the last non-whitespace (but including
                // newlines character for hitting the end of the JSX Text region)
                if (!isWhiteSpaceSingleLine(char)) {
                    lastNonWhitespace = pos;
                }
                char = text.charCodeAt(pos);
                if (char === 123 /* openBrace */) {
                    break;
                }
                if (char === 60 /* lessThan */) {
                    if (isConflictMarkerTrivia(text, pos)) {
                        pos = scanConflictMarkerTrivia(text, pos, error);
                        return token = 7 /* ConflictMarkerTrivia */;
                    }
                    break;
                }
                if (char === 62 /* greaterThan */) {
                    error(ts.Diagnostics.Unexpected_token_Did_you_mean_or_gt, pos, 1);
                }
                if (char === 125 /* closeBrace */) {
                    error(ts.Diagnostics.Unexpected_token_Did_you_mean_or_rbrace, pos, 1);
                }
                if (lastNonWhitespace > 0)
                    lastNonWhitespace++;
                // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces.
                // i.e (- : whitespace)
                //      <div>----
                //      </div> becomes <div></div>
                //
                //      <div>----</div> becomes <div>----</div>
                if (isLineBreak(char) && firstNonWhitespace === 0) {
                    firstNonWhitespace = -1;
                }
                else if (!isWhiteSpaceLike(char)) {
                    firstNonWhitespace = pos;
                }
                pos++;
            }
            var endPosition = lastNonWhitespace === -1 ? pos : lastNonWhitespace;
            tokenValue = text.substring(startPos, endPosition);
            return firstNonWhitespace === -1 ? 12 /* JsxTextAllWhiteSpaces */ : 11 /* JsxText */;
        }
        // Scans a JSX identifier; these differ from normal identifiers in that
        // they allow dashes
        function scanJsxIdentifier() {
            if (tokenIsIdentifierOrKeyword(token)) {
                // An identifier or keyword has already been parsed - check for a `-` and then append it and everything after it to the token
                // Do note that this means that `scanJsxIdentifier` effectively _mutates_ the visible token without advancing to a new token
                // Any caller should be expecting this behavior and should only read the pos or token value after calling it.
                while (pos < end) {
                    var ch = text.charCodeAt(pos);
                    if (ch === 45 /* minus */) {
                        tokenValue += "-";
                        pos++;
                        continue;
                    }
                    var oldPos = pos;
                    tokenValue += scanIdentifierParts(); // reuse `scanIdentifierParts` so unicode escapes are handled
                    if (pos === oldPos) {
                        break;
                    }
                }
            }
            return token;
        }
        function scanJsxAttributeValue() {
            startPos = pos;
            switch (text.charCodeAt(pos)) {
                case 34 /* doubleQuote */:
                case 39 /* singleQuote */:
                    tokenValue = scanString(/*jsxAttributeString*/ true);
                    return token = 10 /* StringLiteral */;
                default:
                    // If this scans anything other than `{`, it's a parse error.
                    return scan();
            }
        }
        function reScanJsxAttributeValue() {
            pos = tokenPos = startPos;
            return scanJsxAttributeValue();
        }
        function scanJsDocToken() {
            startPos = tokenPos = pos;
            tokenFlags = 0 /* None */;
            if (pos >= end) {
                return token = 1 /* EndOfFileToken */;
            }
            var ch = codePointAt(text, pos);
            pos += charSize(ch);
            switch (ch) {
                case 9 /* tab */:
                case 11 /* verticalTab */:
                case 12 /* formFeed */:
                case 32 /* space */:
                    while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) {
                        pos++;
                    }
                    return token = 5 /* WhitespaceTrivia */;
                case 64 /* at */:
                    return token = 59 /* AtToken */;
                case 10 /* lineFeed */:
                case 13 /* carriageReturn */:
                    tokenFlags |= 1 /* PrecedingLineBreak */;
                    return token = 4 /* NewLineTrivia */;
                case 42 /* asterisk */:
                    return token = 41 /* AsteriskToken */;
                case 123 /* openBrace */:
                    return token = 18 /* OpenBraceToken */;
                case 125 /* closeBrace */:
                    return token = 19 /* CloseBraceToken */;
                case 91 /* openBracket */:
                    return token = 22 /* OpenBracketToken */;
                case 93 /* closeBracket */:
                    return token = 23 /* CloseBracketToken */;
                case 60 /* lessThan */:
                    return token = 29 /* LessThanToken */;
                case 62 /* greaterThan */:
                    return token = 31 /* GreaterThanToken */;
                case 61 /* equals */:
                    return token = 62 /* EqualsToken */;
                case 44 /* comma */:
                    return token = 27 /* CommaToken */;
                case 46 /* dot */:
                    return token = 24 /* DotToken */;
                case 96 /* backtick */:
                    return token = 61 /* BacktickToken */;
                case 92 /* backslash */:
                    pos--;
                    var extendedCookedChar = peekExtendedUnicodeEscape();
                    if (extendedCookedChar >= 0 && isIdentifierStart(extendedCookedChar, languageVersion)) {
                        pos += 3;
                        tokenFlags |= 8 /* ExtendedUnicodeEscape */;
                        tokenValue = scanExtendedUnicodeEscape() + scanIdentifierParts();
                        return token = getIdentifierToken();
                    }
                    var cookedChar = peekUnicodeEscape();
                    if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) {
                        pos += 6;
                        tokenFlags |= 1024 /* UnicodeEscape */;
                        tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts();
                        return token = getIdentifierToken();
                    }
                    pos++;
                    return token = 0 /* Unknown */;
            }
            if (isIdentifierStart(ch, languageVersion)) {
                var char = ch;
                while (pos < end && isIdentifierPart(char = codePointAt(text, pos), languageVersion) || text.charCodeAt(pos) === 45 /* minus */)
                    pos += charSize(char);
                tokenValue = text.substring(tokenPos, pos);
                if (char === 92 /* backslash */) {
                    tokenValue += scanIdentifierParts();
                }
                return token = getIdentifierToken();
            }
            else {
                return token = 0 /* Unknown */;
            }
        }
        function speculationHelper(callback, isLookahead) {
            var savePos = pos;
            var saveStartPos = startPos;
            var saveTokenPos = tokenPos;
            var saveToken = token;
            var saveTokenValue = tokenValue;
            var saveTokenFlags = tokenFlags;
            var result = callback();
            // If our callback returned something 'falsy' or we're just looking ahead,
            // then unconditionally restore us to where we were.
            if (!result || isLookahead) {
                pos = savePos;
                startPos = saveStartPos;
                tokenPos = saveTokenPos;
                token = saveToken;
                tokenValue = saveTokenValue;
                tokenFlags = saveTokenFlags;
            }
            return result;
        }
        function scanRange(start, length, callback) {
            var saveEnd = end;
            var savePos = pos;
            var saveStartPos = startPos;
            var saveTokenPos = tokenPos;
            var saveToken = token;
            var saveTokenValue = tokenValue;
            var saveTokenFlags = tokenFlags;
            var saveErrorExpectations = commentDirectives;
            setText(text, start, length);
            var result = callback();
            end = saveEnd;
            pos = savePos;
            startPos = saveStartPos;
            tokenPos = saveTokenPos;
            token = saveToken;
            tokenValue = saveTokenValue;
            tokenFlags = saveTokenFlags;
            commentDirectives = saveErrorExpectations;
            return result;
        }
        function lookAhead(callback) {
            return speculationHelper(callback, /*isLookahead*/ true);
        }
        function tryScan(callback) {
            return speculationHelper(callback, /*isLookahead*/ false);
        }
        function getText() {
            return text;
        }
        function clearCommentDirectives() {
            commentDirectives = undefined;
        }
        function setText(newText, start, length) {
            text = newText || "";
            end = length === undefined ? text.length : start + length;
            setTextPos(start || 0);
        }
        function setOnError(errorCallback) {
            onError = errorCallback;
        }
        function setScriptTarget(scriptTarget) {
            languageVersion = scriptTarget;
        }
        function setLanguageVariant(variant) {
            languageVariant = variant;
        }
        function setTextPos(textPos) {
            ts.Debug.assert(textPos >= 0);
            pos = textPos;
            startPos = textPos;
            tokenPos = textPos;
            token = 0 /* Unknown */;
            tokenValue = undefined;
            tokenFlags = 0 /* None */;
        }
        function setInJSDocType(inType) {
            inJSDocType += inType ? 1 : -1;
        }
    }
    ts.createScanner = createScanner;
    /* @internal */
    var codePointAt = String.prototype.codePointAt ? function (s, i) { return s.codePointAt(i); } : function codePointAt(str, i) {
        // from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt
        var size = str.length;
        // Account for out-of-bounds indices:
        if (i < 0 || i >= size) {
            return undefined; // String.codePointAt returns `undefined` for OOB indexes
        }
        // Get the first code unit
        var first = str.charCodeAt(i);
        // check if it’s the start of a surrogate pair
        if (first >= 0xD800 && first <= 0xDBFF && size > i + 1) { // high surrogate and there is a next code unit
            var second = str.charCodeAt(i + 1);
            if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
                // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
                return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
            }
        }
        return first;
    };
    /* @internal */
    function charSize(ch) {
        if (ch >= 0x10000) {
            return 2;
        }
        return 1;
    }
    // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec.
    function utf16EncodeAsStringFallback(codePoint) {
        ts.Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF);
        if (codePoint <= 65535) {
            return String.fromCharCode(codePoint);
        }
        var codeUnit1 = Math.floor((codePoint - 65536) / 1024) + 0xD800;
        var codeUnit2 = ((codePoint - 65536) % 1024) + 0xDC00;
        return String.fromCharCode(codeUnit1, codeUnit2);
    }
    var utf16EncodeAsStringWorker = String.fromCodePoint ? function (codePoint) { return String.fromCodePoint(codePoint); } : utf16EncodeAsStringFallback;
    /* @internal */
    function utf16EncodeAsString(codePoint) {
        return utf16EncodeAsStringWorker(codePoint);
    }
    ts.utf16EncodeAsString = utf16EncodeAsString;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function isExternalModuleNameRelative(moduleName) {
        // TypeScript 1.0 spec (April 2014): 11.2.1
        // An external module name is "relative" if the first term is "." or "..".
        // Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module.
        return ts.pathIsRelative(moduleName) || ts.isRootedDiskPath(moduleName);
    }
    ts.isExternalModuleNameRelative = isExternalModuleNameRelative;
    function sortAndDeduplicateDiagnostics(diagnostics) {
        return ts.sortAndDeduplicate(diagnostics, ts.compareDiagnostics);
    }
    ts.sortAndDeduplicateDiagnostics = sortAndDeduplicateDiagnostics;
    function getDefaultLibFileName(options) {
        switch (options.target) {
            case 99 /* ESNext */:
                return "lib.esnext.full.d.ts";
            case 7 /* ES2020 */:
                return "lib.es2020.full.d.ts";
            case 6 /* ES2019 */:
                return "lib.es2019.full.d.ts";
            case 5 /* ES2018 */:
                return "lib.es2018.full.d.ts";
            case 4 /* ES2017 */:
                return "lib.es2017.full.d.ts";
            case 3 /* ES2016 */:
                return "lib.es2016.full.d.ts";
            case 2 /* ES2015 */:
                return "lib.es6.d.ts"; // We don't use lib.es2015.full.d.ts due to breaking change.
            default:
                return "lib.d.ts";
        }
    }
    ts.getDefaultLibFileName = getDefaultLibFileName;
    function textSpanEnd(span) {
        return span.start + span.length;
    }
    ts.textSpanEnd = textSpanEnd;
    function textSpanIsEmpty(span) {
        return span.length === 0;
    }
    ts.textSpanIsEmpty = textSpanIsEmpty;
    function textSpanContainsPosition(span, position) {
        return position >= span.start && position < textSpanEnd(span);
    }
    ts.textSpanContainsPosition = textSpanContainsPosition;
    /* @internal */
    function textRangeContainsPositionInclusive(span, position) {
        return position >= span.pos && position <= span.end;
    }
    ts.textRangeContainsPositionInclusive = textRangeContainsPositionInclusive;
    // Returns true if 'span' contains 'other'.
    function textSpanContainsTextSpan(span, other) {
        return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span);
    }
    ts.textSpanContainsTextSpan = textSpanContainsTextSpan;
    function textSpanOverlapsWith(span, other) {
        return textSpanOverlap(span, other) !== undefined;
    }
    ts.textSpanOverlapsWith = textSpanOverlapsWith;
    function textSpanOverlap(span1, span2) {
        var overlap = textSpanIntersection(span1, span2);
        return overlap && overlap.length === 0 ? undefined : overlap;
    }
    ts.textSpanOverlap = textSpanOverlap;
    function textSpanIntersectsWithTextSpan(span, other) {
        return decodedTextSpanIntersectsWith(span.start, span.length, other.start, other.length);
    }
    ts.textSpanIntersectsWithTextSpan = textSpanIntersectsWithTextSpan;
    function textSpanIntersectsWith(span, start, length) {
        return decodedTextSpanIntersectsWith(span.start, span.length, start, length);
    }
    ts.textSpanIntersectsWith = textSpanIntersectsWith;
    function decodedTextSpanIntersectsWith(start1, length1, start2, length2) {
        var end1 = start1 + length1;
        var end2 = start2 + length2;
        return start2 <= end1 && end2 >= start1;
    }
    ts.decodedTextSpanIntersectsWith = decodedTextSpanIntersectsWith;
    function textSpanIntersectsWithPosition(span, position) {
        return position <= textSpanEnd(span) && position >= span.start;
    }
    ts.textSpanIntersectsWithPosition = textSpanIntersectsWithPosition;
    function textSpanIntersection(span1, span2) {
        var start = Math.max(span1.start, span2.start);
        var end = Math.min(textSpanEnd(span1), textSpanEnd(span2));
        return start <= end ? createTextSpanFromBounds(start, end) : undefined;
    }
    ts.textSpanIntersection = textSpanIntersection;
    function createTextSpan(start, length) {
        if (start < 0) {
            throw new Error("start < 0");
        }
        if (length < 0) {
            throw new Error("length < 0");
        }
        return { start: start, length: length };
    }
    ts.createTextSpan = createTextSpan;
    function createTextSpanFromBounds(start, end) {
        return createTextSpan(start, end - start);
    }
    ts.createTextSpanFromBounds = createTextSpanFromBounds;
    function textChangeRangeNewSpan(range) {
        return createTextSpan(range.span.start, range.newLength);
    }
    ts.textChangeRangeNewSpan = textChangeRangeNewSpan;
    function textChangeRangeIsUnchanged(range) {
        return textSpanIsEmpty(range.span) && range.newLength === 0;
    }
    ts.textChangeRangeIsUnchanged = textChangeRangeIsUnchanged;
    function createTextChangeRange(span, newLength) {
        if (newLength < 0) {
            throw new Error("newLength < 0");
        }
        return { span: span, newLength: newLength };
    }
    ts.createTextChangeRange = createTextChangeRange;
    ts.unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0); // eslint-disable-line prefer-const
    /**
     * Called to merge all the changes that occurred across several versions of a script snapshot
     * into a single change.  i.e. if a user keeps making successive edits to a script we will
     * have a text change from V1 to V2, V2 to V3, ..., Vn.
     *
     * This function will then merge those changes into a single change range valid between V1 and
     * Vn.
     */
    function collapseTextChangeRangesAcrossMultipleVersions(changes) {
        if (changes.length === 0) {
            return ts.unchangedTextChangeRange;
        }
        if (changes.length === 1) {
            return changes[0];
        }
        // We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd }
        // as it makes things much easier to reason about.
        var change0 = changes[0];
        var oldStartN = change0.span.start;
        var oldEndN = textSpanEnd(change0.span);
        var newEndN = oldStartN + change0.newLength;
        for (var i = 1; i < changes.length; i++) {
            var nextChange = changes[i];
            // Consider the following case:
            // i.e. two edits.  The first represents the text change range { { 10, 50 }, 30 }.  i.e. The span starting
            // at 10, with length 50 is reduced to length 30.  The second represents the text change range { { 30, 30 }, 40 }.
            // i.e. the span starting at 30 with length 30 is increased to length 40.
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      -------------------------------------------------------------------------------------------------------
            //                |                                                 /
            //                |                                            /----
            //  T1            |                                       /----
            //                |                                  /----
            //                |                             /----
            //      -------------------------------------------------------------------------------------------------------
            //                                     |                            \
            //                                     |                               \
            //   T2                                |                                 \
            //                                     |                                   \
            //                                     |                                      \
            //      -------------------------------------------------------------------------------------------------------
            //
            // Merging these turns out to not be too difficult.  First, determining the new start of the change is trivial
            // it's just the min of the old and new starts.  i.e.:
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      ------------------------------------------------------------*------------------------------------------
            //                |                                                 /
            //                |                                            /----
            //  T1            |                                       /----
            //                |                                  /----
            //                |                             /----
            //      ----------------------------------------$-------------------$------------------------------------------
            //                .                    |                            \
            //                .                    |                               \
            //   T2           .                    |                                 \
            //                .                    |                                   \
            //                .                    |                                      \
            //      ----------------------------------------------------------------------*--------------------------------
            //
            // (Note the dots represent the newly inferred start.
            // Determining the new and old end is also pretty simple.  Basically it boils down to paying attention to the
            // absolute positions at the asterisks, and the relative change between the dollar signs. Basically, we see
            // which if the two $'s precedes the other, and we move that one forward until they line up.  in this case that
            // means:
            //
            //      0         10        20        30        40        50        60        70        80        90        100
            //      --------------------------------------------------------------------------------*----------------------
            //                |                                                                     /
            //                |                                                                /----
            //  T1            |                                                           /----
            //                |                                                      /----
            //                |                                                 /----
            //      ------------------------------------------------------------$------------------------------------------
            //                .                    |                            \
            //                .                    |                               \
            //   T2           .                    |                                 \
            //                .                    |                                   \
            //                .                    |                                      \
            //      ----------------------------------------------------------------------*--------------------------------
            //
            // In other words (in this case), we're recognizing that the second edit happened after where the first edit
            // ended with a delta of 20 characters (60 - 40).  Thus, if we go back in time to where the first edit started
            // that's the same as if we started at char 80 instead of 60.
            //
            // As it so happens, the same logic applies if the second edit precedes the first edit.  In that case rather
            // than pushing the first edit forward to match the second, we'll push the second edit forward to match the
            // first.
            //
            // In this case that means we have { oldStart: 10, oldEnd: 80, newEnd: 70 } or, in TextChangeRange
            // semantics: { { start: 10, length: 70 }, newLength: 60 }
            //
            // The math then works out as follows.
            // If we have { oldStart1, oldEnd1, newEnd1 } and { oldStart2, oldEnd2, newEnd2 } then we can compute the
            // final result like so:
            //
            // {
            //      oldStart3: Min(oldStart1, oldStart2),
            //      oldEnd3: Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)),
            //      newEnd3: Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
            // }
            var oldStart1 = oldStartN;
            var oldEnd1 = oldEndN;
            var newEnd1 = newEndN;
            var oldStart2 = nextChange.span.start;
            var oldEnd2 = textSpanEnd(nextChange.span);
            var newEnd2 = oldStart2 + nextChange.newLength;
            oldStartN = Math.min(oldStart1, oldStart2);
            oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1));
            newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2));
        }
        return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength*/ newEndN - oldStartN);
    }
    ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions;
    function getTypeParameterOwner(d) {
        if (d && d.kind === 155 /* TypeParameter */) {
            for (var current = d; current; current = current.parent) {
                if (isFunctionLike(current) || isClassLike(current) || current.kind === 246 /* InterfaceDeclaration */) {
                    return current;
                }
            }
        }
    }
    ts.getTypeParameterOwner = getTypeParameterOwner;
    function isParameterPropertyDeclaration(node, parent) {
        return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) && parent.kind === 162 /* Constructor */;
    }
    ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration;
    function isEmptyBindingPattern(node) {
        if (isBindingPattern(node)) {
            return ts.every(node.elements, isEmptyBindingElement);
        }
        return false;
    }
    ts.isEmptyBindingPattern = isEmptyBindingPattern;
    function isEmptyBindingElement(node) {
        if (isOmittedExpression(node)) {
            return true;
        }
        return isEmptyBindingPattern(node.name);
    }
    ts.isEmptyBindingElement = isEmptyBindingElement;
    function walkUpBindingElementsAndPatterns(binding) {
        var node = binding.parent;
        while (isBindingElement(node.parent)) {
            node = node.parent.parent;
        }
        return node.parent;
    }
    ts.walkUpBindingElementsAndPatterns = walkUpBindingElementsAndPatterns;
    function getCombinedFlags(node, getFlags) {
        if (isBindingElement(node)) {
            node = walkUpBindingElementsAndPatterns(node);
        }
        var flags = getFlags(node);
        if (node.kind === 242 /* VariableDeclaration */) {
            node = node.parent;
        }
        if (node && node.kind === 243 /* VariableDeclarationList */) {
            flags |= getFlags(node);
            node = node.parent;
        }
        if (node && node.kind === 225 /* VariableStatement */) {
            flags |= getFlags(node);
        }
        return flags;
    }
    function getCombinedModifierFlags(node) {
        return getCombinedFlags(node, ts.getModifierFlags);
    }
    ts.getCombinedModifierFlags = getCombinedModifierFlags;
    // Returns the node flags for this node and all relevant parent nodes.  This is done so that
    // nodes like variable declarations and binding elements can returned a view of their flags
    // that includes the modifiers from their container.  i.e. flags like export/declare aren't
    // stored on the variable declaration directly, but on the containing variable statement
    // (if it has one).  Similarly, flags for let/const are store on the variable declaration
    // list.  By calling this function, all those flags are combined so that the client can treat
    // the node as if it actually had those flags.
    function getCombinedNodeFlags(node) {
        return getCombinedFlags(node, function (n) { return n.flags; });
    }
    ts.getCombinedNodeFlags = getCombinedNodeFlags;
    /**
     * Checks to see if the locale is in the appropriate format,
     * and if it is, attempts to set the appropriate language.
     */
    function validateLocaleAndSetLanguage(locale, sys, errors) {
        var matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase());
        if (!matchResult) {
            if (errors) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp"));
            }
            return;
        }
        var language = matchResult[1];
        var territory = matchResult[3];
        // First try the entire locale, then fall back to just language if that's all we have.
        // Either ways do not fail, and fallback to the English diagnostic strings.
        if (!trySetLanguageAndTerritory(language, territory, errors)) {
            trySetLanguageAndTerritory(language, /*territory*/ undefined, errors);
        }
        // Set the UI locale for string collation
        ts.setUILocale(locale);
        function trySetLanguageAndTerritory(language, territory, errors) {
            var compilerFilePath = ts.normalizePath(sys.getExecutingFilePath());
            var containingDirectoryPath = ts.getDirectoryPath(compilerFilePath);
            var filePath = ts.combinePaths(containingDirectoryPath, language);
            if (territory) {
                filePath = filePath + "-" + territory;
            }
            filePath = sys.resolvePath(ts.combinePaths(filePath, "diagnosticMessages.generated.json"));
            if (!sys.fileExists(filePath)) {
                return false;
            }
            // TODO: Add codePage support for readFile?
            var fileContents = "";
            try {
                fileContents = sys.readFile(filePath);
            }
            catch (e) {
                if (errors) {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unable_to_open_file_0, filePath));
                }
                return false;
            }
            try {
                // this is a global mutation (or live binding update)!
                ts.setLocalizedDiagnosticMessages(JSON.parse(fileContents));
            }
            catch (_a) {
                if (errors) {
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Corrupted_locale_file_0, filePath));
                }
                return false;
            }
            return true;
        }
    }
    ts.validateLocaleAndSetLanguage = validateLocaleAndSetLanguage;
    function getOriginalNode(node, nodeTest) {
        if (node) {
            while (node.original !== undefined) {
                node = node.original;
            }
        }
        return !nodeTest || nodeTest(node) ? node : undefined;
    }
    ts.getOriginalNode = getOriginalNode;
    /**
     * Gets a value indicating whether a node originated in the parse tree.
     *
     * @param node The node to test.
     */
    function isParseTreeNode(node) {
        return (node.flags & 8 /* Synthesized */) === 0;
    }
    ts.isParseTreeNode = isParseTreeNode;
    function getParseTreeNode(node, nodeTest) {
        if (node === undefined || isParseTreeNode(node)) {
            return node;
        }
        node = getOriginalNode(node);
        if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) {
            return node;
        }
        return undefined;
    }
    ts.getParseTreeNode = getParseTreeNode;
    /** Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' */
    function escapeLeadingUnderscores(identifier) {
        return (identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier);
    }
    ts.escapeLeadingUnderscores = escapeLeadingUnderscores;
    /**
     * Remove extra underscore from escaped identifier text content.
     *
     * @param identifier The escaped identifier text.
     * @returns The unescaped identifier text.
     */
    function unescapeLeadingUnderscores(identifier) {
        var id = identifier;
        return id.length >= 3 && id.charCodeAt(0) === 95 /* _ */ && id.charCodeAt(1) === 95 /* _ */ && id.charCodeAt(2) === 95 /* _ */ ? id.substr(1) : id;
    }
    ts.unescapeLeadingUnderscores = unescapeLeadingUnderscores;
    function idText(identifierOrPrivateName) {
        return unescapeLeadingUnderscores(identifierOrPrivateName.escapedText);
    }
    ts.idText = idText;
    function symbolName(symbol) {
        if (symbol.valueDeclaration && isPrivateIdentifierPropertyDeclaration(symbol.valueDeclaration)) {
            return idText(symbol.valueDeclaration.name);
        }
        return unescapeLeadingUnderscores(symbol.escapedName);
    }
    ts.symbolName = symbolName;
    /**
     * A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should
     * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol
     * will be merged with)
     */
    function nameForNamelessJSDocTypedef(declaration) {
        var hostNode = declaration.parent.parent;
        if (!hostNode) {
            return undefined;
        }
        // Covers classes, functions - any named declaration host node
        if (isDeclaration(hostNode)) {
            return getDeclarationIdentifier(hostNode);
        }
        // Covers remaining cases (returning undefined if none match).
        switch (hostNode.kind) {
            case 225 /* VariableStatement */:
                if (hostNode.declarationList && hostNode.declarationList.declarations[0]) {
                    return getDeclarationIdentifier(hostNode.declarationList.declarations[0]);
                }
                break;
            case 226 /* ExpressionStatement */:
                var expr = hostNode.expression;
                if (expr.kind === 209 /* BinaryExpression */ && expr.operatorToken.kind === 62 /* EqualsToken */) {
                    expr = expr.left;
                }
                switch (expr.kind) {
                    case 194 /* PropertyAccessExpression */:
                        return expr.name;
                    case 195 /* ElementAccessExpression */:
                        var arg = expr.argumentExpression;
                        if (isIdentifier(arg)) {
                            return arg;
                        }
                }
                break;
            case 200 /* ParenthesizedExpression */: {
                return getDeclarationIdentifier(hostNode.expression);
            }
            case 238 /* LabeledStatement */: {
                if (isDeclaration(hostNode.statement) || isExpression(hostNode.statement)) {
                    return getDeclarationIdentifier(hostNode.statement);
                }
                break;
            }
        }
    }
    function getDeclarationIdentifier(node) {
        var name = getNameOfDeclaration(node);
        return name && isIdentifier(name) ? name : undefined;
    }
    /** @internal */
    function nodeHasName(statement, name) {
        if (isNamedDeclaration(statement) && isIdentifier(statement.name) && idText(statement.name) === idText(name)) {
            return true;
        }
        if (isVariableStatement(statement) && ts.some(statement.declarationList.declarations, function (d) { return nodeHasName(d, name); })) {
            return true;
        }
        return false;
    }
    ts.nodeHasName = nodeHasName;
    function getNameOfJSDocTypedef(declaration) {
        return declaration.name || nameForNamelessJSDocTypedef(declaration);
    }
    ts.getNameOfJSDocTypedef = getNameOfJSDocTypedef;
    /** @internal */
    function isNamedDeclaration(node) {
        return !!node.name; // A 'name' property should always be a DeclarationName.
    }
    ts.isNamedDeclaration = isNamedDeclaration;
    /** @internal */
    function getNonAssignedNameOfDeclaration(declaration) {
        switch (declaration.kind) {
            case 75 /* Identifier */:
                return declaration;
            case 323 /* JSDocPropertyTag */:
            case 317 /* JSDocParameterTag */: {
                var name = declaration.name;
                if (name.kind === 153 /* QualifiedName */) {
                    return name.right;
                }
                break;
            }
            case 196 /* CallExpression */:
            case 209 /* BinaryExpression */: {
                var expr_1 = declaration;
                switch (ts.getAssignmentDeclarationKind(expr_1)) {
                    case 1 /* ExportsProperty */:
                    case 4 /* ThisProperty */:
                    case 5 /* Property */:
                    case 3 /* PrototypeProperty */:
                        return ts.getElementOrPropertyAccessArgumentExpressionOrName(expr_1.left);
                    case 7 /* ObjectDefinePropertyValue */:
                    case 8 /* ObjectDefinePropertyExports */:
                    case 9 /* ObjectDefinePrototypeProperty */:
                        return expr_1.arguments[1];
                    default:
                        return undefined;
                }
            }
            case 322 /* JSDocTypedefTag */:
                return getNameOfJSDocTypedef(declaration);
            case 316 /* JSDocEnumTag */:
                return nameForNamelessJSDocTypedef(declaration);
            case 259 /* ExportAssignment */: {
                var expression = declaration.expression;
                return isIdentifier(expression) ? expression : undefined;
            }
            case 195 /* ElementAccessExpression */:
                var expr = declaration;
                if (ts.isBindableStaticElementAccessExpression(expr)) {
                    return expr.argumentExpression;
                }
        }
        return declaration.name;
    }
    ts.getNonAssignedNameOfDeclaration = getNonAssignedNameOfDeclaration;
    function getNameOfDeclaration(declaration) {
        if (declaration === undefined)
            return undefined;
        return getNonAssignedNameOfDeclaration(declaration) ||
            (isFunctionExpression(declaration) || isClassExpression(declaration) ? getAssignedName(declaration) : undefined);
    }
    ts.getNameOfDeclaration = getNameOfDeclaration;
    function getAssignedName(node) {
        if (!node.parent) {
            return undefined;
        }
        else if (isPropertyAssignment(node.parent) || isBindingElement(node.parent)) {
            return node.parent.name;
        }
        else if (isBinaryExpression(node.parent) && node === node.parent.right) {
            if (isIdentifier(node.parent.left)) {
                return node.parent.left;
            }
            else if (ts.isAccessExpression(node.parent.left)) {
                return ts.getElementOrPropertyAccessArgumentExpressionOrName(node.parent.left);
            }
        }
        else if (isVariableDeclaration(node.parent) && isIdentifier(node.parent.name)) {
            return node.parent.name;
        }
    }
    /**
     * Gets the JSDoc parameter tags for the node if present.
     *
     * @remarks Returns any JSDoc param tag whose name matches the provided
     * parameter, whether a param tag on a containing function
     * expression, or a param tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are returned first, so in the previous example, the param
     * tag on the containing function expression would be first.
     *
     * For binding patterns, parameter tags are matched by position.
     */
    function getJSDocParameterTags(param) {
        if (param.name) {
            if (isIdentifier(param.name)) {
                var name_1 = param.name.escapedText;
                return getJSDocTags(param.parent).filter(function (tag) { return isJSDocParameterTag(tag) && isIdentifier(tag.name) && tag.name.escapedText === name_1; });
            }
            else {
                var i = param.parent.parameters.indexOf(param);
                ts.Debug.assert(i > -1, "Parameters should always be in their parents' parameter list");
                var paramTags = getJSDocTags(param.parent).filter(isJSDocParameterTag);
                if (i < paramTags.length) {
                    return [paramTags[i]];
                }
            }
        }
        // return empty array for: out-of-order binding patterns and JSDoc function syntax, which has un-named parameters
        return ts.emptyArray;
    }
    ts.getJSDocParameterTags = getJSDocParameterTags;
    /**
     * Gets the JSDoc type parameter tags for the node if present.
     *
     * @remarks Returns any JSDoc template tag whose names match the provided
     * parameter, whether a template tag on a containing function
     * expression, or a template tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are returned first, so in the previous example, the template
     * tag on the containing function expression would be first.
     */
    function getJSDocTypeParameterTags(param) {
        var name = param.name.escapedText;
        return getJSDocTags(param.parent).filter(function (tag) {
            return isJSDocTemplateTag(tag) && tag.typeParameters.some(function (tp) { return tp.name.escapedText === name; });
        });
    }
    ts.getJSDocTypeParameterTags = getJSDocTypeParameterTags;
    /**
     * Return true if the node has JSDoc parameter tags.
     *
     * @remarks Includes parameter tags that are not directly on the node,
     * for example on a variable declaration whose initializer is a function expression.
     */
    function hasJSDocParameterTags(node) {
        return !!getFirstJSDocTag(node, isJSDocParameterTag);
    }
    ts.hasJSDocParameterTags = hasJSDocParameterTags;
    /** Gets the JSDoc augments tag for the node if present */
    function getJSDocAugmentsTag(node) {
        return getFirstJSDocTag(node, isJSDocAugmentsTag);
    }
    ts.getJSDocAugmentsTag = getJSDocAugmentsTag;
    /** Gets the JSDoc implements tags for the node if present */
    function getJSDocImplementsTags(node) {
        return getAllJSDocTags(node, isJSDocImplementsTag);
    }
    ts.getJSDocImplementsTags = getJSDocImplementsTags;
    /** Gets the JSDoc class tag for the node if present */
    function getJSDocClassTag(node) {
        return getFirstJSDocTag(node, isJSDocClassTag);
    }
    ts.getJSDocClassTag = getJSDocClassTag;
    /** Gets the JSDoc public tag for the node if present */
    function getJSDocPublicTag(node) {
        return getFirstJSDocTag(node, isJSDocPublicTag);
    }
    ts.getJSDocPublicTag = getJSDocPublicTag;
    /** Gets the JSDoc private tag for the node if present */
    function getJSDocPrivateTag(node) {
        return getFirstJSDocTag(node, isJSDocPrivateTag);
    }
    ts.getJSDocPrivateTag = getJSDocPrivateTag;
    /** Gets the JSDoc protected tag for the node if present */
    function getJSDocProtectedTag(node) {
        return getFirstJSDocTag(node, isJSDocProtectedTag);
    }
    ts.getJSDocProtectedTag = getJSDocProtectedTag;
    /** Gets the JSDoc protected tag for the node if present */
    function getJSDocReadonlyTag(node) {
        return getFirstJSDocTag(node, isJSDocReadonlyTag);
    }
    ts.getJSDocReadonlyTag = getJSDocReadonlyTag;
    /** Gets the JSDoc enum tag for the node if present */
    function getJSDocEnumTag(node) {
        return getFirstJSDocTag(node, isJSDocEnumTag);
    }
    ts.getJSDocEnumTag = getJSDocEnumTag;
    /** Gets the JSDoc this tag for the node if present */
    function getJSDocThisTag(node) {
        return getFirstJSDocTag(node, isJSDocThisTag);
    }
    ts.getJSDocThisTag = getJSDocThisTag;
    /** Gets the JSDoc return tag for the node if present */
    function getJSDocReturnTag(node) {
        return getFirstJSDocTag(node, isJSDocReturnTag);
    }
    ts.getJSDocReturnTag = getJSDocReturnTag;
    /** Gets the JSDoc template tag for the node if present */
    function getJSDocTemplateTag(node) {
        return getFirstJSDocTag(node, isJSDocTemplateTag);
    }
    ts.getJSDocTemplateTag = getJSDocTemplateTag;
    /** Gets the JSDoc type tag for the node if present and valid */
    function getJSDocTypeTag(node) {
        // We should have already issued an error if there were multiple type jsdocs, so just use the first one.
        var tag = getFirstJSDocTag(node, isJSDocTypeTag);
        if (tag && tag.typeExpression && tag.typeExpression.type) {
            return tag;
        }
        return undefined;
    }
    ts.getJSDocTypeTag = getJSDocTypeTag;
    /**
     * Gets the type node for the node if provided via JSDoc.
     *
     * @remarks The search includes any JSDoc param tag that relates
     * to the provided parameter, for example a type tag on the
     * parameter itself, or a param tag on a containing function
     * expression, or a param tag on a variable declaration whose
     * initializer is the containing function. The tags closest to the
     * node are examined first, so in the previous example, the type
     * tag directly on the node would be returned.
     */
    function getJSDocType(node) {
        var tag = getFirstJSDocTag(node, isJSDocTypeTag);
        if (!tag && isParameter(node)) {
            tag = ts.find(getJSDocParameterTags(node), function (tag) { return !!tag.typeExpression; });
        }
        return tag && tag.typeExpression && tag.typeExpression.type;
    }
    ts.getJSDocType = getJSDocType;
    /**
     * Gets the return type node for the node if provided via JSDoc return tag or type tag.
     *
     * @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
     * gets the type from inside the braces, after the fat arrow, etc.
     */
    function getJSDocReturnType(node) {
        var returnTag = getJSDocReturnTag(node);
        if (returnTag && returnTag.typeExpression) {
            return returnTag.typeExpression.type;
        }
        var typeTag = getJSDocTypeTag(node);
        if (typeTag && typeTag.typeExpression) {
            var type = typeTag.typeExpression.type;
            if (isTypeLiteralNode(type)) {
                var sig = ts.find(type.members, isCallSignatureDeclaration);
                return sig && sig.type;
            }
            if (isFunctionTypeNode(type) || isJSDocFunctionType(type)) {
                return type.type;
            }
        }
    }
    ts.getJSDocReturnType = getJSDocReturnType;
    /** Get all JSDoc tags related to a node, including those on parent nodes. */
    function getJSDocTags(node) {
        var tags = node.jsDocCache;
        // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
        if (tags === undefined) {
            var comments = ts.getJSDocCommentsAndTags(node);
            ts.Debug.assert(comments.length < 2 || comments[0] !== comments[1]);
            node.jsDocCache = tags = ts.flatMap(comments, function (j) { return isJSDoc(j) ? j.tags : j; });
        }
        return tags;
    }
    ts.getJSDocTags = getJSDocTags;
    /** Get the first JSDoc tag of a specified kind, or undefined if not present. */
    function getFirstJSDocTag(node, predicate) {
        return ts.find(getJSDocTags(node), predicate);
    }
    /** Gets all JSDoc tags that match a specified predicate */
    function getAllJSDocTags(node, predicate) {
        return getJSDocTags(node).filter(predicate);
    }
    ts.getAllJSDocTags = getAllJSDocTags;
    /** Gets all JSDoc tags of a specified kind */
    function getAllJSDocTagsOfKind(node, kind) {
        return getJSDocTags(node).filter(function (doc) { return doc.kind === kind; });
    }
    ts.getAllJSDocTagsOfKind = getAllJSDocTagsOfKind;
    /**
     * Gets the effective type parameters. If the node was parsed in a
     * JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
     */
    function getEffectiveTypeParameterDeclarations(node) {
        if (isJSDocSignature(node)) {
            return ts.emptyArray;
        }
        if (ts.isJSDocTypeAlias(node)) {
            ts.Debug.assert(node.parent.kind === 303 /* JSDocComment */);
            return ts.flatMap(node.parent.tags, function (tag) { return isJSDocTemplateTag(tag) ? tag.typeParameters : undefined; });
        }
        if (node.typeParameters) {
            return node.typeParameters;
        }
        if (ts.isInJSFile(node)) {
            var decls = ts.getJSDocTypeParameterDeclarations(node);
            if (decls.length) {
                return decls;
            }
            var typeTag = getJSDocType(node);
            if (typeTag && isFunctionTypeNode(typeTag) && typeTag.typeParameters) {
                return typeTag.typeParameters;
            }
        }
        return ts.emptyArray;
    }
    ts.getEffectiveTypeParameterDeclarations = getEffectiveTypeParameterDeclarations;
    function getEffectiveConstraintOfTypeParameter(node) {
        return node.constraint ? node.constraint :
            isJSDocTemplateTag(node.parent) && node === node.parent.typeParameters[0] ? node.parent.constraint :
                undefined;
    }
    ts.getEffectiveConstraintOfTypeParameter = getEffectiveConstraintOfTypeParameter;
    // #region
    // Simple node tests of the form `node.kind === SyntaxKind.Foo`.
    // Literals
    function isNumericLiteral(node) {
        return node.kind === 8 /* NumericLiteral */;
    }
    ts.isNumericLiteral = isNumericLiteral;
    function isBigIntLiteral(node) {
        return node.kind === 9 /* BigIntLiteral */;
    }
    ts.isBigIntLiteral = isBigIntLiteral;
    function isStringLiteral(node) {
        return node.kind === 10 /* StringLiteral */;
    }
    ts.isStringLiteral = isStringLiteral;
    function isJsxText(node) {
        return node.kind === 11 /* JsxText */;
    }
    ts.isJsxText = isJsxText;
    function isRegularExpressionLiteral(node) {
        return node.kind === 13 /* RegularExpressionLiteral */;
    }
    ts.isRegularExpressionLiteral = isRegularExpressionLiteral;
    function isNoSubstitutionTemplateLiteral(node) {
        return node.kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isNoSubstitutionTemplateLiteral = isNoSubstitutionTemplateLiteral;
    // Pseudo-literals
    function isTemplateHead(node) {
        return node.kind === 15 /* TemplateHead */;
    }
    ts.isTemplateHead = isTemplateHead;
    function isTemplateMiddle(node) {
        return node.kind === 16 /* TemplateMiddle */;
    }
    ts.isTemplateMiddle = isTemplateMiddle;
    function isTemplateTail(node) {
        return node.kind === 17 /* TemplateTail */;
    }
    ts.isTemplateTail = isTemplateTail;
    function isIdentifier(node) {
        return node.kind === 75 /* Identifier */;
    }
    ts.isIdentifier = isIdentifier;
    // Names
    function isQualifiedName(node) {
        return node.kind === 153 /* QualifiedName */;
    }
    ts.isQualifiedName = isQualifiedName;
    function isComputedPropertyName(node) {
        return node.kind === 154 /* ComputedPropertyName */;
    }
    ts.isComputedPropertyName = isComputedPropertyName;
    function isPrivateIdentifier(node) {
        return node.kind === 76 /* PrivateIdentifier */;
    }
    ts.isPrivateIdentifier = isPrivateIdentifier;
    function isIdentifierOrPrivateIdentifier(node) {
        return node.kind === 75 /* Identifier */ || node.kind === 76 /* PrivateIdentifier */;
    }
    ts.isIdentifierOrPrivateIdentifier = isIdentifierOrPrivateIdentifier;
    // Signature elements
    function isTypeParameterDeclaration(node) {
        return node.kind === 155 /* TypeParameter */;
    }
    ts.isTypeParameterDeclaration = isTypeParameterDeclaration;
    function isParameter(node) {
        return node.kind === 156 /* Parameter */;
    }
    ts.isParameter = isParameter;
    function isDecorator(node) {
        return node.kind === 157 /* Decorator */;
    }
    ts.isDecorator = isDecorator;
    // TypeMember
    function isPropertySignature(node) {
        return node.kind === 158 /* PropertySignature */;
    }
    ts.isPropertySignature = isPropertySignature;
    function isPropertyDeclaration(node) {
        return node.kind === 159 /* PropertyDeclaration */;
    }
    ts.isPropertyDeclaration = isPropertyDeclaration;
    function isMethodSignature(node) {
        return node.kind === 160 /* MethodSignature */;
    }
    ts.isMethodSignature = isMethodSignature;
    function isMethodDeclaration(node) {
        return node.kind === 161 /* MethodDeclaration */;
    }
    ts.isMethodDeclaration = isMethodDeclaration;
    function isConstructorDeclaration(node) {
        return node.kind === 162 /* Constructor */;
    }
    ts.isConstructorDeclaration = isConstructorDeclaration;
    function isGetAccessorDeclaration(node) {
        return node.kind === 163 /* GetAccessor */;
    }
    ts.isGetAccessorDeclaration = isGetAccessorDeclaration;
    function isSetAccessorDeclaration(node) {
        return node.kind === 164 /* SetAccessor */;
    }
    ts.isSetAccessorDeclaration = isSetAccessorDeclaration;
    function isCallSignatureDeclaration(node) {
        return node.kind === 165 /* CallSignature */;
    }
    ts.isCallSignatureDeclaration = isCallSignatureDeclaration;
    function isConstructSignatureDeclaration(node) {
        return node.kind === 166 /* ConstructSignature */;
    }
    ts.isConstructSignatureDeclaration = isConstructSignatureDeclaration;
    function isIndexSignatureDeclaration(node) {
        return node.kind === 167 /* IndexSignature */;
    }
    ts.isIndexSignatureDeclaration = isIndexSignatureDeclaration;
    /* @internal */
    function isGetOrSetAccessorDeclaration(node) {
        return node.kind === 164 /* SetAccessor */ || node.kind === 163 /* GetAccessor */;
    }
    ts.isGetOrSetAccessorDeclaration = isGetOrSetAccessorDeclaration;
    // Type
    function isTypePredicateNode(node) {
        return node.kind === 168 /* TypePredicate */;
    }
    ts.isTypePredicateNode = isTypePredicateNode;
    function isTypeReferenceNode(node) {
        return node.kind === 169 /* TypeReference */;
    }
    ts.isTypeReferenceNode = isTypeReferenceNode;
    function isFunctionTypeNode(node) {
        return node.kind === 170 /* FunctionType */;
    }
    ts.isFunctionTypeNode = isFunctionTypeNode;
    function isConstructorTypeNode(node) {
        return node.kind === 171 /* ConstructorType */;
    }
    ts.isConstructorTypeNode = isConstructorTypeNode;
    function isTypeQueryNode(node) {
        return node.kind === 172 /* TypeQuery */;
    }
    ts.isTypeQueryNode = isTypeQueryNode;
    function isTypeLiteralNode(node) {
        return node.kind === 173 /* TypeLiteral */;
    }
    ts.isTypeLiteralNode = isTypeLiteralNode;
    function isArrayTypeNode(node) {
        return node.kind === 174 /* ArrayType */;
    }
    ts.isArrayTypeNode = isArrayTypeNode;
    function isTupleTypeNode(node) {
        return node.kind === 175 /* TupleType */;
    }
    ts.isTupleTypeNode = isTupleTypeNode;
    function isUnionTypeNode(node) {
        return node.kind === 178 /* UnionType */;
    }
    ts.isUnionTypeNode = isUnionTypeNode;
    function isIntersectionTypeNode(node) {
        return node.kind === 179 /* IntersectionType */;
    }
    ts.isIntersectionTypeNode = isIntersectionTypeNode;
    function isConditionalTypeNode(node) {
        return node.kind === 180 /* ConditionalType */;
    }
    ts.isConditionalTypeNode = isConditionalTypeNode;
    function isInferTypeNode(node) {
        return node.kind === 181 /* InferType */;
    }
    ts.isInferTypeNode = isInferTypeNode;
    function isParenthesizedTypeNode(node) {
        return node.kind === 182 /* ParenthesizedType */;
    }
    ts.isParenthesizedTypeNode = isParenthesizedTypeNode;
    function isThisTypeNode(node) {
        return node.kind === 183 /* ThisType */;
    }
    ts.isThisTypeNode = isThisTypeNode;
    function isTypeOperatorNode(node) {
        return node.kind === 184 /* TypeOperator */;
    }
    ts.isTypeOperatorNode = isTypeOperatorNode;
    function isIndexedAccessTypeNode(node) {
        return node.kind === 185 /* IndexedAccessType */;
    }
    ts.isIndexedAccessTypeNode = isIndexedAccessTypeNode;
    function isMappedTypeNode(node) {
        return node.kind === 186 /* MappedType */;
    }
    ts.isMappedTypeNode = isMappedTypeNode;
    function isLiteralTypeNode(node) {
        return node.kind === 187 /* LiteralType */;
    }
    ts.isLiteralTypeNode = isLiteralTypeNode;
    function isImportTypeNode(node) {
        return node.kind === 188 /* ImportType */;
    }
    ts.isImportTypeNode = isImportTypeNode;
    // Binding patterns
    function isObjectBindingPattern(node) {
        return node.kind === 189 /* ObjectBindingPattern */;
    }
    ts.isObjectBindingPattern = isObjectBindingPattern;
    function isArrayBindingPattern(node) {
        return node.kind === 190 /* ArrayBindingPattern */;
    }
    ts.isArrayBindingPattern = isArrayBindingPattern;
    function isBindingElement(node) {
        return node.kind === 191 /* BindingElement */;
    }
    ts.isBindingElement = isBindingElement;
    // Expression
    function isArrayLiteralExpression(node) {
        return node.kind === 192 /* ArrayLiteralExpression */;
    }
    ts.isArrayLiteralExpression = isArrayLiteralExpression;
    function isObjectLiteralExpression(node) {
        return node.kind === 193 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralExpression = isObjectLiteralExpression;
    function isPropertyAccessExpression(node) {
        return node.kind === 194 /* PropertyAccessExpression */;
    }
    ts.isPropertyAccessExpression = isPropertyAccessExpression;
    function isPropertyAccessChain(node) {
        return isPropertyAccessExpression(node) && !!(node.flags & 32 /* OptionalChain */);
    }
    ts.isPropertyAccessChain = isPropertyAccessChain;
    function isElementAccessExpression(node) {
        return node.kind === 195 /* ElementAccessExpression */;
    }
    ts.isElementAccessExpression = isElementAccessExpression;
    function isElementAccessChain(node) {
        return isElementAccessExpression(node) && !!(node.flags & 32 /* OptionalChain */);
    }
    ts.isElementAccessChain = isElementAccessChain;
    function isCallExpression(node) {
        return node.kind === 196 /* CallExpression */;
    }
    ts.isCallExpression = isCallExpression;
    function isCallChain(node) {
        return isCallExpression(node) && !!(node.flags & 32 /* OptionalChain */);
    }
    ts.isCallChain = isCallChain;
    function isOptionalChain(node) {
        var kind = node.kind;
        return !!(node.flags & 32 /* OptionalChain */) &&
            (kind === 194 /* PropertyAccessExpression */
                || kind === 195 /* ElementAccessExpression */
                || kind === 196 /* CallExpression */
                || kind === 218 /* NonNullExpression */);
    }
    ts.isOptionalChain = isOptionalChain;
    /* @internal */
    function isOptionalChainRoot(node) {
        return isOptionalChain(node) && !isNonNullExpression(node) && !!node.questionDotToken;
    }
    ts.isOptionalChainRoot = isOptionalChainRoot;
    /**
     * Determines whether a node is the expression preceding an optional chain (i.e. `a` in `a?.b`).
     */
    /* @internal */
    function isExpressionOfOptionalChainRoot(node) {
        return isOptionalChainRoot(node.parent) && node.parent.expression === node;
    }
    ts.isExpressionOfOptionalChainRoot = isExpressionOfOptionalChainRoot;
    /**
     * Determines whether a node is the outermost `OptionalChain` in an ECMAScript `OptionalExpression`:
     *
     * 1. For `a?.b.c`, the outermost chain is `a?.b.c` (`c` is the end of the chain starting at `a?.`)
     * 2. For `a?.b!`, the outermost chain is `a?.b` (`b` is the end of the chain starting at `a?.`)
     * 3. For `(a?.b.c).d`, the outermost chain is `a?.b.c` (`c` is the end of the chain starting at `a?.` since parens end the chain)
     * 4. For `a?.b.c?.d`, both `a?.b.c` and `a?.b.c?.d` are outermost (`c` is the end of the chain starting at `a?.`, and `d` is
     *   the end of the chain starting at `c?.`)
     * 5. For `a?.(b?.c).d`, both `b?.c` and `a?.(b?.c)d` are outermost (`c` is the end of the chain starting at `b`, and `d` is
     *   the end of the chain starting at `a?.`)
     */
    /* @internal */
    function isOutermostOptionalChain(node) {
        return !isOptionalChain(node.parent) // cases 1, 2, and 3
            || isOptionalChainRoot(node.parent) // case 4
            || node !== node.parent.expression; // case 5
    }
    ts.isOutermostOptionalChain = isOutermostOptionalChain;
    function isNullishCoalesce(node) {
        return node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 60 /* QuestionQuestionToken */;
    }
    ts.isNullishCoalesce = isNullishCoalesce;
    function isNewExpression(node) {
        return node.kind === 197 /* NewExpression */;
    }
    ts.isNewExpression = isNewExpression;
    function isTaggedTemplateExpression(node) {
        return node.kind === 198 /* TaggedTemplateExpression */;
    }
    ts.isTaggedTemplateExpression = isTaggedTemplateExpression;
    function isTypeAssertion(node) {
        return node.kind === 199 /* TypeAssertionExpression */;
    }
    ts.isTypeAssertion = isTypeAssertion;
    function isConstTypeReference(node) {
        return isTypeReferenceNode(node) && isIdentifier(node.typeName) &&
            node.typeName.escapedText === "const" && !node.typeArguments;
    }
    ts.isConstTypeReference = isConstTypeReference;
    function isParenthesizedExpression(node) {
        return node.kind === 200 /* ParenthesizedExpression */;
    }
    ts.isParenthesizedExpression = isParenthesizedExpression;
    function skipPartiallyEmittedExpressions(node) {
        return ts.skipOuterExpressions(node, 8 /* PartiallyEmittedExpressions */);
    }
    ts.skipPartiallyEmittedExpressions = skipPartiallyEmittedExpressions;
    function isFunctionExpression(node) {
        return node.kind === 201 /* FunctionExpression */;
    }
    ts.isFunctionExpression = isFunctionExpression;
    function isArrowFunction(node) {
        return node.kind === 202 /* ArrowFunction */;
    }
    ts.isArrowFunction = isArrowFunction;
    function isDeleteExpression(node) {
        return node.kind === 203 /* DeleteExpression */;
    }
    ts.isDeleteExpression = isDeleteExpression;
    function isTypeOfExpression(node) {
        return node.kind === 204 /* TypeOfExpression */;
    }
    ts.isTypeOfExpression = isTypeOfExpression;
    function isVoidExpression(node) {
        return node.kind === 205 /* VoidExpression */;
    }
    ts.isVoidExpression = isVoidExpression;
    function isAwaitExpression(node) {
        return node.kind === 206 /* AwaitExpression */;
    }
    ts.isAwaitExpression = isAwaitExpression;
    function isPrefixUnaryExpression(node) {
        return node.kind === 207 /* PrefixUnaryExpression */;
    }
    ts.isPrefixUnaryExpression = isPrefixUnaryExpression;
    function isPostfixUnaryExpression(node) {
        return node.kind === 208 /* PostfixUnaryExpression */;
    }
    ts.isPostfixUnaryExpression = isPostfixUnaryExpression;
    function isBinaryExpression(node) {
        return node.kind === 209 /* BinaryExpression */;
    }
    ts.isBinaryExpression = isBinaryExpression;
    function isConditionalExpression(node) {
        return node.kind === 210 /* ConditionalExpression */;
    }
    ts.isConditionalExpression = isConditionalExpression;
    function isTemplateExpression(node) {
        return node.kind === 211 /* TemplateExpression */;
    }
    ts.isTemplateExpression = isTemplateExpression;
    function isYieldExpression(node) {
        return node.kind === 212 /* YieldExpression */;
    }
    ts.isYieldExpression = isYieldExpression;
    function isSpreadElement(node) {
        return node.kind === 213 /* SpreadElement */;
    }
    ts.isSpreadElement = isSpreadElement;
    function isClassExpression(node) {
        return node.kind === 214 /* ClassExpression */;
    }
    ts.isClassExpression = isClassExpression;
    function isOmittedExpression(node) {
        return node.kind === 215 /* OmittedExpression */;
    }
    ts.isOmittedExpression = isOmittedExpression;
    function isExpressionWithTypeArguments(node) {
        return node.kind === 216 /* ExpressionWithTypeArguments */;
    }
    ts.isExpressionWithTypeArguments = isExpressionWithTypeArguments;
    function isAsExpression(node) {
        return node.kind === 217 /* AsExpression */;
    }
    ts.isAsExpression = isAsExpression;
    function isNonNullExpression(node) {
        return node.kind === 218 /* NonNullExpression */;
    }
    ts.isNonNullExpression = isNonNullExpression;
    function isNonNullChain(node) {
        return isNonNullExpression(node) && !!(node.flags & 32 /* OptionalChain */);
    }
    ts.isNonNullChain = isNonNullChain;
    function isMetaProperty(node) {
        return node.kind === 219 /* MetaProperty */;
    }
    ts.isMetaProperty = isMetaProperty;
    // Misc
    function isTemplateSpan(node) {
        return node.kind === 221 /* TemplateSpan */;
    }
    ts.isTemplateSpan = isTemplateSpan;
    function isSemicolonClassElement(node) {
        return node.kind === 222 /* SemicolonClassElement */;
    }
    ts.isSemicolonClassElement = isSemicolonClassElement;
    // Block
    function isBlock(node) {
        return node.kind === 223 /* Block */;
    }
    ts.isBlock = isBlock;
    function isVariableStatement(node) {
        return node.kind === 225 /* VariableStatement */;
    }
    ts.isVariableStatement = isVariableStatement;
    function isEmptyStatement(node) {
        return node.kind === 224 /* EmptyStatement */;
    }
    ts.isEmptyStatement = isEmptyStatement;
    function isExpressionStatement(node) {
        return node.kind === 226 /* ExpressionStatement */;
    }
    ts.isExpressionStatement = isExpressionStatement;
    function isIfStatement(node) {
        return node.kind === 227 /* IfStatement */;
    }
    ts.isIfStatement = isIfStatement;
    function isDoStatement(node) {
        return node.kind === 228 /* DoStatement */;
    }
    ts.isDoStatement = isDoStatement;
    function isWhileStatement(node) {
        return node.kind === 229 /* WhileStatement */;
    }
    ts.isWhileStatement = isWhileStatement;
    function isForStatement(node) {
        return node.kind === 230 /* ForStatement */;
    }
    ts.isForStatement = isForStatement;
    function isForInStatement(node) {
        return node.kind === 231 /* ForInStatement */;
    }
    ts.isForInStatement = isForInStatement;
    function isForOfStatement(node) {
        return node.kind === 232 /* ForOfStatement */;
    }
    ts.isForOfStatement = isForOfStatement;
    function isContinueStatement(node) {
        return node.kind === 233 /* ContinueStatement */;
    }
    ts.isContinueStatement = isContinueStatement;
    function isBreakStatement(node) {
        return node.kind === 234 /* BreakStatement */;
    }
    ts.isBreakStatement = isBreakStatement;
    function isBreakOrContinueStatement(node) {
        return node.kind === 234 /* BreakStatement */ || node.kind === 233 /* ContinueStatement */;
    }
    ts.isBreakOrContinueStatement = isBreakOrContinueStatement;
    function isReturnStatement(node) {
        return node.kind === 235 /* ReturnStatement */;
    }
    ts.isReturnStatement = isReturnStatement;
    function isWithStatement(node) {
        return node.kind === 236 /* WithStatement */;
    }
    ts.isWithStatement = isWithStatement;
    function isSwitchStatement(node) {
        return node.kind === 237 /* SwitchStatement */;
    }
    ts.isSwitchStatement = isSwitchStatement;
    function isLabeledStatement(node) {
        return node.kind === 238 /* LabeledStatement */;
    }
    ts.isLabeledStatement = isLabeledStatement;
    function isThrowStatement(node) {
        return node.kind === 239 /* ThrowStatement */;
    }
    ts.isThrowStatement = isThrowStatement;
    function isTryStatement(node) {
        return node.kind === 240 /* TryStatement */;
    }
    ts.isTryStatement = isTryStatement;
    function isDebuggerStatement(node) {
        return node.kind === 241 /* DebuggerStatement */;
    }
    ts.isDebuggerStatement = isDebuggerStatement;
    function isVariableDeclaration(node) {
        return node.kind === 242 /* VariableDeclaration */;
    }
    ts.isVariableDeclaration = isVariableDeclaration;
    function isVariableDeclarationList(node) {
        return node.kind === 243 /* VariableDeclarationList */;
    }
    ts.isVariableDeclarationList = isVariableDeclarationList;
    function isFunctionDeclaration(node) {
        return node.kind === 244 /* FunctionDeclaration */;
    }
    ts.isFunctionDeclaration = isFunctionDeclaration;
    function isClassDeclaration(node) {
        return node.kind === 245 /* ClassDeclaration */;
    }
    ts.isClassDeclaration = isClassDeclaration;
    function isInterfaceDeclaration(node) {
        return node.kind === 246 /* InterfaceDeclaration */;
    }
    ts.isInterfaceDeclaration = isInterfaceDeclaration;
    function isTypeAliasDeclaration(node) {
        return node.kind === 247 /* TypeAliasDeclaration */;
    }
    ts.isTypeAliasDeclaration = isTypeAliasDeclaration;
    function isEnumDeclaration(node) {
        return node.kind === 248 /* EnumDeclaration */;
    }
    ts.isEnumDeclaration = isEnumDeclaration;
    function isModuleDeclaration(node) {
        return node.kind === 249 /* ModuleDeclaration */;
    }
    ts.isModuleDeclaration = isModuleDeclaration;
    function isModuleBlock(node) {
        return node.kind === 250 /* ModuleBlock */;
    }
    ts.isModuleBlock = isModuleBlock;
    function isCaseBlock(node) {
        return node.kind === 251 /* CaseBlock */;
    }
    ts.isCaseBlock = isCaseBlock;
    function isNamespaceExportDeclaration(node) {
        return node.kind === 252 /* NamespaceExportDeclaration */;
    }
    ts.isNamespaceExportDeclaration = isNamespaceExportDeclaration;
    function isImportEqualsDeclaration(node) {
        return node.kind === 253 /* ImportEqualsDeclaration */;
    }
    ts.isImportEqualsDeclaration = isImportEqualsDeclaration;
    function isImportDeclaration(node) {
        return node.kind === 254 /* ImportDeclaration */;
    }
    ts.isImportDeclaration = isImportDeclaration;
    function isImportClause(node) {
        return node.kind === 255 /* ImportClause */;
    }
    ts.isImportClause = isImportClause;
    function isNamespaceImport(node) {
        return node.kind === 256 /* NamespaceImport */;
    }
    ts.isNamespaceImport = isNamespaceImport;
    function isNamespaceExport(node) {
        return node.kind === 262 /* NamespaceExport */;
    }
    ts.isNamespaceExport = isNamespaceExport;
    function isNamedExportBindings(node) {
        return node.kind === 262 /* NamespaceExport */ || node.kind === 261 /* NamedExports */;
    }
    ts.isNamedExportBindings = isNamedExportBindings;
    function isNamedImports(node) {
        return node.kind === 257 /* NamedImports */;
    }
    ts.isNamedImports = isNamedImports;
    function isImportSpecifier(node) {
        return node.kind === 258 /* ImportSpecifier */;
    }
    ts.isImportSpecifier = isImportSpecifier;
    function isExportAssignment(node) {
        return node.kind === 259 /* ExportAssignment */;
    }
    ts.isExportAssignment = isExportAssignment;
    function isExportDeclaration(node) {
        return node.kind === 260 /* ExportDeclaration */;
    }
    ts.isExportDeclaration = isExportDeclaration;
    function isNamedExports(node) {
        return node.kind === 261 /* NamedExports */;
    }
    ts.isNamedExports = isNamedExports;
    function isExportSpecifier(node) {
        return node.kind === 263 /* ExportSpecifier */;
    }
    ts.isExportSpecifier = isExportSpecifier;
    function isMissingDeclaration(node) {
        return node.kind === 264 /* MissingDeclaration */;
    }
    ts.isMissingDeclaration = isMissingDeclaration;
    // Module References
    function isExternalModuleReference(node) {
        return node.kind === 265 /* ExternalModuleReference */;
    }
    ts.isExternalModuleReference = isExternalModuleReference;
    // JSX
    function isJsxElement(node) {
        return node.kind === 266 /* JsxElement */;
    }
    ts.isJsxElement = isJsxElement;
    function isJsxSelfClosingElement(node) {
        return node.kind === 267 /* JsxSelfClosingElement */;
    }
    ts.isJsxSelfClosingElement = isJsxSelfClosingElement;
    function isJsxOpeningElement(node) {
        return node.kind === 268 /* JsxOpeningElement */;
    }
    ts.isJsxOpeningElement = isJsxOpeningElement;
    function isJsxClosingElement(node) {
        return node.kind === 269 /* JsxClosingElement */;
    }
    ts.isJsxClosingElement = isJsxClosingElement;
    function isJsxFragment(node) {
        return node.kind === 270 /* JsxFragment */;
    }
    ts.isJsxFragment = isJsxFragment;
    function isJsxOpeningFragment(node) {
        return node.kind === 271 /* JsxOpeningFragment */;
    }
    ts.isJsxOpeningFragment = isJsxOpeningFragment;
    function isJsxClosingFragment(node) {
        return node.kind === 272 /* JsxClosingFragment */;
    }
    ts.isJsxClosingFragment = isJsxClosingFragment;
    function isJsxAttribute(node) {
        return node.kind === 273 /* JsxAttribute */;
    }
    ts.isJsxAttribute = isJsxAttribute;
    function isJsxAttributes(node) {
        return node.kind === 274 /* JsxAttributes */;
    }
    ts.isJsxAttributes = isJsxAttributes;
    function isJsxSpreadAttribute(node) {
        return node.kind === 275 /* JsxSpreadAttribute */;
    }
    ts.isJsxSpreadAttribute = isJsxSpreadAttribute;
    function isJsxExpression(node) {
        return node.kind === 276 /* JsxExpression */;
    }
    ts.isJsxExpression = isJsxExpression;
    // Clauses
    function isCaseClause(node) {
        return node.kind === 277 /* CaseClause */;
    }
    ts.isCaseClause = isCaseClause;
    function isDefaultClause(node) {
        return node.kind === 278 /* DefaultClause */;
    }
    ts.isDefaultClause = isDefaultClause;
    function isHeritageClause(node) {
        return node.kind === 279 /* HeritageClause */;
    }
    ts.isHeritageClause = isHeritageClause;
    function isCatchClause(node) {
        return node.kind === 280 /* CatchClause */;
    }
    ts.isCatchClause = isCatchClause;
    // Property assignments
    function isPropertyAssignment(node) {
        return node.kind === 281 /* PropertyAssignment */;
    }
    ts.isPropertyAssignment = isPropertyAssignment;
    function isShorthandPropertyAssignment(node) {
        return node.kind === 282 /* ShorthandPropertyAssignment */;
    }
    ts.isShorthandPropertyAssignment = isShorthandPropertyAssignment;
    function isSpreadAssignment(node) {
        return node.kind === 283 /* SpreadAssignment */;
    }
    ts.isSpreadAssignment = isSpreadAssignment;
    // Enum
    function isEnumMember(node) {
        return node.kind === 284 /* EnumMember */;
    }
    ts.isEnumMember = isEnumMember;
    // Top-level nodes
    function isSourceFile(node) {
        return node.kind === 290 /* SourceFile */;
    }
    ts.isSourceFile = isSourceFile;
    function isBundle(node) {
        return node.kind === 291 /* Bundle */;
    }
    ts.isBundle = isBundle;
    function isUnparsedSource(node) {
        return node.kind === 292 /* UnparsedSource */;
    }
    ts.isUnparsedSource = isUnparsedSource;
    function isUnparsedPrepend(node) {
        return node.kind === 286 /* UnparsedPrepend */;
    }
    ts.isUnparsedPrepend = isUnparsedPrepend;
    function isUnparsedTextLike(node) {
        switch (node.kind) {
            case 287 /* UnparsedText */:
            case 288 /* UnparsedInternalText */:
                return true;
            default:
                return false;
        }
    }
    ts.isUnparsedTextLike = isUnparsedTextLike;
    function isUnparsedNode(node) {
        return isUnparsedTextLike(node) ||
            node.kind === 285 /* UnparsedPrologue */ ||
            node.kind === 289 /* UnparsedSyntheticReference */;
    }
    ts.isUnparsedNode = isUnparsedNode;
    // JSDoc
    function isJSDocTypeExpression(node) {
        return node.kind === 294 /* JSDocTypeExpression */;
    }
    ts.isJSDocTypeExpression = isJSDocTypeExpression;
    function isJSDocAllType(node) {
        return node.kind === 295 /* JSDocAllType */;
    }
    ts.isJSDocAllType = isJSDocAllType;
    function isJSDocUnknownType(node) {
        return node.kind === 296 /* JSDocUnknownType */;
    }
    ts.isJSDocUnknownType = isJSDocUnknownType;
    function isJSDocNullableType(node) {
        return node.kind === 297 /* JSDocNullableType */;
    }
    ts.isJSDocNullableType = isJSDocNullableType;
    function isJSDocNonNullableType(node) {
        return node.kind === 298 /* JSDocNonNullableType */;
    }
    ts.isJSDocNonNullableType = isJSDocNonNullableType;
    function isJSDocOptionalType(node) {
        return node.kind === 299 /* JSDocOptionalType */;
    }
    ts.isJSDocOptionalType = isJSDocOptionalType;
    function isJSDocFunctionType(node) {
        return node.kind === 300 /* JSDocFunctionType */;
    }
    ts.isJSDocFunctionType = isJSDocFunctionType;
    function isJSDocVariadicType(node) {
        return node.kind === 301 /* JSDocVariadicType */;
    }
    ts.isJSDocVariadicType = isJSDocVariadicType;
    function isJSDoc(node) {
        return node.kind === 303 /* JSDocComment */;
    }
    ts.isJSDoc = isJSDoc;
    function isJSDocAuthorTag(node) {
        return node.kind === 309 /* JSDocAuthorTag */;
    }
    ts.isJSDocAuthorTag = isJSDocAuthorTag;
    function isJSDocAugmentsTag(node) {
        return node.kind === 307 /* JSDocAugmentsTag */;
    }
    ts.isJSDocAugmentsTag = isJSDocAugmentsTag;
    function isJSDocImplementsTag(node) {
        return node.kind === 308 /* JSDocImplementsTag */;
    }
    ts.isJSDocImplementsTag = isJSDocImplementsTag;
    function isJSDocClassTag(node) {
        return node.kind === 310 /* JSDocClassTag */;
    }
    ts.isJSDocClassTag = isJSDocClassTag;
    function isJSDocPublicTag(node) {
        return node.kind === 311 /* JSDocPublicTag */;
    }
    ts.isJSDocPublicTag = isJSDocPublicTag;
    function isJSDocPrivateTag(node) {
        return node.kind === 312 /* JSDocPrivateTag */;
    }
    ts.isJSDocPrivateTag = isJSDocPrivateTag;
    function isJSDocProtectedTag(node) {
        return node.kind === 313 /* JSDocProtectedTag */;
    }
    ts.isJSDocProtectedTag = isJSDocProtectedTag;
    function isJSDocReadonlyTag(node) {
        return node.kind === 314 /* JSDocReadonlyTag */;
    }
    ts.isJSDocReadonlyTag = isJSDocReadonlyTag;
    function isJSDocEnumTag(node) {
        return node.kind === 316 /* JSDocEnumTag */;
    }
    ts.isJSDocEnumTag = isJSDocEnumTag;
    function isJSDocThisTag(node) {
        return node.kind === 319 /* JSDocThisTag */;
    }
    ts.isJSDocThisTag = isJSDocThisTag;
    function isJSDocParameterTag(node) {
        return node.kind === 317 /* JSDocParameterTag */;
    }
    ts.isJSDocParameterTag = isJSDocParameterTag;
    function isJSDocReturnTag(node) {
        return node.kind === 318 /* JSDocReturnTag */;
    }
    ts.isJSDocReturnTag = isJSDocReturnTag;
    function isJSDocTypeTag(node) {
        return node.kind === 320 /* JSDocTypeTag */;
    }
    ts.isJSDocTypeTag = isJSDocTypeTag;
    function isJSDocTemplateTag(node) {
        return node.kind === 321 /* JSDocTemplateTag */;
    }
    ts.isJSDocTemplateTag = isJSDocTemplateTag;
    function isJSDocTypedefTag(node) {
        return node.kind === 322 /* JSDocTypedefTag */;
    }
    ts.isJSDocTypedefTag = isJSDocTypedefTag;
    function isJSDocPropertyTag(node) {
        return node.kind === 323 /* JSDocPropertyTag */;
    }
    ts.isJSDocPropertyTag = isJSDocPropertyTag;
    function isJSDocPropertyLikeTag(node) {
        return node.kind === 323 /* JSDocPropertyTag */ || node.kind === 317 /* JSDocParameterTag */;
    }
    ts.isJSDocPropertyLikeTag = isJSDocPropertyLikeTag;
    function isJSDocTypeLiteral(node) {
        return node.kind === 304 /* JSDocTypeLiteral */;
    }
    ts.isJSDocTypeLiteral = isJSDocTypeLiteral;
    function isJSDocCallbackTag(node) {
        return node.kind === 315 /* JSDocCallbackTag */;
    }
    ts.isJSDocCallbackTag = isJSDocCallbackTag;
    function isJSDocSignature(node) {
        return node.kind === 305 /* JSDocSignature */;
    }
    ts.isJSDocSignature = isJSDocSignature;
    // #endregion
    // #region
    // Node tests
    //
    // All node tests in the following list should *not* reference parent pointers so that
    // they may be used with transformations.
    /* @internal */
    function isSyntaxList(n) {
        return n.kind === 324 /* SyntaxList */;
    }
    ts.isSyntaxList = isSyntaxList;
    /* @internal */
    function isNode(node) {
        return isNodeKind(node.kind);
    }
    ts.isNode = isNode;
    /* @internal */
    function isNodeKind(kind) {
        return kind >= 153 /* FirstNode */;
    }
    ts.isNodeKind = isNodeKind;
    /**
     * True if node is of some token syntax kind.
     * For example, this is true for an IfKeyword but not for an IfStatement.
     * Literals are considered tokens, except TemplateLiteral, but does include TemplateHead/Middle/Tail.
     */
    function isToken(n) {
        return n.kind >= 0 /* FirstToken */ && n.kind <= 152 /* LastToken */;
    }
    ts.isToken = isToken;
    // Node Arrays
    /* @internal */
    function isNodeArray(array) {
        return array.hasOwnProperty("pos") && array.hasOwnProperty("end");
    }
    ts.isNodeArray = isNodeArray;
    // Literals
    /* @internal */
    function isLiteralKind(kind) {
        return 8 /* FirstLiteralToken */ <= kind && kind <= 14 /* LastLiteralToken */;
    }
    ts.isLiteralKind = isLiteralKind;
    function isLiteralExpression(node) {
        return isLiteralKind(node.kind);
    }
    ts.isLiteralExpression = isLiteralExpression;
    // Pseudo-literals
    /* @internal */
    function isTemplateLiteralKind(kind) {
        return 14 /* FirstTemplateToken */ <= kind && kind <= 17 /* LastTemplateToken */;
    }
    ts.isTemplateLiteralKind = isTemplateLiteralKind;
    function isTemplateLiteralToken(node) {
        return isTemplateLiteralKind(node.kind);
    }
    ts.isTemplateLiteralToken = isTemplateLiteralToken;
    function isTemplateMiddleOrTemplateTail(node) {
        var kind = node.kind;
        return kind === 16 /* TemplateMiddle */
            || kind === 17 /* TemplateTail */;
    }
    ts.isTemplateMiddleOrTemplateTail = isTemplateMiddleOrTemplateTail;
    function isImportOrExportSpecifier(node) {
        return isImportSpecifier(node) || isExportSpecifier(node);
    }
    ts.isImportOrExportSpecifier = isImportOrExportSpecifier;
    function isTypeOnlyImportOrExportDeclaration(node) {
        switch (node.kind) {
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
                return node.parent.parent.isTypeOnly;
            case 256 /* NamespaceImport */:
                return node.parent.isTypeOnly;
            case 255 /* ImportClause */:
                return node.isTypeOnly;
            default:
                return false;
        }
    }
    ts.isTypeOnlyImportOrExportDeclaration = isTypeOnlyImportOrExportDeclaration;
    function isStringTextContainingNode(node) {
        return node.kind === 10 /* StringLiteral */ || isTemplateLiteralKind(node.kind);
    }
    ts.isStringTextContainingNode = isStringTextContainingNode;
    // Identifiers
    /* @internal */
    function isGeneratedIdentifier(node) {
        return isIdentifier(node) && (node.autoGenerateFlags & 7 /* KindMask */) > 0 /* None */;
    }
    ts.isGeneratedIdentifier = isGeneratedIdentifier;
    // Private Identifiers
    /*@internal*/
    function isPrivateIdentifierPropertyDeclaration(node) {
        return isPropertyDeclaration(node) && isPrivateIdentifier(node.name);
    }
    ts.isPrivateIdentifierPropertyDeclaration = isPrivateIdentifierPropertyDeclaration;
    /*@internal*/
    function isPrivateIdentifierPropertyAccessExpression(node) {
        return isPropertyAccessExpression(node) && isPrivateIdentifier(node.name);
    }
    ts.isPrivateIdentifierPropertyAccessExpression = isPrivateIdentifierPropertyAccessExpression;
    // Keywords
    /* @internal */
    function isModifierKind(token) {
        switch (token) {
            case 122 /* AbstractKeyword */:
            case 126 /* AsyncKeyword */:
            case 81 /* ConstKeyword */:
            case 130 /* DeclareKeyword */:
            case 84 /* DefaultKeyword */:
            case 89 /* ExportKeyword */:
            case 119 /* PublicKeyword */:
            case 117 /* PrivateKeyword */:
            case 118 /* ProtectedKeyword */:
            case 138 /* ReadonlyKeyword */:
            case 120 /* StaticKeyword */:
                return true;
        }
        return false;
    }
    ts.isModifierKind = isModifierKind;
    /* @internal */
    function isParameterPropertyModifier(kind) {
        return !!(ts.modifierToFlag(kind) & 92 /* ParameterPropertyModifier */);
    }
    ts.isParameterPropertyModifier = isParameterPropertyModifier;
    /* @internal */
    function isClassMemberModifier(idToken) {
        return isParameterPropertyModifier(idToken) || idToken === 120 /* StaticKeyword */;
    }
    ts.isClassMemberModifier = isClassMemberModifier;
    function isModifier(node) {
        return isModifierKind(node.kind);
    }
    ts.isModifier = isModifier;
    function isEntityName(node) {
        var kind = node.kind;
        return kind === 153 /* QualifiedName */
            || kind === 75 /* Identifier */;
    }
    ts.isEntityName = isEntityName;
    function isPropertyName(node) {
        var kind = node.kind;
        return kind === 75 /* Identifier */
            || kind === 76 /* PrivateIdentifier */
            || kind === 10 /* StringLiteral */
            || kind === 8 /* NumericLiteral */
            || kind === 154 /* ComputedPropertyName */;
    }
    ts.isPropertyName = isPropertyName;
    function isBindingName(node) {
        var kind = node.kind;
        return kind === 75 /* Identifier */
            || kind === 189 /* ObjectBindingPattern */
            || kind === 190 /* ArrayBindingPattern */;
    }
    ts.isBindingName = isBindingName;
    // Functions
    function isFunctionLike(node) {
        return node && isFunctionLikeKind(node.kind);
    }
    ts.isFunctionLike = isFunctionLike;
    /* @internal */
    function isFunctionLikeDeclaration(node) {
        return node && isFunctionLikeDeclarationKind(node.kind);
    }
    ts.isFunctionLikeDeclaration = isFunctionLikeDeclaration;
    function isFunctionLikeDeclarationKind(kind) {
        switch (kind) {
            case 244 /* FunctionDeclaration */:
            case 161 /* MethodDeclaration */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
                return true;
            default:
                return false;
        }
    }
    /* @internal */
    function isFunctionLikeKind(kind) {
        switch (kind) {
            case 160 /* MethodSignature */:
            case 165 /* CallSignature */:
            case 305 /* JSDocSignature */:
            case 166 /* ConstructSignature */:
            case 167 /* IndexSignature */:
            case 170 /* FunctionType */:
            case 300 /* JSDocFunctionType */:
            case 171 /* ConstructorType */:
                return true;
            default:
                return isFunctionLikeDeclarationKind(kind);
        }
    }
    ts.isFunctionLikeKind = isFunctionLikeKind;
    /* @internal */
    function isFunctionOrModuleBlock(node) {
        return isSourceFile(node) || isModuleBlock(node) || isBlock(node) && isFunctionLike(node.parent);
    }
    ts.isFunctionOrModuleBlock = isFunctionOrModuleBlock;
    // Classes
    function isClassElement(node) {
        var kind = node.kind;
        return kind === 162 /* Constructor */
            || kind === 159 /* PropertyDeclaration */
            || kind === 161 /* MethodDeclaration */
            || kind === 163 /* GetAccessor */
            || kind === 164 /* SetAccessor */
            || kind === 167 /* IndexSignature */
            || kind === 222 /* SemicolonClassElement */;
    }
    ts.isClassElement = isClassElement;
    function isClassLike(node) {
        return node && (node.kind === 245 /* ClassDeclaration */ || node.kind === 214 /* ClassExpression */);
    }
    ts.isClassLike = isClassLike;
    function isAccessor(node) {
        return node && (node.kind === 163 /* GetAccessor */ || node.kind === 164 /* SetAccessor */);
    }
    ts.isAccessor = isAccessor;
    /* @internal */
    function isMethodOrAccessor(node) {
        switch (node.kind) {
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
                return true;
            default:
                return false;
        }
    }
    ts.isMethodOrAccessor = isMethodOrAccessor;
    // Type members
    function isTypeElement(node) {
        var kind = node.kind;
        return kind === 166 /* ConstructSignature */
            || kind === 165 /* CallSignature */
            || kind === 158 /* PropertySignature */
            || kind === 160 /* MethodSignature */
            || kind === 167 /* IndexSignature */;
    }
    ts.isTypeElement = isTypeElement;
    function isClassOrTypeElement(node) {
        return isTypeElement(node) || isClassElement(node);
    }
    ts.isClassOrTypeElement = isClassOrTypeElement;
    function isObjectLiteralElementLike(node) {
        var kind = node.kind;
        return kind === 281 /* PropertyAssignment */
            || kind === 282 /* ShorthandPropertyAssignment */
            || kind === 283 /* SpreadAssignment */
            || kind === 161 /* MethodDeclaration */
            || kind === 163 /* GetAccessor */
            || kind === 164 /* SetAccessor */;
    }
    ts.isObjectLiteralElementLike = isObjectLiteralElementLike;
    // Type
    /**
     * Node test that determines whether a node is a valid type node.
     * This differs from the `isPartOfTypeNode` function which determines whether a node is *part*
     * of a TypeNode.
     */
    function isTypeNode(node) {
        return ts.isTypeNodeKind(node.kind);
    }
    ts.isTypeNode = isTypeNode;
    function isFunctionOrConstructorTypeNode(node) {
        switch (node.kind) {
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
                return true;
        }
        return false;
    }
    ts.isFunctionOrConstructorTypeNode = isFunctionOrConstructorTypeNode;
    // Binding patterns
    /* @internal */
    function isBindingPattern(node) {
        if (node) {
            var kind = node.kind;
            return kind === 190 /* ArrayBindingPattern */
                || kind === 189 /* ObjectBindingPattern */;
        }
        return false;
    }
    ts.isBindingPattern = isBindingPattern;
    /* @internal */
    function isAssignmentPattern(node) {
        var kind = node.kind;
        return kind === 192 /* ArrayLiteralExpression */
            || kind === 193 /* ObjectLiteralExpression */;
    }
    ts.isAssignmentPattern = isAssignmentPattern;
    /* @internal */
    function isArrayBindingElement(node) {
        var kind = node.kind;
        return kind === 191 /* BindingElement */
            || kind === 215 /* OmittedExpression */;
    }
    ts.isArrayBindingElement = isArrayBindingElement;
    /**
     * Determines whether the BindingOrAssignmentElement is a BindingElement-like declaration
     */
    /* @internal */
    function isDeclarationBindingElement(bindingElement) {
        switch (bindingElement.kind) {
            case 242 /* VariableDeclaration */:
            case 156 /* Parameter */:
            case 191 /* BindingElement */:
                return true;
        }
        return false;
    }
    ts.isDeclarationBindingElement = isDeclarationBindingElement;
    /**
     * Determines whether a node is a BindingOrAssignmentPattern
     */
    /* @internal */
    function isBindingOrAssignmentPattern(node) {
        return isObjectBindingOrAssignmentPattern(node)
            || isArrayBindingOrAssignmentPattern(node);
    }
    ts.isBindingOrAssignmentPattern = isBindingOrAssignmentPattern;
    /**
     * Determines whether a node is an ObjectBindingOrAssignmentPattern
     */
    /* @internal */
    function isObjectBindingOrAssignmentPattern(node) {
        switch (node.kind) {
            case 189 /* ObjectBindingPattern */:
            case 193 /* ObjectLiteralExpression */:
                return true;
        }
        return false;
    }
    ts.isObjectBindingOrAssignmentPattern = isObjectBindingOrAssignmentPattern;
    /**
     * Determines whether a node is an ArrayBindingOrAssignmentPattern
     */
    /* @internal */
    function isArrayBindingOrAssignmentPattern(node) {
        switch (node.kind) {
            case 190 /* ArrayBindingPattern */:
            case 192 /* ArrayLiteralExpression */:
                return true;
        }
        return false;
    }
    ts.isArrayBindingOrAssignmentPattern = isArrayBindingOrAssignmentPattern;
    /* @internal */
    function isPropertyAccessOrQualifiedNameOrImportTypeNode(node) {
        var kind = node.kind;
        return kind === 194 /* PropertyAccessExpression */
            || kind === 153 /* QualifiedName */
            || kind === 188 /* ImportType */;
    }
    ts.isPropertyAccessOrQualifiedNameOrImportTypeNode = isPropertyAccessOrQualifiedNameOrImportTypeNode;
    // Expression
    function isPropertyAccessOrQualifiedName(node) {
        var kind = node.kind;
        return kind === 194 /* PropertyAccessExpression */
            || kind === 153 /* QualifiedName */;
    }
    ts.isPropertyAccessOrQualifiedName = isPropertyAccessOrQualifiedName;
    function isCallLikeExpression(node) {
        switch (node.kind) {
            case 268 /* JsxOpeningElement */:
            case 267 /* JsxSelfClosingElement */:
            case 196 /* CallExpression */:
            case 197 /* NewExpression */:
            case 198 /* TaggedTemplateExpression */:
            case 157 /* Decorator */:
                return true;
            default:
                return false;
        }
    }
    ts.isCallLikeExpression = isCallLikeExpression;
    function isCallOrNewExpression(node) {
        return node.kind === 196 /* CallExpression */ || node.kind === 197 /* NewExpression */;
    }
    ts.isCallOrNewExpression = isCallOrNewExpression;
    function isTemplateLiteral(node) {
        var kind = node.kind;
        return kind === 211 /* TemplateExpression */
            || kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isTemplateLiteral = isTemplateLiteral;
    /* @internal */
    function isLeftHandSideExpression(node) {
        return isLeftHandSideExpressionKind(skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isLeftHandSideExpression = isLeftHandSideExpression;
    function isLeftHandSideExpressionKind(kind) {
        switch (kind) {
            case 194 /* PropertyAccessExpression */:
            case 195 /* ElementAccessExpression */:
            case 197 /* NewExpression */:
            case 196 /* CallExpression */:
            case 266 /* JsxElement */:
            case 267 /* JsxSelfClosingElement */:
            case 270 /* JsxFragment */:
            case 198 /* TaggedTemplateExpression */:
            case 192 /* ArrayLiteralExpression */:
            case 200 /* ParenthesizedExpression */:
            case 193 /* ObjectLiteralExpression */:
            case 214 /* ClassExpression */:
            case 201 /* FunctionExpression */:
            case 75 /* Identifier */:
            case 13 /* RegularExpressionLiteral */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 211 /* TemplateExpression */:
            case 91 /* FalseKeyword */:
            case 100 /* NullKeyword */:
            case 104 /* ThisKeyword */:
            case 106 /* TrueKeyword */:
            case 102 /* SuperKeyword */:
            case 218 /* NonNullExpression */:
            case 219 /* MetaProperty */:
            case 96 /* ImportKeyword */: // technically this is only an Expression if it's in a CallExpression
                return true;
            default:
                return false;
        }
    }
    /* @internal */
    function isUnaryExpression(node) {
        return isUnaryExpressionKind(skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isUnaryExpression = isUnaryExpression;
    function isUnaryExpressionKind(kind) {
        switch (kind) {
            case 207 /* PrefixUnaryExpression */:
            case 208 /* PostfixUnaryExpression */:
            case 203 /* DeleteExpression */:
            case 204 /* TypeOfExpression */:
            case 205 /* VoidExpression */:
            case 206 /* AwaitExpression */:
            case 199 /* TypeAssertionExpression */:
                return true;
            default:
                return isLeftHandSideExpressionKind(kind);
        }
    }
    /* @internal */
    function isUnaryExpressionWithWrite(expr) {
        switch (expr.kind) {
            case 208 /* PostfixUnaryExpression */:
                return true;
            case 207 /* PrefixUnaryExpression */:
                return expr.operator === 45 /* PlusPlusToken */ ||
                    expr.operator === 46 /* MinusMinusToken */;
            default:
                return false;
        }
    }
    ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite;
    /* @internal */
    /**
     * Determines whether a node is an expression based only on its kind.
     * Use `isExpressionNode` if not in transforms.
     */
    function isExpression(node) {
        return isExpressionKind(skipPartiallyEmittedExpressions(node).kind);
    }
    ts.isExpression = isExpression;
    function isExpressionKind(kind) {
        switch (kind) {
            case 210 /* ConditionalExpression */:
            case 212 /* YieldExpression */:
            case 202 /* ArrowFunction */:
            case 209 /* BinaryExpression */:
            case 213 /* SpreadElement */:
            case 217 /* AsExpression */:
            case 215 /* OmittedExpression */:
            case 327 /* CommaListExpression */:
            case 326 /* PartiallyEmittedExpression */:
                return true;
            default:
                return isUnaryExpressionKind(kind);
        }
    }
    function isAssertionExpression(node) {
        var kind = node.kind;
        return kind === 199 /* TypeAssertionExpression */
            || kind === 217 /* AsExpression */;
    }
    ts.isAssertionExpression = isAssertionExpression;
    /* @internal */
    function isPartiallyEmittedExpression(node) {
        return node.kind === 326 /* PartiallyEmittedExpression */;
    }
    ts.isPartiallyEmittedExpression = isPartiallyEmittedExpression;
    /* @internal */
    function isNotEmittedStatement(node) {
        return node.kind === 325 /* NotEmittedStatement */;
    }
    ts.isNotEmittedStatement = isNotEmittedStatement;
    /* @internal */
    function isSyntheticReference(node) {
        return node.kind === 330 /* SyntheticReferenceExpression */;
    }
    ts.isSyntheticReference = isSyntheticReference;
    /* @internal */
    function isNotEmittedOrPartiallyEmittedNode(node) {
        return isNotEmittedStatement(node)
            || isPartiallyEmittedExpression(node);
    }
    ts.isNotEmittedOrPartiallyEmittedNode = isNotEmittedOrPartiallyEmittedNode;
    function isIterationStatement(node, lookInLabeledStatements) {
        switch (node.kind) {
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
            case 228 /* DoStatement */:
            case 229 /* WhileStatement */:
                return true;
            case 238 /* LabeledStatement */:
                return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements);
        }
        return false;
    }
    ts.isIterationStatement = isIterationStatement;
    /* @internal */
    function isScopeMarker(node) {
        return isExportAssignment(node) || isExportDeclaration(node);
    }
    ts.isScopeMarker = isScopeMarker;
    /* @internal */
    function hasScopeMarker(statements) {
        return ts.some(statements, isScopeMarker);
    }
    ts.hasScopeMarker = hasScopeMarker;
    /* @internal */
    function needsScopeMarker(result) {
        return !ts.isAnyImportOrReExport(result) && !isExportAssignment(result) && !ts.hasModifier(result, 1 /* Export */) && !ts.isAmbientModule(result);
    }
    ts.needsScopeMarker = needsScopeMarker;
    /* @internal */
    function isExternalModuleIndicator(result) {
        // Exported top-level member indicates moduleness
        return ts.isAnyImportOrReExport(result) || isExportAssignment(result) || ts.hasModifier(result, 1 /* Export */);
    }
    ts.isExternalModuleIndicator = isExternalModuleIndicator;
    /* @internal */
    function isForInOrOfStatement(node) {
        return node.kind === 231 /* ForInStatement */ || node.kind === 232 /* ForOfStatement */;
    }
    ts.isForInOrOfStatement = isForInOrOfStatement;
    // Element
    /* @internal */
    function isConciseBody(node) {
        return isBlock(node)
            || isExpression(node);
    }
    ts.isConciseBody = isConciseBody;
    /* @internal */
    function isFunctionBody(node) {
        return isBlock(node);
    }
    ts.isFunctionBody = isFunctionBody;
    /* @internal */
    function isForInitializer(node) {
        return isVariableDeclarationList(node)
            || isExpression(node);
    }
    ts.isForInitializer = isForInitializer;
    /* @internal */
    function isModuleBody(node) {
        var kind = node.kind;
        return kind === 250 /* ModuleBlock */
            || kind === 249 /* ModuleDeclaration */
            || kind === 75 /* Identifier */;
    }
    ts.isModuleBody = isModuleBody;
    /* @internal */
    function isNamespaceBody(node) {
        var kind = node.kind;
        return kind === 250 /* ModuleBlock */
            || kind === 249 /* ModuleDeclaration */;
    }
    ts.isNamespaceBody = isNamespaceBody;
    /* @internal */
    function isJSDocNamespaceBody(node) {
        var kind = node.kind;
        return kind === 75 /* Identifier */
            || kind === 249 /* ModuleDeclaration */;
    }
    ts.isJSDocNamespaceBody = isJSDocNamespaceBody;
    /* @internal */
    function isNamedImportBindings(node) {
        var kind = node.kind;
        return kind === 257 /* NamedImports */
            || kind === 256 /* NamespaceImport */;
    }
    ts.isNamedImportBindings = isNamedImportBindings;
    /* @internal */
    function isModuleOrEnumDeclaration(node) {
        return node.kind === 249 /* ModuleDeclaration */ || node.kind === 248 /* EnumDeclaration */;
    }
    ts.isModuleOrEnumDeclaration = isModuleOrEnumDeclaration;
    function isDeclarationKind(kind) {
        return kind === 202 /* ArrowFunction */
            || kind === 191 /* BindingElement */
            || kind === 245 /* ClassDeclaration */
            || kind === 214 /* ClassExpression */
            || kind === 162 /* Constructor */
            || kind === 248 /* EnumDeclaration */
            || kind === 284 /* EnumMember */
            || kind === 263 /* ExportSpecifier */
            || kind === 244 /* FunctionDeclaration */
            || kind === 201 /* FunctionExpression */
            || kind === 163 /* GetAccessor */
            || kind === 255 /* ImportClause */
            || kind === 253 /* ImportEqualsDeclaration */
            || kind === 258 /* ImportSpecifier */
            || kind === 246 /* InterfaceDeclaration */
            || kind === 273 /* JsxAttribute */
            || kind === 161 /* MethodDeclaration */
            || kind === 160 /* MethodSignature */
            || kind === 249 /* ModuleDeclaration */
            || kind === 252 /* NamespaceExportDeclaration */
            || kind === 256 /* NamespaceImport */
            || kind === 262 /* NamespaceExport */
            || kind === 156 /* Parameter */
            || kind === 281 /* PropertyAssignment */
            || kind === 159 /* PropertyDeclaration */
            || kind === 158 /* PropertySignature */
            || kind === 164 /* SetAccessor */
            || kind === 282 /* ShorthandPropertyAssignment */
            || kind === 247 /* TypeAliasDeclaration */
            || kind === 155 /* TypeParameter */
            || kind === 242 /* VariableDeclaration */
            || kind === 322 /* JSDocTypedefTag */
            || kind === 315 /* JSDocCallbackTag */
            || kind === 323 /* JSDocPropertyTag */;
    }
    function isDeclarationStatementKind(kind) {
        return kind === 244 /* FunctionDeclaration */
            || kind === 264 /* MissingDeclaration */
            || kind === 245 /* ClassDeclaration */
            || kind === 246 /* InterfaceDeclaration */
            || kind === 247 /* TypeAliasDeclaration */
            || kind === 248 /* EnumDeclaration */
            || kind === 249 /* ModuleDeclaration */
            || kind === 254 /* ImportDeclaration */
            || kind === 253 /* ImportEqualsDeclaration */
            || kind === 260 /* ExportDeclaration */
            || kind === 259 /* ExportAssignment */
            || kind === 252 /* NamespaceExportDeclaration */;
    }
    function isStatementKindButNotDeclarationKind(kind) {
        return kind === 234 /* BreakStatement */
            || kind === 233 /* ContinueStatement */
            || kind === 241 /* DebuggerStatement */
            || kind === 228 /* DoStatement */
            || kind === 226 /* ExpressionStatement */
            || kind === 224 /* EmptyStatement */
            || kind === 231 /* ForInStatement */
            || kind === 232 /* ForOfStatement */
            || kind === 230 /* ForStatement */
            || kind === 227 /* IfStatement */
            || kind === 238 /* LabeledStatement */
            || kind === 235 /* ReturnStatement */
            || kind === 237 /* SwitchStatement */
            || kind === 239 /* ThrowStatement */
            || kind === 240 /* TryStatement */
            || kind === 225 /* VariableStatement */
            || kind === 229 /* WhileStatement */
            || kind === 236 /* WithStatement */
            || kind === 325 /* NotEmittedStatement */
            || kind === 329 /* EndOfDeclarationMarker */
            || kind === 328 /* MergeDeclarationMarker */;
    }
    /* @internal */
    function isDeclaration(node) {
        if (node.kind === 155 /* TypeParameter */) {
            return (node.parent && node.parent.kind !== 321 /* JSDocTemplateTag */) || ts.isInJSFile(node);
        }
        return isDeclarationKind(node.kind);
    }
    ts.isDeclaration = isDeclaration;
    /* @internal */
    function isDeclarationStatement(node) {
        return isDeclarationStatementKind(node.kind);
    }
    ts.isDeclarationStatement = isDeclarationStatement;
    /**
     * Determines whether the node is a statement that is not also a declaration
     */
    /* @internal */
    function isStatementButNotDeclaration(node) {
        return isStatementKindButNotDeclarationKind(node.kind);
    }
    ts.isStatementButNotDeclaration = isStatementButNotDeclaration;
    /* @internal */
    function isStatement(node) {
        var kind = node.kind;
        return isStatementKindButNotDeclarationKind(kind)
            || isDeclarationStatementKind(kind)
            || isBlockStatement(node);
    }
    ts.isStatement = isStatement;
    function isBlockStatement(node) {
        if (node.kind !== 223 /* Block */)
            return false;
        if (node.parent !== undefined) {
            if (node.parent.kind === 240 /* TryStatement */ || node.parent.kind === 280 /* CatchClause */) {
                return false;
            }
        }
        return !ts.isFunctionBlock(node);
    }
    // Module references
    /* @internal */
    function isModuleReference(node) {
        var kind = node.kind;
        return kind === 265 /* ExternalModuleReference */
            || kind === 153 /* QualifiedName */
            || kind === 75 /* Identifier */;
    }
    ts.isModuleReference = isModuleReference;
    // JSX
    /* @internal */
    function isJsxTagNameExpression(node) {
        var kind = node.kind;
        return kind === 104 /* ThisKeyword */
            || kind === 75 /* Identifier */
            || kind === 194 /* PropertyAccessExpression */;
    }
    ts.isJsxTagNameExpression = isJsxTagNameExpression;
    /* @internal */
    function isJsxChild(node) {
        var kind = node.kind;
        return kind === 266 /* JsxElement */
            || kind === 276 /* JsxExpression */
            || kind === 267 /* JsxSelfClosingElement */
            || kind === 11 /* JsxText */
            || kind === 270 /* JsxFragment */;
    }
    ts.isJsxChild = isJsxChild;
    /* @internal */
    function isJsxAttributeLike(node) {
        var kind = node.kind;
        return kind === 273 /* JsxAttribute */
            || kind === 275 /* JsxSpreadAttribute */;
    }
    ts.isJsxAttributeLike = isJsxAttributeLike;
    /* @internal */
    function isStringLiteralOrJsxExpression(node) {
        var kind = node.kind;
        return kind === 10 /* StringLiteral */
            || kind === 276 /* JsxExpression */;
    }
    ts.isStringLiteralOrJsxExpression = isStringLiteralOrJsxExpression;
    function isJsxOpeningLikeElement(node) {
        var kind = node.kind;
        return kind === 268 /* JsxOpeningElement */
            || kind === 267 /* JsxSelfClosingElement */;
    }
    ts.isJsxOpeningLikeElement = isJsxOpeningLikeElement;
    // Clauses
    function isCaseOrDefaultClause(node) {
        var kind = node.kind;
        return kind === 277 /* CaseClause */
            || kind === 278 /* DefaultClause */;
    }
    ts.isCaseOrDefaultClause = isCaseOrDefaultClause;
    // JSDoc
    /** True if node is of some JSDoc syntax kind. */
    /* @internal */
    function isJSDocNode(node) {
        return node.kind >= 294 /* FirstJSDocNode */ && node.kind <= 323 /* LastJSDocNode */;
    }
    ts.isJSDocNode = isJSDocNode;
    /** True if node is of a kind that may contain comment text. */
    function isJSDocCommentContainingNode(node) {
        return node.kind === 303 /* JSDocComment */ || node.kind === 302 /* JSDocNamepathType */ || isJSDocTag(node) || isJSDocTypeLiteral(node) || isJSDocSignature(node);
    }
    ts.isJSDocCommentContainingNode = isJSDocCommentContainingNode;
    // TODO: determine what this does before making it public.
    /* @internal */
    function isJSDocTag(node) {
        return node.kind >= 306 /* FirstJSDocTagNode */ && node.kind <= 323 /* LastJSDocTagNode */;
    }
    ts.isJSDocTag = isJSDocTag;
    function isSetAccessor(node) {
        return node.kind === 164 /* SetAccessor */;
    }
    ts.isSetAccessor = isSetAccessor;
    function isGetAccessor(node) {
        return node.kind === 163 /* GetAccessor */;
    }
    ts.isGetAccessor = isGetAccessor;
    /** True if has jsdoc nodes attached to it. */
    /* @internal */
    // TODO: GH#19856 Would like to return `node is Node & { jsDoc: JSDoc[] }` but it causes long compile times
    function hasJSDocNodes(node) {
        var jsDoc = node.jsDoc;
        return !!jsDoc && jsDoc.length > 0;
    }
    ts.hasJSDocNodes = hasJSDocNodes;
    /** True if has type node attached to it. */
    /* @internal */
    function hasType(node) {
        return !!node.type;
    }
    ts.hasType = hasType;
    /** True if has initializer node attached to it. */
    /* @internal */
    function hasInitializer(node) {
        return !!node.initializer;
    }
    ts.hasInitializer = hasInitializer;
    /** True if has initializer node attached to it. */
    function hasOnlyExpressionInitializer(node) {
        switch (node.kind) {
            case 242 /* VariableDeclaration */:
            case 156 /* Parameter */:
            case 191 /* BindingElement */:
            case 158 /* PropertySignature */:
            case 159 /* PropertyDeclaration */:
            case 281 /* PropertyAssignment */:
            case 284 /* EnumMember */:
                return true;
            default:
                return false;
        }
    }
    ts.hasOnlyExpressionInitializer = hasOnlyExpressionInitializer;
    function isObjectLiteralElement(node) {
        return node.kind === 273 /* JsxAttribute */ || node.kind === 275 /* JsxSpreadAttribute */ || isObjectLiteralElementLike(node);
    }
    ts.isObjectLiteralElement = isObjectLiteralElement;
    /* @internal */
    function isTypeReferenceType(node) {
        return node.kind === 169 /* TypeReference */ || node.kind === 216 /* ExpressionWithTypeArguments */;
    }
    ts.isTypeReferenceType = isTypeReferenceType;
    var MAX_SMI_X86 = 1073741823;
    /* @internal */
    function guessIndentation(lines) {
        var indentation = MAX_SMI_X86;
        for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) {
            var line = lines_1[_i];
            if (!line.length) {
                continue;
            }
            var i = 0;
            for (; i < line.length && i < indentation; i++) {
                if (!ts.isWhiteSpaceLike(line.charCodeAt(i))) {
                    break;
                }
            }
            if (i < indentation) {
                indentation = i;
            }
            if (indentation === 0) {
                return 0;
            }
        }
        return indentation === MAX_SMI_X86 ? undefined : indentation;
    }
    ts.guessIndentation = guessIndentation;
    function isStringLiteralLike(node) {
        return node.kind === 10 /* StringLiteral */ || node.kind === 14 /* NoSubstitutionTemplateLiteral */;
    }
    ts.isStringLiteralLike = isStringLiteralLike;
    // #endregion
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    ts.resolvingEmptyArray = [];
    ts.emptyMap = ts.createMap();
    ts.emptyUnderscoreEscapedMap = ts.emptyMap;
    ts.externalHelpersModuleNameText = "tslib";
    ts.defaultMaximumTruncationLength = 160;
    ts.noTruncationMaximumTruncationLength = 1000000;
    function getDeclarationOfKind(symbol, kind) {
        var declarations = symbol.declarations;
        if (declarations) {
            for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) {
                var declaration = declarations_1[_i];
                if (declaration.kind === kind) {
                    return declaration;
                }
            }
        }
        return undefined;
    }
    ts.getDeclarationOfKind = getDeclarationOfKind;
    /** Create a new escaped identifier map. */
    function createUnderscoreEscapedMap() {
        return new ts.Map();
    }
    ts.createUnderscoreEscapedMap = createUnderscoreEscapedMap;
    function hasEntries(map) {
        return !!map && !!map.size;
    }
    ts.hasEntries = hasEntries;
    function createSymbolTable(symbols) {
        var result = ts.createMap();
        if (symbols) {
            for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) {
                var symbol = symbols_1[_i];
                result.set(symbol.escapedName, symbol);
            }
        }
        return result;
    }
    ts.createSymbolTable = createSymbolTable;
    function isTransientSymbol(symbol) {
        return (symbol.flags & 33554432 /* Transient */) !== 0;
    }
    ts.isTransientSymbol = isTransientSymbol;
    var stringWriter = createSingleLineStringWriter();
    function createSingleLineStringWriter() {
        var str = "";
        var writeText = function (text) { return str += text; };
        return {
            getText: function () { return str; },
            write: writeText,
            rawWrite: writeText,
            writeKeyword: writeText,
            writeOperator: writeText,
            writePunctuation: writeText,
            writeSpace: writeText,
            writeStringLiteral: writeText,
            writeLiteral: writeText,
            writeParameter: writeText,
            writeProperty: writeText,
            writeSymbol: function (s, _) { return writeText(s); },
            writeTrailingSemicolon: writeText,
            writeComment: writeText,
            getTextPos: function () { return str.length; },
            getLine: function () { return 0; },
            getColumn: function () { return 0; },
            getIndent: function () { return 0; },
            isAtStartOfLine: function () { return false; },
            hasTrailingComment: function () { return false; },
            hasTrailingWhitespace: function () { return !!str.length && ts.isWhiteSpaceLike(str.charCodeAt(str.length - 1)); },
            // Completely ignore indentation for string writers.  And map newlines to
            // a single space.
            writeLine: function () { return str += " "; },
            increaseIndent: ts.noop,
            decreaseIndent: ts.noop,
            clear: function () { return str = ""; },
            trackSymbol: ts.noop,
            reportInaccessibleThisError: ts.noop,
            reportInaccessibleUniqueSymbolError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
        };
    }
    function changesAffectModuleResolution(oldOptions, newOptions) {
        return oldOptions.configFilePath !== newOptions.configFilePath ||
            optionsHaveModuleResolutionChanges(oldOptions, newOptions);
    }
    ts.changesAffectModuleResolution = changesAffectModuleResolution;
    function optionsHaveModuleResolutionChanges(oldOptions, newOptions) {
        return ts.moduleResolutionOptionDeclarations.some(function (o) {
            return !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(newOptions, o));
        });
    }
    ts.optionsHaveModuleResolutionChanges = optionsHaveModuleResolutionChanges;
    function findAncestor(node, callback) {
        while (node) {
            var result = callback(node);
            if (result === "quit") {
                return undefined;
            }
            else if (result) {
                return node;
            }
            node = node.parent;
        }
        return undefined;
    }
    ts.findAncestor = findAncestor;
    function forEachAncestor(node, callback) {
        while (true) {
            var res = callback(node);
            if (res === "quit")
                return undefined;
            if (res !== undefined)
                return res;
            if (ts.isSourceFile(node))
                return undefined;
            node = node.parent;
        }
    }
    ts.forEachAncestor = forEachAncestor;
    function forEachEntry(map, callback) {
        var iterator = map.entries();
        for (var iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
            var _a = iterResult.value, key = _a[0], value = _a[1];
            var result = callback(value, key);
            if (result) {
                return result;
            }
        }
        return undefined;
    }
    ts.forEachEntry = forEachEntry;
    function forEachKey(map, callback) {
        var iterator = map.keys();
        for (var iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
            var result = callback(iterResult.value);
            if (result) {
                return result;
            }
        }
        return undefined;
    }
    ts.forEachKey = forEachKey;
    function copyEntries(source, target) {
        source.forEach(function (value, key) {
            target.set(key, value);
        });
    }
    ts.copyEntries = copyEntries;
    function arrayToSet(array, makeKey) {
        return ts.arrayToMap(array, makeKey || (function (s) { return s; }), ts.returnTrue);
    }
    ts.arrayToSet = arrayToSet;
    function cloneMap(map) {
        var clone = ts.createMap();
        copyEntries(map, clone);
        return clone;
    }
    ts.cloneMap = cloneMap;
    function usingSingleLineStringWriter(action) {
        var oldString = stringWriter.getText();
        try {
            action(stringWriter);
            return stringWriter.getText();
        }
        finally {
            stringWriter.clear();
            stringWriter.writeKeyword(oldString);
        }
    }
    ts.usingSingleLineStringWriter = usingSingleLineStringWriter;
    function getFullWidth(node) {
        return node.end - node.pos;
    }
    ts.getFullWidth = getFullWidth;
    function getResolvedModule(sourceFile, moduleNameText) {
        return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText);
    }
    ts.getResolvedModule = getResolvedModule;
    function setResolvedModule(sourceFile, moduleNameText, resolvedModule) {
        if (!sourceFile.resolvedModules) {
            sourceFile.resolvedModules = ts.createMap();
        }
        sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
    }
    ts.setResolvedModule = setResolvedModule;
    function setResolvedTypeReferenceDirective(sourceFile, typeReferenceDirectiveName, resolvedTypeReferenceDirective) {
        if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
            sourceFile.resolvedTypeReferenceDirectiveNames = ts.createMap();
        }
        sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective);
    }
    ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective;
    function projectReferenceIsEqualTo(oldRef, newRef) {
        return oldRef.path === newRef.path &&
            !oldRef.prepend === !newRef.prepend &&
            !oldRef.circular === !newRef.circular;
    }
    ts.projectReferenceIsEqualTo = projectReferenceIsEqualTo;
    function moduleResolutionIsEqualTo(oldResolution, newResolution) {
        return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
            oldResolution.extension === newResolution.extension &&
            oldResolution.resolvedFileName === newResolution.resolvedFileName &&
            oldResolution.originalPath === newResolution.originalPath &&
            packageIdIsEqual(oldResolution.packageId, newResolution.packageId);
    }
    ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo;
    function packageIdIsEqual(a, b) {
        return a === b || !!a && !!b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version;
    }
    function packageIdToString(_a) {
        var name = _a.name, subModuleName = _a.subModuleName, version = _a.version;
        var fullName = subModuleName ? name + "/" + subModuleName : name;
        return fullName + "@" + version;
    }
    ts.packageIdToString = packageIdToString;
    function typeDirectiveIsEqualTo(oldResolution, newResolution) {
        return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary;
    }
    ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo;
    function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) {
        ts.Debug.assert(names.length === newResolutions.length);
        for (var i = 0; i < names.length; i++) {
            var newResolution = newResolutions[i];
            var oldResolution = oldResolutions && oldResolutions.get(names[i]);
            var changed = oldResolution
                ? !newResolution || !comparer(oldResolution, newResolution)
                : newResolution;
            if (changed) {
                return true;
            }
        }
        return false;
    }
    ts.hasChangesInResolutions = hasChangesInResolutions;
    // Returns true if this node contains a parse error anywhere underneath it.
    function containsParseError(node) {
        aggregateChildData(node);
        return (node.flags & 262144 /* ThisNodeOrAnySubNodesHasError */) !== 0;
    }
    ts.containsParseError = containsParseError;
    function aggregateChildData(node) {
        if (!(node.flags & 524288 /* HasAggregatedChildData */)) {
            // A node is considered to contain a parse error if:
            //  a) the parser explicitly marked that it had an error
            //  b) any of it's children reported that it had an error.
            var thisNodeOrAnySubNodesHasError = ((node.flags & 65536 /* ThisNodeHasError */) !== 0) ||
                ts.forEachChild(node, containsParseError);
            // If so, mark ourselves accordingly.
            if (thisNodeOrAnySubNodesHasError) {
                node.flags |= 262144 /* ThisNodeOrAnySubNodesHasError */;
            }
            // Also mark that we've propagated the child information to this node.  This way we can
            // always consult the bit directly on this node without needing to check its children
            // again.
            node.flags |= 524288 /* HasAggregatedChildData */;
        }
    }
    function getSourceFileOfNode(node) {
        while (node && node.kind !== 290 /* SourceFile */) {
            node = node.parent;
        }
        return node;
    }
    ts.getSourceFileOfNode = getSourceFileOfNode;
    function isStatementWithLocals(node) {
        switch (node.kind) {
            case 223 /* Block */:
            case 251 /* CaseBlock */:
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
                return true;
        }
        return false;
    }
    ts.isStatementWithLocals = isStatementWithLocals;
    function getStartPositionOfLine(line, sourceFile) {
        ts.Debug.assert(line >= 0);
        return ts.getLineStarts(sourceFile)[line];
    }
    ts.getStartPositionOfLine = getStartPositionOfLine;
    // This is a useful function for debugging purposes.
    function nodePosToString(node) {
        var file = getSourceFileOfNode(node);
        var loc = ts.getLineAndCharacterOfPosition(file, node.pos);
        return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")";
    }
    ts.nodePosToString = nodePosToString;
    function getEndLinePosition(line, sourceFile) {
        ts.Debug.assert(line >= 0);
        var lineStarts = ts.getLineStarts(sourceFile);
        var lineIndex = line;
        var sourceText = sourceFile.text;
        if (lineIndex + 1 === lineStarts.length) {
            // last line - return EOF
            return sourceText.length - 1;
        }
        else {
            // current line start
            var start = lineStarts[lineIndex];
            // take the start position of the next line - 1 = it should be some line break
            var pos = lineStarts[lineIndex + 1] - 1;
            ts.Debug.assert(ts.isLineBreak(sourceText.charCodeAt(pos)));
            // walk backwards skipping line breaks, stop the the beginning of current line.
            // i.e:
            // <some text>
            // $ <- end of line for this position should match the start position
            while (start <= pos && ts.isLineBreak(sourceText.charCodeAt(pos))) {
                pos--;
            }
            return pos;
        }
    }
    ts.getEndLinePosition = getEndLinePosition;
    /**
     * Returns a value indicating whether a name is unique globally or within the current file.
     * Note: This does not consider whether a name appears as a free identifier or not, so at the expression `x.y` this includes both `x` and `y`.
     */
    function isFileLevelUniqueName(sourceFile, name, hasGlobalName) {
        return !(hasGlobalName && hasGlobalName(name)) && !sourceFile.identifiers.has(name);
    }
    ts.isFileLevelUniqueName = isFileLevelUniqueName;
    // Returns true if this node is missing from the actual source code. A 'missing' node is different
    // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes
    // in the tree), it is definitely missing. However, a node may be defined, but still be
    // missing.  This happens whenever the parser knows it needs to parse something, but can't
    // get anything in the source code that it expects at that location. For example:
    //
    //          let a: ;
    //
    // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source
    // code). So the parser will attempt to parse out a type, and will create an actual node.
    // However, this node will be 'missing' in the sense that no actual source-code/tokens are
    // contained within it.
    function nodeIsMissing(node) {
        if (node === undefined) {
            return true;
        }
        return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */;
    }
    ts.nodeIsMissing = nodeIsMissing;
    function nodeIsPresent(node) {
        return !nodeIsMissing(node);
    }
    ts.nodeIsPresent = nodeIsPresent;
    function insertStatementsAfterPrologue(to, from, isPrologueDirective) {
        if (from === undefined || from.length === 0)
            return to;
        var statementIndex = 0;
        // skip all prologue directives to insert at the correct position
        for (; statementIndex < to.length; ++statementIndex) {
            if (!isPrologueDirective(to[statementIndex])) {
                break;
            }
        }
        to.splice.apply(to, __spreadArrays([statementIndex, 0], from));
        return to;
    }
    function insertStatementAfterPrologue(to, statement, isPrologueDirective) {
        if (statement === undefined)
            return to;
        var statementIndex = 0;
        // skip all prologue directives to insert at the correct position
        for (; statementIndex < to.length; ++statementIndex) {
            if (!isPrologueDirective(to[statementIndex])) {
                break;
            }
        }
        to.splice(statementIndex, 0, statement);
        return to;
    }
    function isAnyPrologueDirective(node) {
        return isPrologueDirective(node) || !!(getEmitFlags(node) & 1048576 /* CustomPrologue */);
    }
    /**
     * Prepends statements to an array while taking care of prologue directives.
     */
    function insertStatementsAfterStandardPrologue(to, from) {
        return insertStatementsAfterPrologue(to, from, isPrologueDirective);
    }
    ts.insertStatementsAfterStandardPrologue = insertStatementsAfterStandardPrologue;
    function insertStatementsAfterCustomPrologue(to, from) {
        return insertStatementsAfterPrologue(to, from, isAnyPrologueDirective);
    }
    ts.insertStatementsAfterCustomPrologue = insertStatementsAfterCustomPrologue;
    /**
     * Prepends statements to an array while taking care of prologue directives.
     */
    function insertStatementAfterStandardPrologue(to, statement) {
        return insertStatementAfterPrologue(to, statement, isPrologueDirective);
    }
    ts.insertStatementAfterStandardPrologue = insertStatementAfterStandardPrologue;
    function insertStatementAfterCustomPrologue(to, statement) {
        return insertStatementAfterPrologue(to, statement, isAnyPrologueDirective);
    }
    ts.insertStatementAfterCustomPrologue = insertStatementAfterCustomPrologue;
    /**
     * Determine if the given comment is a triple-slash
     *
     * @return true if the comment is a triple-slash comment else false
     */
    function isRecognizedTripleSlashComment(text, commentPos, commentEnd) {
        // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text
        // so that we don't end up computing comment string and doing match for all // comments
        if (text.charCodeAt(commentPos + 1) === 47 /* slash */ &&
            commentPos + 2 < commentEnd &&
            text.charCodeAt(commentPos + 2) === 47 /* slash */) {
            var textSubStr = text.substring(commentPos, commentEnd);
            return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) ||
                textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) ||
                textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) ||
                textSubStr.match(defaultLibReferenceRegEx) ?
                true : false;
        }
        return false;
    }
    ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment;
    function isPinnedComment(text, start) {
        return text.charCodeAt(start + 1) === 42 /* asterisk */ &&
            text.charCodeAt(start + 2) === 33 /* exclamation */;
    }
    ts.isPinnedComment = isPinnedComment;
    function createCommentDirectivesMap(sourceFile, commentDirectives) {
        var directivesByLine = ts.createMapFromEntries(commentDirectives.map(function (commentDirective) { return ([
            "" + ts.getLineAndCharacterOfPosition(sourceFile, commentDirective.range.end).line,
            commentDirective,
        ]); }));
        var usedLines = ts.createMap();
        return { getUnusedExpectations: getUnusedExpectations, markUsed: markUsed };
        function getUnusedExpectations() {
            return ts.arrayFrom(directivesByLine.entries())
                .filter(function (_a) {
                var line = _a[0], directive = _a[1];
                return directive.type === 0 /* ExpectError */ && !usedLines.get(line);
            })
                .map(function (_a) {
                var _ = _a[0], directive = _a[1];
                return directive;
            });
        }
        function markUsed(line) {
            if (!directivesByLine.has("" + line)) {
                return false;
            }
            usedLines.set("" + line, true);
            return true;
        }
    }
    ts.createCommentDirectivesMap = createCommentDirectivesMap;
    function getTokenPosOfNode(node, sourceFile, includeJsDoc) {
        // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't*
        // want to skip trivia because this will launch us forward to the next token.
        if (nodeIsMissing(node)) {
            return node.pos;
        }
        if (ts.isJSDocNode(node)) {
            return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
        }
        if (includeJsDoc && ts.hasJSDocNodes(node)) {
            return getTokenPosOfNode(node.jsDoc[0], sourceFile);
        }
        // For a syntax list, it is possible that one of its children has JSDocComment nodes, while
        // the syntax list itself considers them as normal trivia. Therefore if we simply skip
        // trivia for the list, we may have skipped the JSDocComment as well. So we should process its
        // first child to determine the actual position of its first token.
        if (node.kind === 324 /* SyntaxList */ && node._children.length > 0) {
            return getTokenPosOfNode(node._children[0], sourceFile, includeJsDoc);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos);
    }
    ts.getTokenPosOfNode = getTokenPosOfNode;
    function getNonDecoratorTokenPosOfNode(node, sourceFile) {
        if (nodeIsMissing(node) || !node.decorators) {
            return getTokenPosOfNode(node, sourceFile);
        }
        return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end);
    }
    ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode;
    function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        return getTextOfNodeFromSourceText(sourceFile.text, node, includeTrivia);
    }
    ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile;
    function isJSDocTypeExpressionOrChild(node) {
        return !!findAncestor(node, ts.isJSDocTypeExpression);
    }
    function getTextOfNodeFromSourceText(sourceText, node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        if (nodeIsMissing(node)) {
            return "";
        }
        var text = sourceText.substring(includeTrivia ? node.pos : ts.skipTrivia(sourceText, node.pos), node.end);
        if (isJSDocTypeExpressionOrChild(node)) {
            // strip space + asterisk at line start
            text = text.replace(/(^|\r?\n|\r)\s*\*\s*/g, "$1");
        }
        return text;
    }
    ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText;
    function getTextOfNode(node, includeTrivia) {
        if (includeTrivia === void 0) { includeTrivia = false; }
        return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia);
    }
    ts.getTextOfNode = getTextOfNode;
    function getPos(range) {
        return range.pos;
    }
    /**
     * Note: it is expected that the `nodeArray` and the `node` are within the same file.
     * For example, searching for a `SourceFile` in a `SourceFile[]` wouldn't work.
     */
    function indexOfNode(nodeArray, node) {
        return ts.binarySearch(nodeArray, node, getPos, ts.compareValues);
    }
    ts.indexOfNode = indexOfNode;
    /**
     * Gets flags that control emit behavior of a node.
     */
    function getEmitFlags(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.flags || 0;
    }
    ts.getEmitFlags = getEmitFlags;
    function getLiteralText(node, sourceFile, neverAsciiEscape, jsxAttributeEscape) {
        // If we don't need to downlevel and we can reach the original source text using
        // the node's parent reference, then simply get the text as it was originally written.
        if (!nodeIsSynthesized(node) && node.parent && !((ts.isNumericLiteral(node) && node.numericLiteralFlags & 512 /* ContainsSeparator */) ||
            ts.isBigIntLiteral(node))) {
            return getSourceTextOfNodeFromSourceFile(sourceFile, node);
        }
        // If we can't reach the original source text, use the canonical form if it's a number,
        // or a (possibly escaped) quoted form of the original text if it's string-like.
        switch (node.kind) {
            case 10 /* StringLiteral */: {
                var escapeText = jsxAttributeEscape ? escapeJsxAttributeString :
                    neverAsciiEscape || (getEmitFlags(node) & 16777216 /* NoAsciiEscaping */) ? escapeString :
                        escapeNonAsciiString;
                if (node.singleQuote) {
                    return "'" + escapeText(node.text, 39 /* singleQuote */) + "'";
                }
                else {
                    return '"' + escapeText(node.text, 34 /* doubleQuote */) + '"';
                }
            }
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 15 /* TemplateHead */:
            case 16 /* TemplateMiddle */:
            case 17 /* TemplateTail */: {
                // If a NoSubstitutionTemplateLiteral appears to have a substitution in it, the original text
                // had to include a backslash: `not \${a} substitution`.
                var escapeText = neverAsciiEscape || (getEmitFlags(node) & 16777216 /* NoAsciiEscaping */) ? escapeString :
                    escapeNonAsciiString;
                var rawText = node.rawText || escapeTemplateSubstitution(escapeText(node.text, 96 /* backtick */));
                switch (node.kind) {
                    case 14 /* NoSubstitutionTemplateLiteral */:
                        return "`" + rawText + "`";
                    case 15 /* TemplateHead */:
                        return "`" + rawText + "${";
                    case 16 /* TemplateMiddle */:
                        return "}" + rawText + "${";
                    case 17 /* TemplateTail */:
                        return "}" + rawText + "`";
                }
                break;
            }
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 13 /* RegularExpressionLiteral */:
                return node.text;
        }
        return ts.Debug.fail("Literal kind '" + node.kind + "' not accounted for.");
    }
    ts.getLiteralText = getLiteralText;
    function getTextOfConstantValue(value) {
        return ts.isString(value) ? '"' + escapeNonAsciiString(value) + '"' : "" + value;
    }
    ts.getTextOfConstantValue = getTextOfConstantValue;
    // Make an identifier from an external module name by extracting the string after the last "/" and replacing
    // all non-alphanumeric characters with underscores
    function makeIdentifierFromModuleName(moduleName) {
        return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_");
    }
    ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName;
    function isBlockOrCatchScoped(declaration) {
        return (ts.getCombinedNodeFlags(declaration) & 3 /* BlockScoped */) !== 0 ||
            isCatchClauseVariableDeclarationOrBindingElement(declaration);
    }
    ts.isBlockOrCatchScoped = isBlockOrCatchScoped;
    function isCatchClauseVariableDeclarationOrBindingElement(declaration) {
        var node = getRootDeclaration(declaration);
        return node.kind === 242 /* VariableDeclaration */ && node.parent.kind === 280 /* CatchClause */;
    }
    ts.isCatchClauseVariableDeclarationOrBindingElement = isCatchClauseVariableDeclarationOrBindingElement;
    function isAmbientModule(node) {
        return ts.isModuleDeclaration(node) && (node.name.kind === 10 /* StringLiteral */ || isGlobalScopeAugmentation(node));
    }
    ts.isAmbientModule = isAmbientModule;
    function isModuleWithStringLiteralName(node) {
        return ts.isModuleDeclaration(node) && node.name.kind === 10 /* StringLiteral */;
    }
    ts.isModuleWithStringLiteralName = isModuleWithStringLiteralName;
    function isNonGlobalAmbientModule(node) {
        return ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name);
    }
    ts.isNonGlobalAmbientModule = isNonGlobalAmbientModule;
    /**
     * An effective module (namespace) declaration is either
     * 1. An actual declaration: namespace X { ... }
     * 2. A Javascript declaration, which is:
     *    An identifier in a nested property access expression: Y in `X.Y.Z = { ... }`
     */
    function isEffectiveModuleDeclaration(node) {
        return ts.isModuleDeclaration(node) || ts.isIdentifier(node);
    }
    ts.isEffectiveModuleDeclaration = isEffectiveModuleDeclaration;
    /** Given a symbol for a module, checks that it is a shorthand ambient module. */
    function isShorthandAmbientModuleSymbol(moduleSymbol) {
        return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
    }
    ts.isShorthandAmbientModuleSymbol = isShorthandAmbientModuleSymbol;
    function isShorthandAmbientModule(node) {
        // The only kind of module that can be missing a body is a shorthand ambient module.
        return node && node.kind === 249 /* ModuleDeclaration */ && (!node.body);
    }
    function isBlockScopedContainerTopLevel(node) {
        return node.kind === 290 /* SourceFile */ ||
            node.kind === 249 /* ModuleDeclaration */ ||
            ts.isFunctionLike(node);
    }
    ts.isBlockScopedContainerTopLevel = isBlockScopedContainerTopLevel;
    function isGlobalScopeAugmentation(module) {
        return !!(module.flags & 1024 /* GlobalAugmentation */);
    }
    ts.isGlobalScopeAugmentation = isGlobalScopeAugmentation;
    function isExternalModuleAugmentation(node) {
        return isAmbientModule(node) && isModuleAugmentationExternal(node);
    }
    ts.isExternalModuleAugmentation = isExternalModuleAugmentation;
    function isModuleAugmentationExternal(node) {
        // external module augmentation is a ambient module declaration that is either:
        // - defined in the top level scope and source file is an external module
        // - defined inside ambient module declaration located in the top level scope and source file not an external module
        switch (node.parent.kind) {
            case 290 /* SourceFile */:
                return ts.isExternalModule(node.parent);
            case 250 /* ModuleBlock */:
                return isAmbientModule(node.parent.parent) && ts.isSourceFile(node.parent.parent.parent) && !ts.isExternalModule(node.parent.parent.parent);
        }
        return false;
    }
    ts.isModuleAugmentationExternal = isModuleAugmentationExternal;
    function getNonAugmentationDeclaration(symbol) {
        return ts.find(symbol.declarations, function (d) { return !isExternalModuleAugmentation(d) && !(ts.isModuleDeclaration(d) && isGlobalScopeAugmentation(d)); });
    }
    ts.getNonAugmentationDeclaration = getNonAugmentationDeclaration;
    function isEffectiveExternalModule(node, compilerOptions) {
        return ts.isExternalModule(node) || compilerOptions.isolatedModules || ((getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS) && !!node.commonJsModuleIndicator);
    }
    ts.isEffectiveExternalModule = isEffectiveExternalModule;
    /**
     * Returns whether the source file will be treated as if it were in strict mode at runtime.
     */
    function isEffectiveStrictModeSourceFile(node, compilerOptions) {
        // We can only verify strict mode for JS/TS files
        switch (node.scriptKind) {
            case 1 /* JS */:
            case 3 /* TS */:
            case 2 /* JSX */:
            case 4 /* TSX */:
                break;
            default:
                return false;
        }
        // Strict mode does not matter for declaration files.
        if (node.isDeclarationFile) {
            return false;
        }
        // If `alwaysStrict` is set, then treat the file as strict.
        if (getStrictOptionValue(compilerOptions, "alwaysStrict")) {
            return true;
        }
        // Starting with a "use strict" directive indicates the file is strict.
        if (ts.startsWithUseStrict(node.statements)) {
            return true;
        }
        if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
            // ECMAScript Modules are always strict.
            if (getEmitModuleKind(compilerOptions) >= ts.ModuleKind.ES2015) {
                return true;
            }
            // Other modules are strict unless otherwise specified.
            return !compilerOptions.noImplicitUseStrict;
        }
        return false;
    }
    ts.isEffectiveStrictModeSourceFile = isEffectiveStrictModeSourceFile;
    function isBlockScope(node, parentNode) {
        switch (node.kind) {
            case 290 /* SourceFile */:
            case 251 /* CaseBlock */:
            case 280 /* CatchClause */:
            case 249 /* ModuleDeclaration */:
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
            case 162 /* Constructor */:
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
                return true;
            case 223 /* Block */:
                // function block is not considered block-scope container
                // see comment in binder.ts: bind(...), case for SyntaxKind.Block
                return !ts.isFunctionLike(parentNode);
        }
        return false;
    }
    ts.isBlockScope = isBlockScope;
    function isDeclarationWithTypeParameters(node) {
        switch (node.kind) {
            case 315 /* JSDocCallbackTag */:
            case 322 /* JSDocTypedefTag */:
            case 305 /* JSDocSignature */:
                return true;
            default:
                ts.assertType(node);
                return isDeclarationWithTypeParameterChildren(node);
        }
    }
    ts.isDeclarationWithTypeParameters = isDeclarationWithTypeParameters;
    function isDeclarationWithTypeParameterChildren(node) {
        switch (node.kind) {
            case 165 /* CallSignature */:
            case 166 /* ConstructSignature */:
            case 160 /* MethodSignature */:
            case 167 /* IndexSignature */:
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
            case 300 /* JSDocFunctionType */:
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 321 /* JSDocTemplateTag */:
            case 244 /* FunctionDeclaration */:
            case 161 /* MethodDeclaration */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
                return true;
            default:
                ts.assertType(node);
                return false;
        }
    }
    ts.isDeclarationWithTypeParameterChildren = isDeclarationWithTypeParameterChildren;
    function isAnyImportSyntax(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
            case 253 /* ImportEqualsDeclaration */:
                return true;
            default:
                return false;
        }
    }
    ts.isAnyImportSyntax = isAnyImportSyntax;
    function isLateVisibilityPaintedStatement(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
            case 253 /* ImportEqualsDeclaration */:
            case 225 /* VariableStatement */:
            case 245 /* ClassDeclaration */:
            case 244 /* FunctionDeclaration */:
            case 249 /* ModuleDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 246 /* InterfaceDeclaration */:
            case 248 /* EnumDeclaration */:
                return true;
            default:
                return false;
        }
    }
    ts.isLateVisibilityPaintedStatement = isLateVisibilityPaintedStatement;
    function isAnyImportOrReExport(node) {
        return isAnyImportSyntax(node) || ts.isExportDeclaration(node);
    }
    ts.isAnyImportOrReExport = isAnyImportOrReExport;
    // Gets the nearest enclosing block scope container that has the provided node
    // as a descendant, that is not the provided node.
    function getEnclosingBlockScopeContainer(node) {
        return findAncestor(node.parent, function (current) { return isBlockScope(current, current.parent); });
    }
    ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer;
    // Return display name of an identifier
    // Computed property names will just be emitted as "[<expr>]", where <expr> is the source
    // text of the expression in the computed property.
    function declarationNameToString(name) {
        return !name || getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
    }
    ts.declarationNameToString = declarationNameToString;
    function getNameFromIndexInfo(info) {
        return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
    }
    ts.getNameFromIndexInfo = getNameFromIndexInfo;
    function isComputedNonLiteralName(name) {
        return name.kind === 154 /* ComputedPropertyName */ && !isStringOrNumericLiteralLike(name.expression);
    }
    ts.isComputedNonLiteralName = isComputedNonLiteralName;
    function getTextOfPropertyName(name) {
        switch (name.kind) {
            case 75 /* Identifier */:
            case 76 /* PrivateIdentifier */:
                return name.escapedText;
            case 10 /* StringLiteral */:
            case 8 /* NumericLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
                return ts.escapeLeadingUnderscores(name.text);
            case 154 /* ComputedPropertyName */:
                if (isStringOrNumericLiteralLike(name.expression))
                    return ts.escapeLeadingUnderscores(name.expression.text);
                return ts.Debug.fail("Text of property name cannot be read from non-literal-valued ComputedPropertyNames");
            default:
                return ts.Debug.assertNever(name);
        }
    }
    ts.getTextOfPropertyName = getTextOfPropertyName;
    function entityNameToString(name) {
        switch (name.kind) {
            case 104 /* ThisKeyword */:
                return "this";
            case 76 /* PrivateIdentifier */:
            case 75 /* Identifier */:
                return getFullWidth(name) === 0 ? ts.idText(name) : getTextOfNode(name);
            case 153 /* QualifiedName */:
                return entityNameToString(name.left) + "." + entityNameToString(name.right);
            case 194 /* PropertyAccessExpression */:
                if (ts.isIdentifier(name.name) || ts.isPrivateIdentifier(name.name)) {
                    return entityNameToString(name.expression) + "." + entityNameToString(name.name);
                }
                else {
                    return ts.Debug.assertNever(name.name);
                }
            default:
                return ts.Debug.assertNever(name);
        }
    }
    ts.entityNameToString = entityNameToString;
    function createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3) {
        var sourceFile = getSourceFileOfNode(node);
        return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNode = createDiagnosticForNode;
    function createDiagnosticForNodeArray(sourceFile, nodes, message, arg0, arg1, arg2, arg3) {
        var start = ts.skipTrivia(sourceFile.text, nodes.pos);
        return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNodeArray = createDiagnosticForNodeArray;
    function createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3) {
        var span = getErrorSpanForNode(sourceFile, node);
        return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3);
    }
    ts.createDiagnosticForNodeInSourceFile = createDiagnosticForNodeInSourceFile;
    function createDiagnosticForNodeFromMessageChain(node, messageChain, relatedInformation) {
        var sourceFile = getSourceFileOfNode(node);
        var span = getErrorSpanForNode(sourceFile, node);
        return {
            file: sourceFile,
            start: span.start,
            length: span.length,
            code: messageChain.code,
            category: messageChain.category,
            messageText: messageChain.next ? messageChain : messageChain.messageText,
            relatedInformation: relatedInformation
        };
    }
    ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain;
    function createDiagnosticForRange(sourceFile, range, message) {
        return {
            file: sourceFile,
            start: range.pos,
            length: range.end - range.pos,
            code: message.code,
            category: message.category,
            messageText: message.message,
        };
    }
    ts.createDiagnosticForRange = createDiagnosticForRange;
    function getSpanOfTokenAtPosition(sourceFile, pos) {
        var scanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos);
        scanner.scan();
        var start = scanner.getTokenPos();
        return ts.createTextSpanFromBounds(start, scanner.getTextPos());
    }
    ts.getSpanOfTokenAtPosition = getSpanOfTokenAtPosition;
    function getErrorSpanForArrowFunction(sourceFile, node) {
        var pos = ts.skipTrivia(sourceFile.text, node.pos);
        if (node.body && node.body.kind === 223 /* Block */) {
            var startLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.pos).line;
            var endLine = ts.getLineAndCharacterOfPosition(sourceFile, node.body.end).line;
            if (startLine < endLine) {
                // The arrow function spans multiple lines,
                // make the error span be the first line, inclusive.
                return ts.createTextSpan(pos, getEndLinePosition(startLine, sourceFile) - pos + 1);
            }
        }
        return ts.createTextSpanFromBounds(pos, node.end);
    }
    function getErrorSpanForNode(sourceFile, node) {
        var errorNode = node;
        switch (node.kind) {
            case 290 /* SourceFile */:
                var pos_1 = ts.skipTrivia(sourceFile.text, 0, /*stopAfterLineBreak*/ false);
                if (pos_1 === sourceFile.text.length) {
                    // file is empty - return span for the beginning of the file
                    return ts.createTextSpan(0, 0);
                }
                return getSpanOfTokenAtPosition(sourceFile, pos_1);
            // This list is a work in progress. Add missing node kinds to improve their error
            // spans.
            case 242 /* VariableDeclaration */:
            case 191 /* BindingElement */:
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
            case 246 /* InterfaceDeclaration */:
            case 249 /* ModuleDeclaration */:
            case 248 /* EnumDeclaration */:
            case 284 /* EnumMember */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 247 /* TypeAliasDeclaration */:
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
                errorNode = node.name;
                break;
            case 202 /* ArrowFunction */:
                return getErrorSpanForArrowFunction(sourceFile, node);
            case 277 /* CaseClause */:
            case 278 /* DefaultClause */:
                var start = ts.skipTrivia(sourceFile.text, node.pos);
                var end = node.statements.length > 0 ? node.statements[0].pos : node.end;
                return ts.createTextSpanFromBounds(start, end);
        }
        if (errorNode === undefined) {
            // If we don't have a better node, then just set the error on the first token of
            // construct.
            return getSpanOfTokenAtPosition(sourceFile, node.pos);
        }
        ts.Debug.assert(!ts.isJSDoc(errorNode));
        var isMissing = nodeIsMissing(errorNode);
        var pos = isMissing || ts.isJsxText(node)
            ? errorNode.pos
            : ts.skipTrivia(sourceFile.text, errorNode.pos);
        // These asserts should all be satisfied for a properly constructed `errorNode`.
        if (isMissing) {
            ts.Debug.assert(pos === errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
            ts.Debug.assert(pos === errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
        }
        else {
            ts.Debug.assert(pos >= errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
            ts.Debug.assert(pos <= errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
        }
        return ts.createTextSpanFromBounds(pos, errorNode.end);
    }
    ts.getErrorSpanForNode = getErrorSpanForNode;
    function isExternalOrCommonJsModule(file) {
        return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined;
    }
    ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule;
    function isJsonSourceFile(file) {
        return file.scriptKind === 6 /* JSON */;
    }
    ts.isJsonSourceFile = isJsonSourceFile;
    function isEnumConst(node) {
        return !!(ts.getCombinedModifierFlags(node) & 2048 /* Const */);
    }
    ts.isEnumConst = isEnumConst;
    function isDeclarationReadonly(declaration) {
        return !!(ts.getCombinedModifierFlags(declaration) & 64 /* Readonly */ && !ts.isParameterPropertyDeclaration(declaration, declaration.parent));
    }
    ts.isDeclarationReadonly = isDeclarationReadonly;
    function isVarConst(node) {
        return !!(ts.getCombinedNodeFlags(node) & 2 /* Const */);
    }
    ts.isVarConst = isVarConst;
    function isLet(node) {
        return !!(ts.getCombinedNodeFlags(node) & 1 /* Let */);
    }
    ts.isLet = isLet;
    function isSuperCall(n) {
        return n.kind === 196 /* CallExpression */ && n.expression.kind === 102 /* SuperKeyword */;
    }
    ts.isSuperCall = isSuperCall;
    function isImportCall(n) {
        return n.kind === 196 /* CallExpression */ && n.expression.kind === 96 /* ImportKeyword */;
    }
    ts.isImportCall = isImportCall;
    function isImportMeta(n) {
        return ts.isMetaProperty(n)
            && n.keywordToken === 96 /* ImportKeyword */
            && n.name.escapedText === "meta";
    }
    ts.isImportMeta = isImportMeta;
    function isLiteralImportTypeNode(n) {
        return ts.isImportTypeNode(n) && ts.isLiteralTypeNode(n.argument) && ts.isStringLiteral(n.argument.literal);
    }
    ts.isLiteralImportTypeNode = isLiteralImportTypeNode;
    function isPrologueDirective(node) {
        return node.kind === 226 /* ExpressionStatement */
            && node.expression.kind === 10 /* StringLiteral */;
    }
    ts.isPrologueDirective = isPrologueDirective;
    function isCustomPrologue(node) {
        return !!(getEmitFlags(node) & 1048576 /* CustomPrologue */);
    }
    ts.isCustomPrologue = isCustomPrologue;
    function isHoistedFunction(node) {
        return isCustomPrologue(node)
            && ts.isFunctionDeclaration(node);
    }
    ts.isHoistedFunction = isHoistedFunction;
    function isHoistedVariable(node) {
        return ts.isIdentifier(node.name)
            && !node.initializer;
    }
    function isHoistedVariableStatement(node) {
        return isCustomPrologue(node)
            && ts.isVariableStatement(node)
            && ts.every(node.declarationList.declarations, isHoistedVariable);
    }
    ts.isHoistedVariableStatement = isHoistedVariableStatement;
    function getLeadingCommentRangesOfNode(node, sourceFileOfNode) {
        return node.kind !== 11 /* JsxText */ ? ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined;
    }
    ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode;
    function getJSDocCommentRanges(node, text) {
        var commentRanges = (node.kind === 156 /* Parameter */ ||
            node.kind === 155 /* TypeParameter */ ||
            node.kind === 201 /* FunctionExpression */ ||
            node.kind === 202 /* ArrowFunction */ ||
            node.kind === 200 /* ParenthesizedExpression */) ?
            ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) :
            ts.getLeadingCommentRanges(text, node.pos);
        // True if the comment starts with '/**' but not if it is '/**/'
        return ts.filter(commentRanges, function (comment) {
            return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ &&
                text.charCodeAt(comment.pos + 3) !== 47 /* slash */;
        });
    }
    ts.getJSDocCommentRanges = getJSDocCommentRanges;
    ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*<reference\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*<reference\s+types\s*=\s*)('|")(.+?)\2.*?\/>/;
    ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*<amd-dependency\s+path\s*=\s*)('|")(.+?)\2.*?\/>/;
    var defaultLibReferenceRegEx = /^(\/\/\/\s*<reference\s+no-default-lib\s*=\s*)('|")(.+?)\2\s*\/>/;
    function isPartOfTypeNode(node) {
        if (168 /* FirstTypeNode */ <= node.kind && node.kind <= 188 /* LastTypeNode */) {
            return true;
        }
        switch (node.kind) {
            case 125 /* AnyKeyword */:
            case 148 /* UnknownKeyword */:
            case 140 /* NumberKeyword */:
            case 151 /* BigIntKeyword */:
            case 143 /* StringKeyword */:
            case 128 /* BooleanKeyword */:
            case 144 /* SymbolKeyword */:
            case 141 /* ObjectKeyword */:
            case 146 /* UndefinedKeyword */:
            case 137 /* NeverKeyword */:
                return true;
            case 110 /* VoidKeyword */:
                return node.parent.kind !== 205 /* VoidExpression */;
            case 216 /* ExpressionWithTypeArguments */:
                return !isExpressionWithTypeArgumentsInClassExtendsClause(node);
            case 155 /* TypeParameter */:
                return node.parent.kind === 186 /* MappedType */ || node.parent.kind === 181 /* InferType */;
            // Identifiers and qualified names may be type nodes, depending on their context. Climb
            // above them to find the lowest container
            case 75 /* Identifier */:
                // If the identifier is the RHS of a qualified name, then it's a type iff its parent is.
                if (node.parent.kind === 153 /* QualifiedName */ && node.parent.right === node) {
                    node = node.parent;
                }
                else if (node.parent.kind === 194 /* PropertyAccessExpression */ && node.parent.name === node) {
                    node = node.parent;
                }
                // At this point, node is either a qualified name or an identifier
                ts.Debug.assert(node.kind === 75 /* Identifier */ || node.kind === 153 /* QualifiedName */ || node.kind === 194 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'.");
            // falls through
            case 153 /* QualifiedName */:
            case 194 /* PropertyAccessExpression */:
            case 104 /* ThisKeyword */: {
                var parent = node.parent;
                if (parent.kind === 172 /* TypeQuery */) {
                    return false;
                }
                if (parent.kind === 188 /* ImportType */) {
                    return !parent.isTypeOf;
                }
                // Do not recursively call isPartOfTypeNode on the parent. In the example:
                //
                //     let a: A.B.C;
                //
                // Calling isPartOfTypeNode would consider the qualified name A.B a type node.
                // Only C and A.B.C are type nodes.
                if (168 /* FirstTypeNode */ <= parent.kind && parent.kind <= 188 /* LastTypeNode */) {
                    return true;
                }
                switch (parent.kind) {
                    case 216 /* ExpressionWithTypeArguments */:
                        return !isExpressionWithTypeArgumentsInClassExtendsClause(parent);
                    case 155 /* TypeParameter */:
                        return node === parent.constraint;
                    case 321 /* JSDocTemplateTag */:
                        return node === parent.constraint;
                    case 159 /* PropertyDeclaration */:
                    case 158 /* PropertySignature */:
                    case 156 /* Parameter */:
                    case 242 /* VariableDeclaration */:
                        return node === parent.type;
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                    case 162 /* Constructor */:
                    case 161 /* MethodDeclaration */:
                    case 160 /* MethodSignature */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        return node === parent.type;
                    case 165 /* CallSignature */:
                    case 166 /* ConstructSignature */:
                    case 167 /* IndexSignature */:
                        return node === parent.type;
                    case 199 /* TypeAssertionExpression */:
                        return node === parent.type;
                    case 196 /* CallExpression */:
                    case 197 /* NewExpression */:
                        return ts.contains(parent.typeArguments, node);
                    case 198 /* TaggedTemplateExpression */:
                        // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
                        return false;
                }
            }
        }
        return false;
    }
    ts.isPartOfTypeNode = isPartOfTypeNode;
    function isChildOfNodeWithKind(node, kind) {
        while (node) {
            if (node.kind === kind) {
                return true;
            }
            node = node.parent;
        }
        return false;
    }
    ts.isChildOfNodeWithKind = isChildOfNodeWithKind;
    // Warning: This has the same semantics as the forEach family of functions,
    //          in that traversal terminates in the event that 'visitor' supplies a truthy value.
    function forEachReturnStatement(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 235 /* ReturnStatement */:
                    return visitor(node);
                case 251 /* CaseBlock */:
                case 223 /* Block */:
                case 227 /* IfStatement */:
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                case 236 /* WithStatement */:
                case 237 /* SwitchStatement */:
                case 277 /* CaseClause */:
                case 278 /* DefaultClause */:
                case 238 /* LabeledStatement */:
                case 240 /* TryStatement */:
                case 280 /* CatchClause */:
                    return ts.forEachChild(node, traverse);
            }
        }
    }
    ts.forEachReturnStatement = forEachReturnStatement;
    function forEachYieldExpression(body, visitor) {
        return traverse(body);
        function traverse(node) {
            switch (node.kind) {
                case 212 /* YieldExpression */:
                    visitor(node);
                    var operand = node.expression;
                    if (operand) {
                        traverse(operand);
                    }
                    return;
                case 248 /* EnumDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                    // These are not allowed inside a generator now, but eventually they may be allowed
                    // as local types. Regardless, skip them to avoid the work.
                    return;
                default:
                    if (ts.isFunctionLike(node)) {
                        if (node.name && node.name.kind === 154 /* ComputedPropertyName */) {
                            // Note that we will not include methods/accessors of a class because they would require
                            // first descending into the class. This is by design.
                            traverse(node.name.expression);
                            return;
                        }
                    }
                    else if (!isPartOfTypeNode(node)) {
                        // This is the general case, which should include mostly expressions and statements.
                        // Also includes NodeArrays.
                        ts.forEachChild(node, traverse);
                    }
            }
        }
    }
    ts.forEachYieldExpression = forEachYieldExpression;
    /**
     * Gets the most likely element type for a TypeNode. This is not an exhaustive test
     * as it assumes a rest argument can only be an array type (either T[], or Array<T>).
     *
     * @param node The type node.
     */
    function getRestParameterElementType(node) {
        if (node && node.kind === 174 /* ArrayType */) {
            return node.elementType;
        }
        else if (node && node.kind === 169 /* TypeReference */) {
            return ts.singleOrUndefined(node.typeArguments);
        }
        else {
            return undefined;
        }
    }
    ts.getRestParameterElementType = getRestParameterElementType;
    function getMembersOfDeclaration(node) {
        switch (node.kind) {
            case 246 /* InterfaceDeclaration */:
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
            case 173 /* TypeLiteral */:
                return node.members;
            case 193 /* ObjectLiteralExpression */:
                return node.properties;
        }
    }
    ts.getMembersOfDeclaration = getMembersOfDeclaration;
    function isVariableLike(node) {
        if (node) {
            switch (node.kind) {
                case 191 /* BindingElement */:
                case 284 /* EnumMember */:
                case 156 /* Parameter */:
                case 281 /* PropertyAssignment */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 282 /* ShorthandPropertyAssignment */:
                case 242 /* VariableDeclaration */:
                    return true;
            }
        }
        return false;
    }
    ts.isVariableLike = isVariableLike;
    function isVariableLikeOrAccessor(node) {
        return isVariableLike(node) || ts.isAccessor(node);
    }
    ts.isVariableLikeOrAccessor = isVariableLikeOrAccessor;
    function isVariableDeclarationInVariableStatement(node) {
        return node.parent.kind === 243 /* VariableDeclarationList */
            && node.parent.parent.kind === 225 /* VariableStatement */;
    }
    ts.isVariableDeclarationInVariableStatement = isVariableDeclarationInVariableStatement;
    function isValidESSymbolDeclaration(node) {
        return ts.isVariableDeclaration(node) ? isVarConst(node) && ts.isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) :
            ts.isPropertyDeclaration(node) ? hasReadonlyModifier(node) && hasStaticModifier(node) :
                ts.isPropertySignature(node) && hasReadonlyModifier(node);
    }
    ts.isValidESSymbolDeclaration = isValidESSymbolDeclaration;
    function introducesArgumentsExoticObject(node) {
        switch (node.kind) {
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
                return true;
        }
        return false;
    }
    ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject;
    function unwrapInnermostStatementOfLabel(node, beforeUnwrapLabelCallback) {
        while (true) {
            if (beforeUnwrapLabelCallback) {
                beforeUnwrapLabelCallback(node);
            }
            if (node.statement.kind !== 238 /* LabeledStatement */) {
                return node.statement;
            }
            node = node.statement;
        }
    }
    ts.unwrapInnermostStatementOfLabel = unwrapInnermostStatementOfLabel;
    function isFunctionBlock(node) {
        return node && node.kind === 223 /* Block */ && ts.isFunctionLike(node.parent);
    }
    ts.isFunctionBlock = isFunctionBlock;
    function isObjectLiteralMethod(node) {
        return node && node.kind === 161 /* MethodDeclaration */ && node.parent.kind === 193 /* ObjectLiteralExpression */;
    }
    ts.isObjectLiteralMethod = isObjectLiteralMethod;
    function isObjectLiteralOrClassExpressionMethod(node) {
        return node.kind === 161 /* MethodDeclaration */ &&
            (node.parent.kind === 193 /* ObjectLiteralExpression */ ||
                node.parent.kind === 214 /* ClassExpression */);
    }
    ts.isObjectLiteralOrClassExpressionMethod = isObjectLiteralOrClassExpressionMethod;
    function isIdentifierTypePredicate(predicate) {
        return predicate && predicate.kind === 1 /* Identifier */;
    }
    ts.isIdentifierTypePredicate = isIdentifierTypePredicate;
    function isThisTypePredicate(predicate) {
        return predicate && predicate.kind === 0 /* This */;
    }
    ts.isThisTypePredicate = isThisTypePredicate;
    function getPropertyAssignment(objectLiteral, key, key2) {
        return objectLiteral.properties.filter(function (property) {
            if (property.kind === 281 /* PropertyAssignment */) {
                var propName = getTextOfPropertyName(property.name);
                return key === propName || (!!key2 && key2 === propName);
            }
            return false;
        });
    }
    ts.getPropertyAssignment = getPropertyAssignment;
    function getTsConfigObjectLiteralExpression(tsConfigSourceFile) {
        if (tsConfigSourceFile && tsConfigSourceFile.statements.length) {
            var expression = tsConfigSourceFile.statements[0].expression;
            return ts.tryCast(expression, ts.isObjectLiteralExpression);
        }
    }
    ts.getTsConfigObjectLiteralExpression = getTsConfigObjectLiteralExpression;
    function getTsConfigPropArrayElementValue(tsConfigSourceFile, propKey, elementValue) {
        return ts.firstDefined(getTsConfigPropArray(tsConfigSourceFile, propKey), function (property) {
            return ts.isArrayLiteralExpression(property.initializer) ?
                ts.find(property.initializer.elements, function (element) { return ts.isStringLiteral(element) && element.text === elementValue; }) :
                undefined;
        });
    }
    ts.getTsConfigPropArrayElementValue = getTsConfigPropArrayElementValue;
    function getTsConfigPropArray(tsConfigSourceFile, propKey) {
        var jsonObjectLiteral = getTsConfigObjectLiteralExpression(tsConfigSourceFile);
        return jsonObjectLiteral ? getPropertyAssignment(jsonObjectLiteral, propKey) : ts.emptyArray;
    }
    ts.getTsConfigPropArray = getTsConfigPropArray;
    function getContainingFunction(node) {
        return findAncestor(node.parent, ts.isFunctionLike);
    }
    ts.getContainingFunction = getContainingFunction;
    function getContainingFunctionDeclaration(node) {
        return findAncestor(node.parent, ts.isFunctionLikeDeclaration);
    }
    ts.getContainingFunctionDeclaration = getContainingFunctionDeclaration;
    function getContainingClass(node) {
        return findAncestor(node.parent, ts.isClassLike);
    }
    ts.getContainingClass = getContainingClass;
    function getThisContainer(node, includeArrowFunctions) {
        ts.Debug.assert(node.kind !== 290 /* SourceFile */);
        while (true) {
            node = node.parent;
            if (!node) {
                return ts.Debug.fail(); // If we never pass in a SourceFile, this should be unreachable, since we'll stop when we reach that.
            }
            switch (node.kind) {
                case 154 /* ComputedPropertyName */:
                    // If the grandparent node is an object literal (as opposed to a class),
                    // then the computed property is not a 'this' container.
                    // A computed property name in a class needs to be a this container
                    // so that we can error on it.
                    if (ts.isClassLike(node.parent.parent)) {
                        return node;
                    }
                    // If this is a computed property, then the parent should not
                    // make it a this container. The parent might be a property
                    // in an object literal, like a method or accessor. But in order for
                    // such a parent to be a this container, the reference must be in
                    // the *body* of the container.
                    node = node.parent;
                    break;
                case 157 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 156 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
                        // If the decorator's parent is a Parameter, we resolve the this container from
                        // the grandparent class declaration.
                        node = node.parent.parent;
                    }
                    else if (ts.isClassElement(node.parent)) {
                        // If the decorator's parent is a class element, we resolve the 'this' container
                        // from the parent class declaration.
                        node = node.parent;
                    }
                    break;
                case 202 /* ArrowFunction */:
                    if (!includeArrowFunctions) {
                        continue;
                    }
                // falls through
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 249 /* ModuleDeclaration */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 162 /* Constructor */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 167 /* IndexSignature */:
                case 248 /* EnumDeclaration */:
                case 290 /* SourceFile */:
                    return node;
            }
        }
    }
    ts.getThisContainer = getThisContainer;
    function getNewTargetContainer(node) {
        var container = getThisContainer(node, /*includeArrowFunctions*/ false);
        if (container) {
            switch (container.kind) {
                case 162 /* Constructor */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                    return container;
            }
        }
        return undefined;
    }
    ts.getNewTargetContainer = getNewTargetContainer;
    /**
     * Given an super call/property node, returns the closest node where
     * - a super call/property access is legal in the node and not legal in the parent node the node.
     *   i.e. super call is legal in constructor but not legal in the class body.
     * - the container is an arrow function (so caller might need to call getSuperContainer again in case it needs to climb higher)
     * - a super call/property is definitely illegal in the container (but might be legal in some subnode)
     *   i.e. super property access is illegal in function declaration but can be legal in the statement list
     */
    function getSuperContainer(node, stopOnFunctions) {
        while (true) {
            node = node.parent;
            if (!node) {
                return node;
            }
            switch (node.kind) {
                case 154 /* ComputedPropertyName */:
                    node = node.parent;
                    break;
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    if (!stopOnFunctions) {
                        continue;
                    }
                // falls through
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 162 /* Constructor */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return node;
                case 157 /* Decorator */:
                    // Decorators are always applied outside of the body of a class or method.
                    if (node.parent.kind === 156 /* Parameter */ && ts.isClassElement(node.parent.parent)) {
                        // If the decorator's parent is a Parameter, we resolve the this container from
                        // the grandparent class declaration.
                        node = node.parent.parent;
                    }
                    else if (ts.isClassElement(node.parent)) {
                        // If the decorator's parent is a class element, we resolve the 'this' container
                        // from the parent class declaration.
                        node = node.parent;
                    }
                    break;
            }
        }
    }
    ts.getSuperContainer = getSuperContainer;
    function getImmediatelyInvokedFunctionExpression(func) {
        if (func.kind === 201 /* FunctionExpression */ || func.kind === 202 /* ArrowFunction */) {
            var prev = func;
            var parent = func.parent;
            while (parent.kind === 200 /* ParenthesizedExpression */) {
                prev = parent;
                parent = parent.parent;
            }
            if (parent.kind === 196 /* CallExpression */ && parent.expression === prev) {
                return parent;
            }
        }
    }
    ts.getImmediatelyInvokedFunctionExpression = getImmediatelyInvokedFunctionExpression;
    function isSuperOrSuperProperty(node) {
        return node.kind === 102 /* SuperKeyword */
            || isSuperProperty(node);
    }
    ts.isSuperOrSuperProperty = isSuperOrSuperProperty;
    /**
     * Determines whether a node is a property or element access expression for `super`.
     */
    function isSuperProperty(node) {
        var kind = node.kind;
        return (kind === 194 /* PropertyAccessExpression */ || kind === 195 /* ElementAccessExpression */)
            && node.expression.kind === 102 /* SuperKeyword */;
    }
    ts.isSuperProperty = isSuperProperty;
    /**
     * Determines whether a node is a property or element access expression for `this`.
     */
    function isThisProperty(node) {
        var kind = node.kind;
        return (kind === 194 /* PropertyAccessExpression */ || kind === 195 /* ElementAccessExpression */)
            && node.expression.kind === 104 /* ThisKeyword */;
    }
    ts.isThisProperty = isThisProperty;
    function getEntityNameFromTypeNode(node) {
        switch (node.kind) {
            case 169 /* TypeReference */:
                return node.typeName;
            case 216 /* ExpressionWithTypeArguments */:
                return isEntityNameExpression(node.expression)
                    ? node.expression
                    : undefined;
            case 75 /* Identifier */:
            case 153 /* QualifiedName */:
                return node;
        }
        return undefined;
    }
    ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode;
    function getInvokedExpression(node) {
        switch (node.kind) {
            case 198 /* TaggedTemplateExpression */:
                return node.tag;
            case 268 /* JsxOpeningElement */:
            case 267 /* JsxSelfClosingElement */:
                return node.tagName;
            default:
                return node.expression;
        }
    }
    ts.getInvokedExpression = getInvokedExpression;
    function nodeCanBeDecorated(node, parent, grandparent) {
        // private names cannot be used with decorators yet
        if (ts.isNamedDeclaration(node) && ts.isPrivateIdentifier(node.name)) {
            return false;
        }
        switch (node.kind) {
            case 245 /* ClassDeclaration */:
                // classes are valid targets
                return true;
            case 159 /* PropertyDeclaration */:
                // property declarations are valid if their parent is a class declaration.
                return parent.kind === 245 /* ClassDeclaration */;
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 161 /* MethodDeclaration */:
                // if this method has a body and its parent is a class declaration, this is a valid target.
                return node.body !== undefined
                    && parent.kind === 245 /* ClassDeclaration */;
            case 156 /* Parameter */:
                // if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target;
                return parent.body !== undefined
                    && (parent.kind === 162 /* Constructor */
                        || parent.kind === 161 /* MethodDeclaration */
                        || parent.kind === 164 /* SetAccessor */)
                    && grandparent.kind === 245 /* ClassDeclaration */;
        }
        return false;
    }
    ts.nodeCanBeDecorated = nodeCanBeDecorated;
    function nodeIsDecorated(node, parent, grandparent) {
        return node.decorators !== undefined
            && nodeCanBeDecorated(node, parent, grandparent); // TODO: GH#18217
    }
    ts.nodeIsDecorated = nodeIsDecorated;
    function nodeOrChildIsDecorated(node, parent, grandparent) {
        return nodeIsDecorated(node, parent, grandparent) || childIsDecorated(node, parent); // TODO: GH#18217
    }
    ts.nodeOrChildIsDecorated = nodeOrChildIsDecorated;
    function childIsDecorated(node, parent) {
        switch (node.kind) {
            case 245 /* ClassDeclaration */:
                return ts.some(node.members, function (m) { return nodeOrChildIsDecorated(m, node, parent); }); // TODO: GH#18217
            case 161 /* MethodDeclaration */:
            case 164 /* SetAccessor */:
                return ts.some(node.parameters, function (p) { return nodeIsDecorated(p, node, parent); }); // TODO: GH#18217
            default:
                return false;
        }
    }
    ts.childIsDecorated = childIsDecorated;
    function isJSXTagName(node) {
        var parent = node.parent;
        if (parent.kind === 268 /* JsxOpeningElement */ ||
            parent.kind === 267 /* JsxSelfClosingElement */ ||
            parent.kind === 269 /* JsxClosingElement */) {
            return parent.tagName === node;
        }
        return false;
    }
    ts.isJSXTagName = isJSXTagName;
    function isExpressionNode(node) {
        switch (node.kind) {
            case 102 /* SuperKeyword */:
            case 100 /* NullKeyword */:
            case 106 /* TrueKeyword */:
            case 91 /* FalseKeyword */:
            case 13 /* RegularExpressionLiteral */:
            case 192 /* ArrayLiteralExpression */:
            case 193 /* ObjectLiteralExpression */:
            case 194 /* PropertyAccessExpression */:
            case 195 /* ElementAccessExpression */:
            case 196 /* CallExpression */:
            case 197 /* NewExpression */:
            case 198 /* TaggedTemplateExpression */:
            case 217 /* AsExpression */:
            case 199 /* TypeAssertionExpression */:
            case 218 /* NonNullExpression */:
            case 200 /* ParenthesizedExpression */:
            case 201 /* FunctionExpression */:
            case 214 /* ClassExpression */:
            case 202 /* ArrowFunction */:
            case 205 /* VoidExpression */:
            case 203 /* DeleteExpression */:
            case 204 /* TypeOfExpression */:
            case 207 /* PrefixUnaryExpression */:
            case 208 /* PostfixUnaryExpression */:
            case 209 /* BinaryExpression */:
            case 210 /* ConditionalExpression */:
            case 213 /* SpreadElement */:
            case 211 /* TemplateExpression */:
            case 215 /* OmittedExpression */:
            case 266 /* JsxElement */:
            case 267 /* JsxSelfClosingElement */:
            case 270 /* JsxFragment */:
            case 212 /* YieldExpression */:
            case 206 /* AwaitExpression */:
            case 219 /* MetaProperty */:
                return true;
            case 153 /* QualifiedName */:
                while (node.parent.kind === 153 /* QualifiedName */) {
                    node = node.parent;
                }
                return node.parent.kind === 172 /* TypeQuery */ || isJSXTagName(node);
            case 75 /* Identifier */:
                if (node.parent.kind === 172 /* TypeQuery */ || isJSXTagName(node)) {
                    return true;
                }
            // falls through
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 104 /* ThisKeyword */:
                return isInExpressionContext(node);
            default:
                return false;
        }
    }
    ts.isExpressionNode = isExpressionNode;
    function isInExpressionContext(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 242 /* VariableDeclaration */:
            case 156 /* Parameter */:
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 284 /* EnumMember */:
            case 281 /* PropertyAssignment */:
            case 191 /* BindingElement */:
                return parent.initializer === node;
            case 226 /* ExpressionStatement */:
            case 227 /* IfStatement */:
            case 228 /* DoStatement */:
            case 229 /* WhileStatement */:
            case 235 /* ReturnStatement */:
            case 236 /* WithStatement */:
            case 237 /* SwitchStatement */:
            case 277 /* CaseClause */:
            case 239 /* ThrowStatement */:
                return parent.expression === node;
            case 230 /* ForStatement */:
                var forStatement = parent;
                return (forStatement.initializer === node && forStatement.initializer.kind !== 243 /* VariableDeclarationList */) ||
                    forStatement.condition === node ||
                    forStatement.incrementor === node;
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
                var forInStatement = parent;
                return (forInStatement.initializer === node && forInStatement.initializer.kind !== 243 /* VariableDeclarationList */) ||
                    forInStatement.expression === node;
            case 199 /* TypeAssertionExpression */:
            case 217 /* AsExpression */:
                return node === parent.expression;
            case 221 /* TemplateSpan */:
                return node === parent.expression;
            case 154 /* ComputedPropertyName */:
                return node === parent.expression;
            case 157 /* Decorator */:
            case 276 /* JsxExpression */:
            case 275 /* JsxSpreadAttribute */:
            case 283 /* SpreadAssignment */:
                return true;
            case 216 /* ExpressionWithTypeArguments */:
                return parent.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
            case 282 /* ShorthandPropertyAssignment */:
                return parent.objectAssignmentInitializer === node;
            default:
                return isExpressionNode(parent);
        }
    }
    ts.isInExpressionContext = isInExpressionContext;
    function isPartOfTypeQuery(node) {
        while (node.kind === 153 /* QualifiedName */ || node.kind === 75 /* Identifier */) {
            node = node.parent;
        }
        return node.kind === 172 /* TypeQuery */;
    }
    ts.isPartOfTypeQuery = isPartOfTypeQuery;
    function isExternalModuleImportEqualsDeclaration(node) {
        return node.kind === 253 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 265 /* ExternalModuleReference */;
    }
    ts.isExternalModuleImportEqualsDeclaration = isExternalModuleImportEqualsDeclaration;
    function getExternalModuleImportEqualsDeclarationExpression(node) {
        ts.Debug.assert(isExternalModuleImportEqualsDeclaration(node));
        return node.moduleReference.expression;
    }
    ts.getExternalModuleImportEqualsDeclarationExpression = getExternalModuleImportEqualsDeclarationExpression;
    function isInternalModuleImportEqualsDeclaration(node) {
        return node.kind === 253 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 265 /* ExternalModuleReference */;
    }
    ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration;
    function isSourceFileJS(file) {
        return isInJSFile(file);
    }
    ts.isSourceFileJS = isSourceFileJS;
    function isSourceFileNotJS(file) {
        return !isInJSFile(file);
    }
    ts.isSourceFileNotJS = isSourceFileNotJS;
    function isInJSFile(node) {
        return !!node && !!(node.flags & 131072 /* JavaScriptFile */);
    }
    ts.isInJSFile = isInJSFile;
    function isInJsonFile(node) {
        return !!node && !!(node.flags & 33554432 /* JsonFile */);
    }
    ts.isInJsonFile = isInJsonFile;
    function isSourceFileNotJson(file) {
        return !isJsonSourceFile(file);
    }
    ts.isSourceFileNotJson = isSourceFileNotJson;
    function isInJSDoc(node) {
        return !!node && !!(node.flags & 4194304 /* JSDoc */);
    }
    ts.isInJSDoc = isInJSDoc;
    function isJSDocIndexSignature(node) {
        return ts.isTypeReferenceNode(node) &&
            ts.isIdentifier(node.typeName) &&
            node.typeName.escapedText === "Object" &&
            node.typeArguments && node.typeArguments.length === 2 &&
            (node.typeArguments[0].kind === 143 /* StringKeyword */ || node.typeArguments[0].kind === 140 /* NumberKeyword */);
    }
    ts.isJSDocIndexSignature = isJSDocIndexSignature;
    function isRequireCall(callExpression, requireStringLiteralLikeArgument) {
        if (callExpression.kind !== 196 /* CallExpression */) {
            return false;
        }
        var _a = callExpression, expression = _a.expression, args = _a.arguments;
        if (expression.kind !== 75 /* Identifier */ || expression.escapedText !== "require") {
            return false;
        }
        if (args.length !== 1) {
            return false;
        }
        var arg = args[0];
        return !requireStringLiteralLikeArgument || ts.isStringLiteralLike(arg);
    }
    ts.isRequireCall = isRequireCall;
    function isRequireVariableDeclaration(node, requireStringLiteralLikeArgument) {
        return ts.isVariableDeclaration(node) && !!node.initializer && isRequireCall(node.initializer, requireStringLiteralLikeArgument);
    }
    ts.isRequireVariableDeclaration = isRequireVariableDeclaration;
    function isRequireVariableDeclarationStatement(node, requireStringLiteralLikeArgument) {
        if (requireStringLiteralLikeArgument === void 0) { requireStringLiteralLikeArgument = true; }
        return ts.isVariableStatement(node) && ts.every(node.declarationList.declarations, function (decl) { return isRequireVariableDeclaration(decl, requireStringLiteralLikeArgument); });
    }
    ts.isRequireVariableDeclarationStatement = isRequireVariableDeclarationStatement;
    function isSingleOrDoubleQuote(charCode) {
        return charCode === 39 /* singleQuote */ || charCode === 34 /* doubleQuote */;
    }
    ts.isSingleOrDoubleQuote = isSingleOrDoubleQuote;
    function isStringDoubleQuoted(str, sourceFile) {
        return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === 34 /* doubleQuote */;
    }
    ts.isStringDoubleQuoted = isStringDoubleQuoted;
    function getDeclarationOfExpando(node) {
        if (!node.parent) {
            return undefined;
        }
        var name;
        var decl;
        if (ts.isVariableDeclaration(node.parent) && node.parent.initializer === node) {
            if (!isInJSFile(node) && !isVarConst(node.parent)) {
                return undefined;
            }
            name = node.parent.name;
            decl = node.parent;
        }
        else if (ts.isBinaryExpression(node.parent)) {
            var parentNode = node.parent;
            var parentNodeOperator = node.parent.operatorToken.kind;
            if (parentNodeOperator === 62 /* EqualsToken */ && parentNode.right === node) {
                name = parentNode.left;
                decl = name;
            }
            else if (parentNodeOperator === 56 /* BarBarToken */ || parentNodeOperator === 60 /* QuestionQuestionToken */) {
                if (ts.isVariableDeclaration(parentNode.parent) && parentNode.parent.initializer === parentNode) {
                    name = parentNode.parent.name;
                    decl = parentNode.parent;
                }
                else if (ts.isBinaryExpression(parentNode.parent) && parentNode.parent.operatorToken.kind === 62 /* EqualsToken */ && parentNode.parent.right === parentNode) {
                    name = parentNode.parent.left;
                    decl = name;
                }
                if (!name || !isBindableStaticNameExpression(name) || !isSameEntityName(name, parentNode.left)) {
                    return undefined;
                }
            }
        }
        if (!name || !getExpandoInitializer(node, isPrototypeAccess(name))) {
            return undefined;
        }
        return decl;
    }
    ts.getDeclarationOfExpando = getDeclarationOfExpando;
    function isAssignmentDeclaration(decl) {
        return ts.isBinaryExpression(decl) || isAccessExpression(decl) || ts.isIdentifier(decl) || ts.isCallExpression(decl);
    }
    ts.isAssignmentDeclaration = isAssignmentDeclaration;
    /** Get the initializer, taking into account defaulted Javascript initializers */
    function getEffectiveInitializer(node) {
        if (isInJSFile(node) && node.initializer &&
            ts.isBinaryExpression(node.initializer) &&
            (node.initializer.operatorToken.kind === 56 /* BarBarToken */ || node.initializer.operatorToken.kind === 60 /* QuestionQuestionToken */) &&
            node.name && isEntityNameExpression(node.name) && isSameEntityName(node.name, node.initializer.left)) {
            return node.initializer.right;
        }
        return node.initializer;
    }
    ts.getEffectiveInitializer = getEffectiveInitializer;
    /** Get the declaration initializer when it is container-like (See getExpandoInitializer). */
    function getDeclaredExpandoInitializer(node) {
        var init = getEffectiveInitializer(node);
        return init && getExpandoInitializer(init, isPrototypeAccess(node.name));
    }
    ts.getDeclaredExpandoInitializer = getDeclaredExpandoInitializer;
    function hasExpandoValueProperty(node, isPrototypeAssignment) {
        return ts.forEach(node.properties, function (p) {
            return ts.isPropertyAssignment(p) &&
                ts.isIdentifier(p.name) &&
                p.name.escapedText === "value" &&
                p.initializer &&
                getExpandoInitializer(p.initializer, isPrototypeAssignment);
        });
    }
    /**
     * Get the assignment 'initializer' -- the righthand side-- when the initializer is container-like (See getExpandoInitializer).
     * We treat the right hand side of assignments with container-like initalizers as declarations.
     */
    function getAssignedExpandoInitializer(node) {
        if (node && node.parent && ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 62 /* EqualsToken */) {
            var isPrototypeAssignment = isPrototypeAccess(node.parent.left);
            return getExpandoInitializer(node.parent.right, isPrototypeAssignment) ||
                getDefaultedExpandoInitializer(node.parent.left, node.parent.right, isPrototypeAssignment);
        }
        if (node && ts.isCallExpression(node) && isBindableObjectDefinePropertyCall(node)) {
            var result = hasExpandoValueProperty(node.arguments[2], node.arguments[1].text === "prototype");
            if (result) {
                return result;
            }
        }
    }
    ts.getAssignedExpandoInitializer = getAssignedExpandoInitializer;
    /**
     * Recognized expando initializers are:
     * 1. (function() {})() -- IIFEs
     * 2. function() { } -- Function expressions
     * 3. class { } -- Class expressions
     * 4. {} -- Empty object literals
     * 5. { ... } -- Non-empty object literals, when used to initialize a prototype, like `C.prototype = { m() { } }`
     *
     * This function returns the provided initializer, or undefined if it is not valid.
     */
    function getExpandoInitializer(initializer, isPrototypeAssignment) {
        if (ts.isCallExpression(initializer)) {
            var e = skipParentheses(initializer.expression);
            return e.kind === 201 /* FunctionExpression */ || e.kind === 202 /* ArrowFunction */ ? initializer : undefined;
        }
        if (initializer.kind === 201 /* FunctionExpression */ ||
            initializer.kind === 214 /* ClassExpression */ ||
            initializer.kind === 202 /* ArrowFunction */) {
            return initializer;
        }
        if (ts.isObjectLiteralExpression(initializer) && (initializer.properties.length === 0 || isPrototypeAssignment)) {
            return initializer;
        }
    }
    ts.getExpandoInitializer = getExpandoInitializer;
    /**
     * A defaulted expando initializer matches the pattern
     * `Lhs = Lhs || ExpandoInitializer`
     * or `var Lhs = Lhs || ExpandoInitializer`
     *
     * The second Lhs is required to be the same as the first except that it may be prefixed with
     * 'window.', 'global.' or 'self.' The second Lhs is otherwise ignored by the binder and checker.
     */
    function getDefaultedExpandoInitializer(name, initializer, isPrototypeAssignment) {
        var e = ts.isBinaryExpression(initializer)
            && (initializer.operatorToken.kind === 56 /* BarBarToken */ || initializer.operatorToken.kind === 60 /* QuestionQuestionToken */)
            && getExpandoInitializer(initializer.right, isPrototypeAssignment);
        if (e && isSameEntityName(name, initializer.left)) {
            return e;
        }
    }
    function isDefaultedExpandoInitializer(node) {
        var name = ts.isVariableDeclaration(node.parent) ? node.parent.name :
            ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === 62 /* EqualsToken */ ? node.parent.left :
                undefined;
        return name && getExpandoInitializer(node.right, isPrototypeAccess(name)) && isEntityNameExpression(name) && isSameEntityName(name, node.left);
    }
    ts.isDefaultedExpandoInitializer = isDefaultedExpandoInitializer;
    /** Given an expando initializer, return its declaration name, or the left-hand side of the assignment if it's part of an assignment declaration. */
    function getNameOfExpando(node) {
        if (ts.isBinaryExpression(node.parent)) {
            var parent = ((node.parent.operatorToken.kind === 56 /* BarBarToken */ || node.parent.operatorToken.kind === 60 /* QuestionQuestionToken */) && ts.isBinaryExpression(node.parent.parent)) ? node.parent.parent : node.parent;
            if (parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isIdentifier(parent.left)) {
                return parent.left;
            }
        }
        else if (ts.isVariableDeclaration(node.parent)) {
            return node.parent.name;
        }
    }
    ts.getNameOfExpando = getNameOfExpando;
    /**
     * Is the 'declared' name the same as the one in the initializer?
     * @return true for identical entity names, as well as ones where the initializer is prefixed with
     * 'window', 'self' or 'global'. For example:
     *
     * var my = my || {}
     * var min = window.min || {}
     * my.app = self.my.app || class { }
     */
    function isSameEntityName(name, initializer) {
        if (isPropertyNameLiteral(name) && isPropertyNameLiteral(initializer)) {
            return getTextOfIdentifierOrLiteral(name) === getTextOfIdentifierOrLiteral(name);
        }
        if (ts.isIdentifier(name) && isLiteralLikeAccess(initializer) &&
            (initializer.expression.kind === 104 /* ThisKeyword */ ||
                ts.isIdentifier(initializer.expression) &&
                    (initializer.expression.escapedText === "window" ||
                        initializer.expression.escapedText === "self" ||
                        initializer.expression.escapedText === "global"))) {
            var nameOrArgument = getNameOrArgument(initializer);
            if (ts.isPrivateIdentifier(nameOrArgument)) {
                ts.Debug.fail("Unexpected PrivateIdentifier in name expression with literal-like access.");
            }
            return isSameEntityName(name, nameOrArgument);
        }
        if (isLiteralLikeAccess(name) && isLiteralLikeAccess(initializer)) {
            return getElementOrPropertyAccessName(name) === getElementOrPropertyAccessName(initializer)
                && isSameEntityName(name.expression, initializer.expression);
        }
        return false;
    }
    function getRightMostAssignedExpression(node) {
        while (isAssignmentExpression(node, /*excludeCompoundAssignments*/ true)) {
            node = node.right;
        }
        return node;
    }
    ts.getRightMostAssignedExpression = getRightMostAssignedExpression;
    function isExportsIdentifier(node) {
        return ts.isIdentifier(node) && node.escapedText === "exports";
    }
    ts.isExportsIdentifier = isExportsIdentifier;
    function isModuleIdentifier(node) {
        return ts.isIdentifier(node) && node.escapedText === "module";
    }
    ts.isModuleIdentifier = isModuleIdentifier;
    function isModuleExportsAccessExpression(node) {
        return (ts.isPropertyAccessExpression(node) || isLiteralLikeElementAccess(node))
            && isModuleIdentifier(node.expression)
            && getElementOrPropertyAccessName(node) === "exports";
    }
    ts.isModuleExportsAccessExpression = isModuleExportsAccessExpression;
    /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
    /// assignments we treat as special in the binder
    function getAssignmentDeclarationKind(expr) {
        var special = getAssignmentDeclarationKindWorker(expr);
        return special === 5 /* Property */ || isInJSFile(expr) ? special : 0 /* None */;
    }
    ts.getAssignmentDeclarationKind = getAssignmentDeclarationKind;
    function isBindableObjectDefinePropertyCall(expr) {
        return ts.length(expr.arguments) === 3 &&
            ts.isPropertyAccessExpression(expr.expression) &&
            ts.isIdentifier(expr.expression.expression) &&
            ts.idText(expr.expression.expression) === "Object" &&
            ts.idText(expr.expression.name) === "defineProperty" &&
            isStringOrNumericLiteralLike(expr.arguments[1]) &&
            isBindableStaticNameExpression(expr.arguments[0], /*excludeThisKeyword*/ true);
    }
    ts.isBindableObjectDefinePropertyCall = isBindableObjectDefinePropertyCall;
    /** x.y OR x[0] */
    function isLiteralLikeAccess(node) {
        return ts.isPropertyAccessExpression(node) || isLiteralLikeElementAccess(node);
    }
    ts.isLiteralLikeAccess = isLiteralLikeAccess;
    /** x[0] OR x['a'] OR x[Symbol.y] */
    function isLiteralLikeElementAccess(node) {
        return ts.isElementAccessExpression(node) && (isStringOrNumericLiteralLike(node.argumentExpression) ||
            isWellKnownSymbolSyntactically(node.argumentExpression));
    }
    ts.isLiteralLikeElementAccess = isLiteralLikeElementAccess;
    /** Any series of property and element accesses. */
    function isBindableStaticAccessExpression(node, excludeThisKeyword) {
        return ts.isPropertyAccessExpression(node) && (!excludeThisKeyword && node.expression.kind === 104 /* ThisKeyword */ || ts.isIdentifier(node.name) && isBindableStaticNameExpression(node.expression, /*excludeThisKeyword*/ true))
            || isBindableStaticElementAccessExpression(node, excludeThisKeyword);
    }
    ts.isBindableStaticAccessExpression = isBindableStaticAccessExpression;
    /** Any series of property and element accesses, ending in a literal element access */
    function isBindableStaticElementAccessExpression(node, excludeThisKeyword) {
        return isLiteralLikeElementAccess(node)
            && ((!excludeThisKeyword && node.expression.kind === 104 /* ThisKeyword */) ||
                isEntityNameExpression(node.expression) ||
                isBindableStaticAccessExpression(node.expression, /*excludeThisKeyword*/ true));
    }
    ts.isBindableStaticElementAccessExpression = isBindableStaticElementAccessExpression;
    function isBindableStaticNameExpression(node, excludeThisKeyword) {
        return isEntityNameExpression(node) || isBindableStaticAccessExpression(node, excludeThisKeyword);
    }
    ts.isBindableStaticNameExpression = isBindableStaticNameExpression;
    function getNameOrArgument(expr) {
        if (ts.isPropertyAccessExpression(expr)) {
            return expr.name;
        }
        return expr.argumentExpression;
    }
    ts.getNameOrArgument = getNameOrArgument;
    function getAssignmentDeclarationKindWorker(expr) {
        if (ts.isCallExpression(expr)) {
            if (!isBindableObjectDefinePropertyCall(expr)) {
                return 0 /* None */;
            }
            var entityName = expr.arguments[0];
            if (isExportsIdentifier(entityName) || isModuleExportsAccessExpression(entityName)) {
                return 8 /* ObjectDefinePropertyExports */;
            }
            if (isBindableStaticAccessExpression(entityName) && getElementOrPropertyAccessName(entityName) === "prototype") {
                return 9 /* ObjectDefinePrototypeProperty */;
            }
            return 7 /* ObjectDefinePropertyValue */;
        }
        if (expr.operatorToken.kind !== 62 /* EqualsToken */ || !isAccessExpression(expr.left)) {
            return 0 /* None */;
        }
        if (isBindableStaticNameExpression(expr.left.expression, /*excludeThisKeyword*/ true) && getElementOrPropertyAccessName(expr.left) === "prototype" && ts.isObjectLiteralExpression(getInitializerOfBinaryExpression(expr))) {
            // F.prototype = { ... }
            return 6 /* Prototype */;
        }
        return getAssignmentDeclarationPropertyAccessKind(expr.left);
    }
    /**
     * Does not handle signed numeric names like `a[+0]` - handling those would require handling prefix unary expressions
     * throughout late binding handling as well, which is awkward (but ultimately probably doable if there is demand)
     */
    /* @internal */
    function getElementOrPropertyAccessArgumentExpressionOrName(node) {
        if (ts.isPropertyAccessExpression(node)) {
            return node.name;
        }
        var arg = skipParentheses(node.argumentExpression);
        if (ts.isNumericLiteral(arg) || ts.isStringLiteralLike(arg)) {
            return arg;
        }
        return node;
    }
    ts.getElementOrPropertyAccessArgumentExpressionOrName = getElementOrPropertyAccessArgumentExpressionOrName;
    function getElementOrPropertyAccessName(node) {
        var name = getElementOrPropertyAccessArgumentExpressionOrName(node);
        if (name) {
            if (ts.isIdentifier(name)) {
                return name.escapedText;
            }
            if (ts.isStringLiteralLike(name) || ts.isNumericLiteral(name)) {
                return ts.escapeLeadingUnderscores(name.text);
            }
        }
        if (ts.isElementAccessExpression(node) && isWellKnownSymbolSyntactically(node.argumentExpression)) {
            return getPropertyNameForKnownSymbolName(ts.idText(node.argumentExpression.name));
        }
        return undefined;
    }
    ts.getElementOrPropertyAccessName = getElementOrPropertyAccessName;
    function getAssignmentDeclarationPropertyAccessKind(lhs) {
        if (lhs.expression.kind === 104 /* ThisKeyword */) {
            return 4 /* ThisProperty */;
        }
        else if (isModuleExportsAccessExpression(lhs)) {
            // module.exports = expr
            return 2 /* ModuleExports */;
        }
        else if (isBindableStaticNameExpression(lhs.expression, /*excludeThisKeyword*/ true)) {
            if (isPrototypeAccess(lhs.expression)) {
                // F.G....prototype.x = expr
                return 3 /* PrototypeProperty */;
            }
            var nextToLast = lhs;
            while (!ts.isIdentifier(nextToLast.expression)) {
                nextToLast = nextToLast.expression;
            }
            var id = nextToLast.expression;
            if ((id.escapedText === "exports" ||
                id.escapedText === "module" && getElementOrPropertyAccessName(nextToLast) === "exports") &&
                // ExportsProperty does not support binding with computed names
                isBindableStaticAccessExpression(lhs)) {
                // exports.name = expr OR module.exports.name = expr OR exports["name"] = expr ...
                return 1 /* ExportsProperty */;
            }
            if (isBindableStaticNameExpression(lhs, /*excludeThisKeyword*/ true) || (ts.isElementAccessExpression(lhs) && isDynamicName(lhs))) {
                // F.G...x = expr
                return 5 /* Property */;
            }
        }
        return 0 /* None */;
    }
    ts.getAssignmentDeclarationPropertyAccessKind = getAssignmentDeclarationPropertyAccessKind;
    function getInitializerOfBinaryExpression(expr) {
        while (ts.isBinaryExpression(expr.right)) {
            expr = expr.right;
        }
        return expr.right;
    }
    ts.getInitializerOfBinaryExpression = getInitializerOfBinaryExpression;
    function isPrototypePropertyAssignment(node) {
        return ts.isBinaryExpression(node) && getAssignmentDeclarationKind(node) === 3 /* PrototypeProperty */;
    }
    ts.isPrototypePropertyAssignment = isPrototypePropertyAssignment;
    function isSpecialPropertyDeclaration(expr) {
        return isInJSFile(expr) &&
            expr.parent && expr.parent.kind === 226 /* ExpressionStatement */ &&
            (!ts.isElementAccessExpression(expr) || isLiteralLikeElementAccess(expr)) &&
            !!ts.getJSDocTypeTag(expr.parent);
    }
    ts.isSpecialPropertyDeclaration = isSpecialPropertyDeclaration;
    function setValueDeclaration(symbol, node) {
        var valueDeclaration = symbol.valueDeclaration;
        if (!valueDeclaration ||
            !(node.flags & 8388608 /* Ambient */ && !(valueDeclaration.flags & 8388608 /* Ambient */)) &&
                (isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
            (valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
            // other kinds of value declarations take precedence over modules and assignment declarations
            symbol.valueDeclaration = node;
        }
    }
    ts.setValueDeclaration = setValueDeclaration;
    function isFunctionSymbol(symbol) {
        if (!symbol || !symbol.valueDeclaration) {
            return false;
        }
        var decl = symbol.valueDeclaration;
        return decl.kind === 244 /* FunctionDeclaration */ || ts.isVariableDeclaration(decl) && decl.initializer && ts.isFunctionLike(decl.initializer);
    }
    ts.isFunctionSymbol = isFunctionSymbol;
    function importFromModuleSpecifier(node) {
        return tryGetImportFromModuleSpecifier(node) || ts.Debug.failBadSyntaxKind(node.parent);
    }
    ts.importFromModuleSpecifier = importFromModuleSpecifier;
    function tryGetImportFromModuleSpecifier(node) {
        switch (node.parent.kind) {
            case 254 /* ImportDeclaration */:
            case 260 /* ExportDeclaration */:
                return node.parent;
            case 265 /* ExternalModuleReference */:
                return node.parent.parent;
            case 196 /* CallExpression */:
                return isImportCall(node.parent) || isRequireCall(node.parent, /*checkArg*/ false) ? node.parent : undefined;
            case 187 /* LiteralType */:
                ts.Debug.assert(ts.isStringLiteral(node));
                return ts.tryCast(node.parent.parent, ts.isImportTypeNode);
            default:
                return undefined;
        }
    }
    ts.tryGetImportFromModuleSpecifier = tryGetImportFromModuleSpecifier;
    function getExternalModuleName(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
            case 260 /* ExportDeclaration */:
                return node.moduleSpecifier;
            case 253 /* ImportEqualsDeclaration */:
                return node.moduleReference.kind === 265 /* ExternalModuleReference */ ? node.moduleReference.expression : undefined;
            case 188 /* ImportType */:
                return isLiteralImportTypeNode(node) ? node.argument.literal : undefined;
            default:
                return ts.Debug.assertNever(node);
        }
    }
    ts.getExternalModuleName = getExternalModuleName;
    function getNamespaceDeclarationNode(node) {
        switch (node.kind) {
            case 254 /* ImportDeclaration */:
                return node.importClause && ts.tryCast(node.importClause.namedBindings, ts.isNamespaceImport);
            case 253 /* ImportEqualsDeclaration */:
                return node;
            case 260 /* ExportDeclaration */:
                return node.exportClause && ts.tryCast(node.exportClause, ts.isNamespaceExport);
            default:
                return ts.Debug.assertNever(node);
        }
    }
    ts.getNamespaceDeclarationNode = getNamespaceDeclarationNode;
    function isDefaultImport(node) {
        return node.kind === 254 /* ImportDeclaration */ && !!node.importClause && !!node.importClause.name;
    }
    ts.isDefaultImport = isDefaultImport;
    function forEachImportClauseDeclaration(node, action) {
        if (node.name) {
            var result = action(node);
            if (result)
                return result;
        }
        if (node.namedBindings) {
            var result = ts.isNamespaceImport(node.namedBindings)
                ? action(node.namedBindings)
                : ts.forEach(node.namedBindings.elements, action);
            if (result)
                return result;
        }
    }
    ts.forEachImportClauseDeclaration = forEachImportClauseDeclaration;
    function hasQuestionToken(node) {
        if (node) {
            switch (node.kind) {
                case 156 /* Parameter */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 282 /* ShorthandPropertyAssignment */:
                case 281 /* PropertyAssignment */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    return node.questionToken !== undefined;
            }
        }
        return false;
    }
    ts.hasQuestionToken = hasQuestionToken;
    function isJSDocConstructSignature(node) {
        var param = ts.isJSDocFunctionType(node) ? ts.firstOrUndefined(node.parameters) : undefined;
        var name = ts.tryCast(param && param.name, ts.isIdentifier);
        return !!name && name.escapedText === "new";
    }
    ts.isJSDocConstructSignature = isJSDocConstructSignature;
    function isJSDocTypeAlias(node) {
        return node.kind === 322 /* JSDocTypedefTag */ || node.kind === 315 /* JSDocCallbackTag */ || node.kind === 316 /* JSDocEnumTag */;
    }
    ts.isJSDocTypeAlias = isJSDocTypeAlias;
    function isTypeAlias(node) {
        return isJSDocTypeAlias(node) || ts.isTypeAliasDeclaration(node);
    }
    ts.isTypeAlias = isTypeAlias;
    function getSourceOfAssignment(node) {
        return ts.isExpressionStatement(node) &&
            ts.isBinaryExpression(node.expression) &&
            node.expression.operatorToken.kind === 62 /* EqualsToken */
            ? getRightMostAssignedExpression(node.expression)
            : undefined;
    }
    function getSourceOfDefaultedAssignment(node) {
        return ts.isExpressionStatement(node) &&
            ts.isBinaryExpression(node.expression) &&
            getAssignmentDeclarationKind(node.expression) !== 0 /* None */ &&
            ts.isBinaryExpression(node.expression.right) &&
            (node.expression.right.operatorToken.kind === 56 /* BarBarToken */ || node.expression.right.operatorToken.kind === 60 /* QuestionQuestionToken */)
            ? node.expression.right.right
            : undefined;
    }
    function getSingleInitializerOfVariableStatementOrPropertyDeclaration(node) {
        switch (node.kind) {
            case 225 /* VariableStatement */:
                var v = getSingleVariableOfVariableStatement(node);
                return v && v.initializer;
            case 159 /* PropertyDeclaration */:
                return node.initializer;
            case 281 /* PropertyAssignment */:
                return node.initializer;
        }
    }
    ts.getSingleInitializerOfVariableStatementOrPropertyDeclaration = getSingleInitializerOfVariableStatementOrPropertyDeclaration;
    function getSingleVariableOfVariableStatement(node) {
        return ts.isVariableStatement(node) ? ts.firstOrUndefined(node.declarationList.declarations) : undefined;
    }
    function getNestedModuleDeclaration(node) {
        return ts.isModuleDeclaration(node) &&
            node.body &&
            node.body.kind === 249 /* ModuleDeclaration */
            ? node.body
            : undefined;
    }
    function getJSDocCommentsAndTags(hostNode) {
        var result;
        // Pull parameter comments from declaring function as well
        if (isVariableLike(hostNode) && ts.hasInitializer(hostNode) && ts.hasJSDocNodes(hostNode.initializer)) {
            result = ts.append(result, ts.last(hostNode.initializer.jsDoc));
        }
        var node = hostNode;
        while (node && node.parent) {
            if (ts.hasJSDocNodes(node)) {
                result = ts.append(result, ts.last(node.jsDoc));
            }
            if (node.kind === 156 /* Parameter */) {
                result = ts.addRange(result, ts.getJSDocParameterTags(node));
                break;
            }
            if (node.kind === 155 /* TypeParameter */) {
                result = ts.addRange(result, ts.getJSDocTypeParameterTags(node));
                break;
            }
            node = getNextJSDocCommentLocation(node);
        }
        return result || ts.emptyArray;
    }
    ts.getJSDocCommentsAndTags = getJSDocCommentsAndTags;
    function getNextJSDocCommentLocation(node) {
        var parent = node.parent;
        if (parent.kind === 281 /* PropertyAssignment */ ||
            parent.kind === 259 /* ExportAssignment */ ||
            parent.kind === 159 /* PropertyDeclaration */ ||
            parent.kind === 226 /* ExpressionStatement */ && node.kind === 194 /* PropertyAccessExpression */ ||
            getNestedModuleDeclaration(parent) ||
            ts.isBinaryExpression(node) && node.operatorToken.kind === 62 /* EqualsToken */) {
            return parent;
        }
        // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
        // /**
        //   * @param {number} name
        //   * @returns {number}
        //   */
        // var x = function(name) { return name.length; }
        else if (parent.parent &&
            (getSingleVariableOfVariableStatement(parent.parent) === node ||
                ts.isBinaryExpression(parent) && parent.operatorToken.kind === 62 /* EqualsToken */)) {
            return parent.parent;
        }
        else if (parent.parent && parent.parent.parent &&
            (getSingleVariableOfVariableStatement(parent.parent.parent) ||
                getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node ||
                getSourceOfDefaultedAssignment(parent.parent.parent))) {
            return parent.parent.parent;
        }
    }
    /** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */
    function getParameterSymbolFromJSDoc(node) {
        if (node.symbol) {
            return node.symbol;
        }
        if (!ts.isIdentifier(node.name)) {
            return undefined;
        }
        var name = node.name.escapedText;
        var decl = getHostSignatureFromJSDoc(node);
        if (!decl) {
            return undefined;
        }
        var parameter = ts.find(decl.parameters, function (p) { return p.name.kind === 75 /* Identifier */ && p.name.escapedText === name; });
        return parameter && parameter.symbol;
    }
    ts.getParameterSymbolFromJSDoc = getParameterSymbolFromJSDoc;
    function getHostSignatureFromJSDoc(node) {
        var host = getEffectiveJSDocHost(node);
        return host && ts.isFunctionLike(host) ? host : undefined;
    }
    ts.getHostSignatureFromJSDoc = getHostSignatureFromJSDoc;
    function getEffectiveJSDocHost(node) {
        var host = getJSDocHost(node);
        var decl = getSourceOfDefaultedAssignment(host) ||
            getSourceOfAssignment(host) ||
            getSingleInitializerOfVariableStatementOrPropertyDeclaration(host) ||
            getSingleVariableOfVariableStatement(host) ||
            getNestedModuleDeclaration(host) ||
            host;
        return decl;
    }
    ts.getEffectiveJSDocHost = getEffectiveJSDocHost;
    /** Use getEffectiveJSDocHost if you additionally need to look for jsdoc on parent nodes, like assignments.  */
    function getJSDocHost(node) {
        return ts.Debug.checkDefined(findAncestor(node.parent, ts.isJSDoc)).parent;
    }
    ts.getJSDocHost = getJSDocHost;
    function getTypeParameterFromJsDoc(node) {
        var name = node.name.escapedText;
        var typeParameters = node.parent.parent.parent.typeParameters;
        return typeParameters && ts.find(typeParameters, function (p) { return p.name.escapedText === name; });
    }
    ts.getTypeParameterFromJsDoc = getTypeParameterFromJsDoc;
    function hasRestParameter(s) {
        var last = ts.lastOrUndefined(s.parameters);
        return !!last && isRestParameter(last);
    }
    ts.hasRestParameter = hasRestParameter;
    function isRestParameter(node) {
        var type = ts.isJSDocParameterTag(node) ? (node.typeExpression && node.typeExpression.type) : node.type;
        return node.dotDotDotToken !== undefined || !!type && type.kind === 301 /* JSDocVariadicType */;
    }
    ts.isRestParameter = isRestParameter;
    function hasTypeArguments(node) {
        return !!node.typeArguments;
    }
    ts.hasTypeArguments = hasTypeArguments;
    var AssignmentKind;
    (function (AssignmentKind) {
        AssignmentKind[AssignmentKind["None"] = 0] = "None";
        AssignmentKind[AssignmentKind["Definite"] = 1] = "Definite";
        AssignmentKind[AssignmentKind["Compound"] = 2] = "Compound";
    })(AssignmentKind = ts.AssignmentKind || (ts.AssignmentKind = {}));
    function getAssignmentTargetKind(node) {
        var parent = node.parent;
        while (true) {
            switch (parent.kind) {
                case 209 /* BinaryExpression */:
                    var binaryOperator = parent.operatorToken.kind;
                    return isAssignmentOperator(binaryOperator) && parent.left === node ?
                        binaryOperator === 62 /* EqualsToken */ ? 1 /* Definite */ : 2 /* Compound */ :
                        0 /* None */;
                case 207 /* PrefixUnaryExpression */:
                case 208 /* PostfixUnaryExpression */:
                    var unaryOperator = parent.operator;
                    return unaryOperator === 45 /* PlusPlusToken */ || unaryOperator === 46 /* MinusMinusToken */ ? 2 /* Compound */ : 0 /* None */;
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                    return parent.initializer === node ? 1 /* Definite */ : 0 /* None */;
                case 200 /* ParenthesizedExpression */:
                case 192 /* ArrayLiteralExpression */:
                case 213 /* SpreadElement */:
                case 218 /* NonNullExpression */:
                    node = parent;
                    break;
                case 282 /* ShorthandPropertyAssignment */:
                    if (parent.name !== node) {
                        return 0 /* None */;
                    }
                    node = parent.parent;
                    break;
                case 281 /* PropertyAssignment */:
                    if (parent.name === node) {
                        return 0 /* None */;
                    }
                    node = parent.parent;
                    break;
                default:
                    return 0 /* None */;
            }
            parent = node.parent;
        }
    }
    ts.getAssignmentTargetKind = getAssignmentTargetKind;
    // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property
    // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is
    // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'.
    // (Note that `p` is not a target in the above examples, only `a`.)
    function isAssignmentTarget(node) {
        return getAssignmentTargetKind(node) !== 0 /* None */;
    }
    ts.isAssignmentTarget = isAssignmentTarget;
    /**
     * Indicates whether a node could contain a `var` VariableDeclarationList that contributes to
     * the same `var` declaration scope as the node's parent.
     */
    function isNodeWithPossibleHoistedDeclaration(node) {
        switch (node.kind) {
            case 223 /* Block */:
            case 225 /* VariableStatement */:
            case 236 /* WithStatement */:
            case 227 /* IfStatement */:
            case 237 /* SwitchStatement */:
            case 251 /* CaseBlock */:
            case 277 /* CaseClause */:
            case 278 /* DefaultClause */:
            case 238 /* LabeledStatement */:
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
            case 228 /* DoStatement */:
            case 229 /* WhileStatement */:
            case 240 /* TryStatement */:
            case 280 /* CatchClause */:
                return true;
        }
        return false;
    }
    ts.isNodeWithPossibleHoistedDeclaration = isNodeWithPossibleHoistedDeclaration;
    function isValueSignatureDeclaration(node) {
        return ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isMethodOrAccessor(node) || ts.isFunctionDeclaration(node) || ts.isConstructorDeclaration(node);
    }
    ts.isValueSignatureDeclaration = isValueSignatureDeclaration;
    function walkUp(node, kind) {
        while (node && node.kind === kind) {
            node = node.parent;
        }
        return node;
    }
    function walkUpParenthesizedTypes(node) {
        return walkUp(node, 182 /* ParenthesizedType */);
    }
    ts.walkUpParenthesizedTypes = walkUpParenthesizedTypes;
    function walkUpParenthesizedExpressions(node) {
        return walkUp(node, 200 /* ParenthesizedExpression */);
    }
    ts.walkUpParenthesizedExpressions = walkUpParenthesizedExpressions;
    function skipParentheses(node) {
        return ts.skipOuterExpressions(node, 1 /* Parentheses */);
    }
    ts.skipParentheses = skipParentheses;
    function skipParenthesesUp(node) {
        while (node.kind === 200 /* ParenthesizedExpression */) {
            node = node.parent;
        }
        return node;
    }
    // a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped
    function isDeleteTarget(node) {
        if (node.kind !== 194 /* PropertyAccessExpression */ && node.kind !== 195 /* ElementAccessExpression */) {
            return false;
        }
        node = walkUpParenthesizedExpressions(node.parent);
        return node && node.kind === 203 /* DeleteExpression */;
    }
    ts.isDeleteTarget = isDeleteTarget;
    function isNodeDescendantOf(node, ancestor) {
        while (node) {
            if (node === ancestor)
                return true;
            node = node.parent;
        }
        return false;
    }
    ts.isNodeDescendantOf = isNodeDescendantOf;
    // True if `name` is the name of a declaration node
    function isDeclarationName(name) {
        return !ts.isSourceFile(name) && !ts.isBindingPattern(name) && ts.isDeclaration(name.parent) && name.parent.name === name;
    }
    ts.isDeclarationName = isDeclarationName;
    // See GH#16030
    function getDeclarationFromName(name) {
        var parent = name.parent;
        switch (name.kind) {
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 8 /* NumericLiteral */:
                if (ts.isComputedPropertyName(parent))
                    return parent.parent;
            // falls through
            case 75 /* Identifier */:
                if (ts.isDeclaration(parent)) {
                    return parent.name === name ? parent : undefined;
                }
                else if (ts.isQualifiedName(parent)) {
                    var tag = parent.parent;
                    return ts.isJSDocParameterTag(tag) && tag.name === parent ? tag : undefined;
                }
                else {
                    var binExp = parent.parent;
                    return ts.isBinaryExpression(binExp) &&
                        getAssignmentDeclarationKind(binExp) !== 0 /* None */ &&
                        (binExp.left.symbol || binExp.symbol) &&
                        ts.getNameOfDeclaration(binExp) === name
                        ? binExp
                        : undefined;
                }
            case 76 /* PrivateIdentifier */:
                return ts.isDeclaration(parent) && parent.name === name ? parent : undefined;
            default:
                return undefined;
        }
    }
    ts.getDeclarationFromName = getDeclarationFromName;
    function isLiteralComputedPropertyDeclarationName(node) {
        return isStringOrNumericLiteralLike(node) &&
            node.parent.kind === 154 /* ComputedPropertyName */ &&
            ts.isDeclaration(node.parent.parent);
    }
    ts.isLiteralComputedPropertyDeclarationName = isLiteralComputedPropertyDeclarationName;
    // Return true if the given identifier is classified as an IdentifierName
    function isIdentifierName(node) {
        var parent = node.parent;
        switch (parent.kind) {
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 284 /* EnumMember */:
            case 281 /* PropertyAssignment */:
            case 194 /* PropertyAccessExpression */:
                // Name in member declaration or property name in property access
                return parent.name === node;
            case 153 /* QualifiedName */:
                // Name on right hand side of dot in a type query or type reference
                if (parent.right === node) {
                    while (parent.kind === 153 /* QualifiedName */) {
                        parent = parent.parent;
                    }
                    return parent.kind === 172 /* TypeQuery */ || parent.kind === 169 /* TypeReference */;
                }
                return false;
            case 191 /* BindingElement */:
            case 258 /* ImportSpecifier */:
                // Property name in binding element or import specifier
                return parent.propertyName === node;
            case 263 /* ExportSpecifier */:
            case 273 /* JsxAttribute */:
                // Any name in an export specifier or JSX Attribute
                return true;
        }
        return false;
    }
    ts.isIdentifierName = isIdentifierName;
    // An alias symbol is created by one of the following declarations:
    // import <symbol> = ...
    // import <symbol> from ...
    // import * as <symbol> from ...
    // import { x as <symbol> } from ...
    // export { x as <symbol> } from ...
    // export * as ns <symbol> from ...
    // export = <EntityNameExpression>
    // export default <EntityNameExpression>
    // module.exports = <EntityNameExpression>
    // {<Identifier>}
    // {name: <EntityNameExpression>}
    function isAliasSymbolDeclaration(node) {
        return node.kind === 253 /* ImportEqualsDeclaration */ ||
            node.kind === 252 /* NamespaceExportDeclaration */ ||
            node.kind === 255 /* ImportClause */ && !!node.name ||
            node.kind === 256 /* NamespaceImport */ ||
            node.kind === 262 /* NamespaceExport */ ||
            node.kind === 258 /* ImportSpecifier */ ||
            node.kind === 263 /* ExportSpecifier */ ||
            node.kind === 259 /* ExportAssignment */ && exportAssignmentIsAlias(node) ||
            ts.isBinaryExpression(node) && getAssignmentDeclarationKind(node) === 2 /* ModuleExports */ && exportAssignmentIsAlias(node) ||
            ts.isPropertyAccessExpression(node) && ts.isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === 62 /* EqualsToken */ && isAliasableExpression(node.parent.right) ||
            node.kind === 282 /* ShorthandPropertyAssignment */ ||
            node.kind === 281 /* PropertyAssignment */ && isAliasableExpression(node.initializer);
    }
    ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration;
    function getAliasDeclarationFromName(node) {
        switch (node.parent.kind) {
            case 255 /* ImportClause */:
            case 258 /* ImportSpecifier */:
            case 256 /* NamespaceImport */:
            case 263 /* ExportSpecifier */:
            case 259 /* ExportAssignment */:
            case 253 /* ImportEqualsDeclaration */:
                return node.parent;
            case 153 /* QualifiedName */:
                do {
                    node = node.parent;
                } while (node.parent.kind === 153 /* QualifiedName */);
                return getAliasDeclarationFromName(node);
        }
    }
    ts.getAliasDeclarationFromName = getAliasDeclarationFromName;
    function isAliasableExpression(e) {
        return isEntityNameExpression(e) || ts.isClassExpression(e);
    }
    ts.isAliasableExpression = isAliasableExpression;
    function exportAssignmentIsAlias(node) {
        var e = getExportAssignmentExpression(node);
        return isAliasableExpression(e);
    }
    ts.exportAssignmentIsAlias = exportAssignmentIsAlias;
    function getExportAssignmentExpression(node) {
        return ts.isExportAssignment(node) ? node.expression : node.right;
    }
    ts.getExportAssignmentExpression = getExportAssignmentExpression;
    function getPropertyAssignmentAliasLikeExpression(node) {
        return node.kind === 282 /* ShorthandPropertyAssignment */ ? node.name : node.kind === 281 /* PropertyAssignment */ ? node.initializer :
            node.parent.right;
    }
    ts.getPropertyAssignmentAliasLikeExpression = getPropertyAssignmentAliasLikeExpression;
    function getEffectiveBaseTypeNode(node) {
        var baseType = getClassExtendsHeritageElement(node);
        if (baseType && isInJSFile(node)) {
            // Prefer an @augments tag because it may have type parameters.
            var tag = ts.getJSDocAugmentsTag(node);
            if (tag) {
                return tag.class;
            }
        }
        return baseType;
    }
    ts.getEffectiveBaseTypeNode = getEffectiveBaseTypeNode;
    function getClassExtendsHeritageElement(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 90 /* ExtendsKeyword */);
        return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined;
    }
    ts.getClassExtendsHeritageElement = getClassExtendsHeritageElement;
    function getEffectiveImplementsTypeNodes(node) {
        if (isInJSFile(node)) {
            return ts.getJSDocImplementsTags(node).map(function (n) { return n.class; });
        }
        else {
            var heritageClause = getHeritageClause(node.heritageClauses, 113 /* ImplementsKeyword */);
            return heritageClause === null || heritageClause === void 0 ? void 0 : heritageClause.types;
        }
    }
    ts.getEffectiveImplementsTypeNodes = getEffectiveImplementsTypeNodes;
    /** Returns the node in an `extends` or `implements` clause of a class or interface. */
    function getAllSuperTypeNodes(node) {
        return ts.isInterfaceDeclaration(node) ? getInterfaceBaseTypeNodes(node) || ts.emptyArray :
            ts.isClassLike(node) ? ts.concatenate(ts.singleElementArray(getEffectiveBaseTypeNode(node)), getEffectiveImplementsTypeNodes(node)) || ts.emptyArray :
                ts.emptyArray;
    }
    ts.getAllSuperTypeNodes = getAllSuperTypeNodes;
    function getInterfaceBaseTypeNodes(node) {
        var heritageClause = getHeritageClause(node.heritageClauses, 90 /* ExtendsKeyword */);
        return heritageClause ? heritageClause.types : undefined;
    }
    ts.getInterfaceBaseTypeNodes = getInterfaceBaseTypeNodes;
    function getHeritageClause(clauses, kind) {
        if (clauses) {
            for (var _i = 0, clauses_1 = clauses; _i < clauses_1.length; _i++) {
                var clause = clauses_1[_i];
                if (clause.token === kind) {
                    return clause;
                }
            }
        }
        return undefined;
    }
    ts.getHeritageClause = getHeritageClause;
    function getAncestor(node, kind) {
        while (node) {
            if (node.kind === kind) {
                return node;
            }
            node = node.parent;
        }
        return undefined;
    }
    ts.getAncestor = getAncestor;
    function isKeyword(token) {
        return 77 /* FirstKeyword */ <= token && token <= 152 /* LastKeyword */;
    }
    ts.isKeyword = isKeyword;
    function isContextualKeyword(token) {
        return 122 /* FirstContextualKeyword */ <= token && token <= 152 /* LastContextualKeyword */;
    }
    ts.isContextualKeyword = isContextualKeyword;
    function isNonContextualKeyword(token) {
        return isKeyword(token) && !isContextualKeyword(token);
    }
    ts.isNonContextualKeyword = isNonContextualKeyword;
    function isFutureReservedKeyword(token) {
        return 113 /* FirstFutureReservedWord */ <= token && token <= 121 /* LastFutureReservedWord */;
    }
    ts.isFutureReservedKeyword = isFutureReservedKeyword;
    function isStringANonContextualKeyword(name) {
        var token = ts.stringToToken(name);
        return token !== undefined && isNonContextualKeyword(token);
    }
    ts.isStringANonContextualKeyword = isStringANonContextualKeyword;
    function isStringAKeyword(name) {
        var token = ts.stringToToken(name);
        return token !== undefined && isKeyword(token);
    }
    ts.isStringAKeyword = isStringAKeyword;
    function isIdentifierANonContextualKeyword(_a) {
        var originalKeywordKind = _a.originalKeywordKind;
        return !!originalKeywordKind && !isContextualKeyword(originalKeywordKind);
    }
    ts.isIdentifierANonContextualKeyword = isIdentifierANonContextualKeyword;
    function isTrivia(token) {
        return 2 /* FirstTriviaToken */ <= token && token <= 7 /* LastTriviaToken */;
    }
    ts.isTrivia = isTrivia;
    var FunctionFlags;
    (function (FunctionFlags) {
        FunctionFlags[FunctionFlags["Normal"] = 0] = "Normal";
        FunctionFlags[FunctionFlags["Generator"] = 1] = "Generator";
        FunctionFlags[FunctionFlags["Async"] = 2] = "Async";
        FunctionFlags[FunctionFlags["Invalid"] = 4] = "Invalid";
        FunctionFlags[FunctionFlags["AsyncGenerator"] = 3] = "AsyncGenerator";
    })(FunctionFlags = ts.FunctionFlags || (ts.FunctionFlags = {}));
    function getFunctionFlags(node) {
        if (!node) {
            return 4 /* Invalid */;
        }
        var flags = 0 /* Normal */;
        switch (node.kind) {
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 161 /* MethodDeclaration */:
                if (node.asteriskToken) {
                    flags |= 1 /* Generator */;
                }
            // falls through
            case 202 /* ArrowFunction */:
                if (hasModifier(node, 256 /* Async */)) {
                    flags |= 2 /* Async */;
                }
                break;
        }
        if (!node.body) {
            flags |= 4 /* Invalid */;
        }
        return flags;
    }
    ts.getFunctionFlags = getFunctionFlags;
    function isAsyncFunction(node) {
        switch (node.kind) {
            case 244 /* FunctionDeclaration */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
            case 161 /* MethodDeclaration */:
                return node.body !== undefined
                    && node.asteriskToken === undefined
                    && hasModifier(node, 256 /* Async */);
        }
        return false;
    }
    ts.isAsyncFunction = isAsyncFunction;
    function isStringOrNumericLiteralLike(node) {
        return ts.isStringLiteralLike(node) || ts.isNumericLiteral(node);
    }
    ts.isStringOrNumericLiteralLike = isStringOrNumericLiteralLike;
    function isSignedNumericLiteral(node) {
        return ts.isPrefixUnaryExpression(node) && (node.operator === 39 /* PlusToken */ || node.operator === 40 /* MinusToken */) && ts.isNumericLiteral(node.operand);
    }
    ts.isSignedNumericLiteral = isSignedNumericLiteral;
    /**
     * A declaration has a dynamic name if all of the following are true:
     *   1. The declaration has a computed property name.
     *   2. The computed name is *not* expressed as a StringLiteral.
     *   3. The computed name is *not* expressed as a NumericLiteral.
     *   4. The computed name is *not* expressed as a PlusToken or MinusToken
     *      immediately followed by a NumericLiteral.
     *   5. The computed name is *not* expressed as `Symbol.<name>`, where `<name>`
     *      is a property of the Symbol constructor that denotes a built-in
     *      Symbol.
     */
    function hasDynamicName(declaration) {
        var name = ts.getNameOfDeclaration(declaration);
        return !!name && isDynamicName(name);
    }
    ts.hasDynamicName = hasDynamicName;
    function isDynamicName(name) {
        if (!(name.kind === 154 /* ComputedPropertyName */ || name.kind === 195 /* ElementAccessExpression */)) {
            return false;
        }
        var expr = ts.isElementAccessExpression(name) ? skipParentheses(name.argumentExpression) : name.expression;
        return !isStringOrNumericLiteralLike(expr) &&
            !isSignedNumericLiteral(expr) &&
            !isWellKnownSymbolSyntactically(expr);
    }
    ts.isDynamicName = isDynamicName;
    /**
     * Checks if the expression is of the form:
     *    Symbol.name
     * where Symbol is literally the word "Symbol", and name is any identifierName
     */
    function isWellKnownSymbolSyntactically(node) {
        return ts.isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression);
    }
    ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically;
    function getPropertyNameForPropertyNameNode(name) {
        switch (name.kind) {
            case 75 /* Identifier */:
            case 76 /* PrivateIdentifier */:
                return name.escapedText;
            case 10 /* StringLiteral */:
            case 8 /* NumericLiteral */:
                return ts.escapeLeadingUnderscores(name.text);
            case 154 /* ComputedPropertyName */:
                var nameExpression = name.expression;
                if (isWellKnownSymbolSyntactically(nameExpression)) {
                    return getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
                }
                else if (isStringOrNumericLiteralLike(nameExpression)) {
                    return ts.escapeLeadingUnderscores(nameExpression.text);
                }
                return undefined;
            default:
                return ts.Debug.assertNever(name);
        }
    }
    ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode;
    function isPropertyNameLiteral(node) {
        switch (node.kind) {
            case 75 /* Identifier */:
            case 10 /* StringLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 8 /* NumericLiteral */:
                return true;
            default:
                return false;
        }
    }
    ts.isPropertyNameLiteral = isPropertyNameLiteral;
    function getTextOfIdentifierOrLiteral(node) {
        return ts.isIdentifierOrPrivateIdentifier(node) ? ts.idText(node) : node.text;
    }
    ts.getTextOfIdentifierOrLiteral = getTextOfIdentifierOrLiteral;
    function getEscapedTextOfIdentifierOrLiteral(node) {
        return ts.isIdentifierOrPrivateIdentifier(node) ? node.escapedText : ts.escapeLeadingUnderscores(node.text);
    }
    ts.getEscapedTextOfIdentifierOrLiteral = getEscapedTextOfIdentifierOrLiteral;
    function getPropertyNameForUniqueESSymbol(symbol) {
        return "__@" + ts.getSymbolId(symbol) + "@" + symbol.escapedName;
    }
    ts.getPropertyNameForUniqueESSymbol = getPropertyNameForUniqueESSymbol;
    function getPropertyNameForKnownSymbolName(symbolName) {
        return "__@" + symbolName;
    }
    ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName;
    function getSymbolNameForPrivateIdentifier(containingClassSymbol, description) {
        return "__#" + ts.getSymbolId(containingClassSymbol) + "@" + description;
    }
    ts.getSymbolNameForPrivateIdentifier = getSymbolNameForPrivateIdentifier;
    function isKnownSymbol(symbol) {
        return ts.startsWith(symbol.escapedName, "__@");
    }
    ts.isKnownSymbol = isKnownSymbol;
    /**
     * Includes the word "Symbol" with unicode escapes
     */
    function isESSymbolIdentifier(node) {
        return node.kind === 75 /* Identifier */ && node.escapedText === "Symbol";
    }
    ts.isESSymbolIdentifier = isESSymbolIdentifier;
    function isPushOrUnshiftIdentifier(node) {
        return node.escapedText === "push" || node.escapedText === "unshift";
    }
    ts.isPushOrUnshiftIdentifier = isPushOrUnshiftIdentifier;
    function isParameterDeclaration(node) {
        var root = getRootDeclaration(node);
        return root.kind === 156 /* Parameter */;
    }
    ts.isParameterDeclaration = isParameterDeclaration;
    function getRootDeclaration(node) {
        while (node.kind === 191 /* BindingElement */) {
            node = node.parent.parent;
        }
        return node;
    }
    ts.getRootDeclaration = getRootDeclaration;
    function nodeStartsNewLexicalEnvironment(node) {
        var kind = node.kind;
        return kind === 162 /* Constructor */
            || kind === 201 /* FunctionExpression */
            || kind === 244 /* FunctionDeclaration */
            || kind === 202 /* ArrowFunction */
            || kind === 161 /* MethodDeclaration */
            || kind === 163 /* GetAccessor */
            || kind === 164 /* SetAccessor */
            || kind === 249 /* ModuleDeclaration */
            || kind === 290 /* SourceFile */;
    }
    ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment;
    function nodeIsSynthesized(range) {
        return positionIsSynthesized(range.pos)
            || positionIsSynthesized(range.end);
    }
    ts.nodeIsSynthesized = nodeIsSynthesized;
    function getOriginalSourceFile(sourceFile) {
        return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile;
    }
    ts.getOriginalSourceFile = getOriginalSourceFile;
    var Associativity;
    (function (Associativity) {
        Associativity[Associativity["Left"] = 0] = "Left";
        Associativity[Associativity["Right"] = 1] = "Right";
    })(Associativity = ts.Associativity || (ts.Associativity = {}));
    function getExpressionAssociativity(expression) {
        var operator = getOperator(expression);
        var hasArguments = expression.kind === 197 /* NewExpression */ && expression.arguments !== undefined;
        return getOperatorAssociativity(expression.kind, operator, hasArguments);
    }
    ts.getExpressionAssociativity = getExpressionAssociativity;
    function getOperatorAssociativity(kind, operator, hasArguments) {
        switch (kind) {
            case 197 /* NewExpression */:
                return hasArguments ? 0 /* Left */ : 1 /* Right */;
            case 207 /* PrefixUnaryExpression */:
            case 204 /* TypeOfExpression */:
            case 205 /* VoidExpression */:
            case 203 /* DeleteExpression */:
            case 206 /* AwaitExpression */:
            case 210 /* ConditionalExpression */:
            case 212 /* YieldExpression */:
                return 1 /* Right */;
            case 209 /* BinaryExpression */:
                switch (operator) {
                    case 42 /* AsteriskAsteriskToken */:
                    case 62 /* EqualsToken */:
                    case 63 /* PlusEqualsToken */:
                    case 64 /* MinusEqualsToken */:
                    case 66 /* AsteriskAsteriskEqualsToken */:
                    case 65 /* AsteriskEqualsToken */:
                    case 67 /* SlashEqualsToken */:
                    case 68 /* PercentEqualsToken */:
                    case 69 /* LessThanLessThanEqualsToken */:
                    case 70 /* GreaterThanGreaterThanEqualsToken */:
                    case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 72 /* AmpersandEqualsToken */:
                    case 74 /* CaretEqualsToken */:
                    case 73 /* BarEqualsToken */:
                        return 1 /* Right */;
                }
        }
        return 0 /* Left */;
    }
    ts.getOperatorAssociativity = getOperatorAssociativity;
    function getExpressionPrecedence(expression) {
        var operator = getOperator(expression);
        var hasArguments = expression.kind === 197 /* NewExpression */ && expression.arguments !== undefined;
        return getOperatorPrecedence(expression.kind, operator, hasArguments);
    }
    ts.getExpressionPrecedence = getExpressionPrecedence;
    function getOperator(expression) {
        if (expression.kind === 209 /* BinaryExpression */) {
            return expression.operatorToken.kind;
        }
        else if (expression.kind === 207 /* PrefixUnaryExpression */ || expression.kind === 208 /* PostfixUnaryExpression */) {
            return expression.operator;
        }
        else {
            return expression.kind;
        }
    }
    ts.getOperator = getOperator;
    function getOperatorPrecedence(nodeKind, operatorKind, hasArguments) {
        switch (nodeKind) {
            case 327 /* CommaListExpression */:
                return 0;
            case 213 /* SpreadElement */:
                return 1;
            case 212 /* YieldExpression */:
                return 2;
            case 210 /* ConditionalExpression */:
                return 4;
            case 209 /* BinaryExpression */:
                switch (operatorKind) {
                    case 27 /* CommaToken */:
                        return 0;
                    case 62 /* EqualsToken */:
                    case 63 /* PlusEqualsToken */:
                    case 64 /* MinusEqualsToken */:
                    case 66 /* AsteriskAsteriskEqualsToken */:
                    case 65 /* AsteriskEqualsToken */:
                    case 67 /* SlashEqualsToken */:
                    case 68 /* PercentEqualsToken */:
                    case 69 /* LessThanLessThanEqualsToken */:
                    case 70 /* GreaterThanGreaterThanEqualsToken */:
                    case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                    case 72 /* AmpersandEqualsToken */:
                    case 74 /* CaretEqualsToken */:
                    case 73 /* BarEqualsToken */:
                        return 3;
                    default:
                        return getBinaryOperatorPrecedence(operatorKind);
                }
            case 207 /* PrefixUnaryExpression */:
            case 204 /* TypeOfExpression */:
            case 205 /* VoidExpression */:
            case 203 /* DeleteExpression */:
            case 206 /* AwaitExpression */:
                return 16;
            case 208 /* PostfixUnaryExpression */:
                return 17;
            case 196 /* CallExpression */:
                return 18;
            case 197 /* NewExpression */:
                return hasArguments ? 19 : 18;
            case 198 /* TaggedTemplateExpression */:
            case 194 /* PropertyAccessExpression */:
            case 195 /* ElementAccessExpression */:
                return 19;
            case 104 /* ThisKeyword */:
            case 102 /* SuperKeyword */:
            case 75 /* Identifier */:
            case 100 /* NullKeyword */:
            case 106 /* TrueKeyword */:
            case 91 /* FalseKeyword */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
            case 192 /* ArrayLiteralExpression */:
            case 193 /* ObjectLiteralExpression */:
            case 201 /* FunctionExpression */:
            case 202 /* ArrowFunction */:
            case 214 /* ClassExpression */:
            case 266 /* JsxElement */:
            case 267 /* JsxSelfClosingElement */:
            case 270 /* JsxFragment */:
            case 13 /* RegularExpressionLiteral */:
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 211 /* TemplateExpression */:
            case 200 /* ParenthesizedExpression */:
            case 215 /* OmittedExpression */:
                return 20;
            default:
                return -1;
        }
    }
    ts.getOperatorPrecedence = getOperatorPrecedence;
    function getBinaryOperatorPrecedence(kind) {
        switch (kind) {
            case 60 /* QuestionQuestionToken */:
                return 4;
            case 56 /* BarBarToken */:
                return 5;
            case 55 /* AmpersandAmpersandToken */:
                return 6;
            case 51 /* BarToken */:
                return 7;
            case 52 /* CaretToken */:
                return 8;
            case 50 /* AmpersandToken */:
                return 9;
            case 34 /* EqualsEqualsToken */:
            case 35 /* ExclamationEqualsToken */:
            case 36 /* EqualsEqualsEqualsToken */:
            case 37 /* ExclamationEqualsEqualsToken */:
                return 10;
            case 29 /* LessThanToken */:
            case 31 /* GreaterThanToken */:
            case 32 /* LessThanEqualsToken */:
            case 33 /* GreaterThanEqualsToken */:
            case 98 /* InstanceOfKeyword */:
            case 97 /* InKeyword */:
            case 123 /* AsKeyword */:
                return 11;
            case 47 /* LessThanLessThanToken */:
            case 48 /* GreaterThanGreaterThanToken */:
            case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                return 12;
            case 39 /* PlusToken */:
            case 40 /* MinusToken */:
                return 13;
            case 41 /* AsteriskToken */:
            case 43 /* SlashToken */:
            case 44 /* PercentToken */:
                return 14;
            case 42 /* AsteriskAsteriskToken */:
                return 15;
        }
        // -1 is lower than all other precedences.  Returning it will cause binary expression
        // parsing to stop.
        return -1;
    }
    ts.getBinaryOperatorPrecedence = getBinaryOperatorPrecedence;
    function createDiagnosticCollection() {
        var nonFileDiagnostics = []; // See GH#19873
        var filesWithDiagnostics = [];
        var fileDiagnostics = ts.createMap();
        var hasReadNonFileDiagnostics = false;
        return {
            add: add,
            lookup: lookup,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getDiagnostics: getDiagnostics,
            reattachFileDiagnostics: reattachFileDiagnostics
        };
        function reattachFileDiagnostics(newFile) {
            ts.forEach(fileDiagnostics.get(newFile.fileName), function (diagnostic) { return diagnostic.file = newFile; });
        }
        function lookup(diagnostic) {
            var diagnostics;
            if (diagnostic.file) {
                diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
            }
            else {
                diagnostics = nonFileDiagnostics;
            }
            if (!diagnostics) {
                return undefined;
            }
            var result = ts.binarySearch(diagnostics, diagnostic, ts.identity, compareDiagnosticsSkipRelatedInformation);
            if (result >= 0) {
                return diagnostics[result];
            }
            return undefined;
        }
        function add(diagnostic) {
            var diagnostics;
            if (diagnostic.file) {
                diagnostics = fileDiagnostics.get(diagnostic.file.fileName);
                if (!diagnostics) {
                    diagnostics = []; // See GH#19873
                    fileDiagnostics.set(diagnostic.file.fileName, diagnostics);
                    ts.insertSorted(filesWithDiagnostics, diagnostic.file.fileName, ts.compareStringsCaseSensitive);
                }
            }
            else {
                // If we've already read the non-file diagnostics, do not modify the existing array.
                if (hasReadNonFileDiagnostics) {
                    hasReadNonFileDiagnostics = false;
                    nonFileDiagnostics = nonFileDiagnostics.slice();
                }
                diagnostics = nonFileDiagnostics;
            }
            ts.insertSorted(diagnostics, diagnostic, compareDiagnostics);
        }
        function getGlobalDiagnostics() {
            hasReadNonFileDiagnostics = true;
            return nonFileDiagnostics;
        }
        function getDiagnostics(fileName) {
            if (fileName) {
                return fileDiagnostics.get(fileName) || [];
            }
            var fileDiags = ts.flatMapToMutable(filesWithDiagnostics, function (f) { return fileDiagnostics.get(f); });
            if (!nonFileDiagnostics.length) {
                return fileDiags;
            }
            fileDiags.unshift.apply(fileDiags, nonFileDiagnostics);
            return fileDiags;
        }
    }
    ts.createDiagnosticCollection = createDiagnosticCollection;
    var templateSubstitutionRegExp = /\$\{/g;
    function escapeTemplateSubstitution(str) {
        return str.replace(templateSubstitutionRegExp, "\\${");
    }
    /** @internal */
    function hasInvalidEscape(template) {
        return template && !!(ts.isNoSubstitutionTemplateLiteral(template)
            ? template.templateFlags
            : (template.head.templateFlags || ts.some(template.templateSpans, function (span) { return !!span.literal.templateFlags; })));
    }
    ts.hasInvalidEscape = hasInvalidEscape;
    // This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
    // paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
    // the language service. These characters should be escaped when printing, and if any characters are added,
    // the map below must be updated. Note that this regexp *does not* include the 'delete' character.
    // There is no reason for this other than that JSON.stringify does not handle it either.
    var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
    // Template strings should be preserved as much as possible
    var backtickQuoteEscapedCharsRegExp = /[\\`]/g;
    var escapedCharsMap = ts.createMapFromTemplate({
        "\t": "\\t",
        "\v": "\\v",
        "\f": "\\f",
        "\b": "\\b",
        "\r": "\\r",
        "\n": "\\n",
        "\\": "\\\\",
        "\"": "\\\"",
        "\'": "\\\'",
        "\`": "\\\`",
        "\u2028": "\\u2028",
        "\u2029": "\\u2029",
        "\u0085": "\\u0085" // nextLine
    });
    function encodeUtf16EscapeSequence(charCode) {
        var hexCharCode = charCode.toString(16).toUpperCase();
        var paddedHexCode = ("0000" + hexCharCode).slice(-4);
        return "\\u" + paddedHexCode;
    }
    function getReplacement(c, offset, input) {
        if (c.charCodeAt(0) === 0 /* nullCharacter */) {
            var lookAhead = input.charCodeAt(offset + c.length);
            if (lookAhead >= 48 /* _0 */ && lookAhead <= 57 /* _9 */) {
                // If the null character is followed by digits, print as a hex escape to prevent the result from parsing as an octal (which is forbidden in strict mode)
                return "\\x00";
            }
            // Otherwise, keep printing a literal \0 for the null character
            return "\\0";
        }
        return escapedCharsMap.get(c) || encodeUtf16EscapeSequence(c.charCodeAt(0));
    }
    /**
     * Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
     * but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine)
     * Note that this doesn't actually wrap the input in double quotes.
     */
    function escapeString(s, quoteChar) {
        var escapedCharsRegExp = quoteChar === 96 /* backtick */ ? backtickQuoteEscapedCharsRegExp :
            quoteChar === 39 /* singleQuote */ ? singleQuoteEscapedCharsRegExp :
                doubleQuoteEscapedCharsRegExp;
        return s.replace(escapedCharsRegExp, getReplacement);
    }
    ts.escapeString = escapeString;
    var nonAsciiCharacters = /[^\u0000-\u007F]/g;
    function escapeNonAsciiString(s, quoteChar) {
        s = escapeString(s, quoteChar);
        // Replace non-ASCII characters with '\uNNNN' escapes if any exist.
        // Otherwise just return the original string.
        return nonAsciiCharacters.test(s) ?
            s.replace(nonAsciiCharacters, function (c) { return encodeUtf16EscapeSequence(c.charCodeAt(0)); }) :
            s;
    }
    ts.escapeNonAsciiString = escapeNonAsciiString;
    // This consists of the first 19 unprintable ASCII characters, JSX canonical escapes, lineSeparator,
    // paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
    // the language service. These characters should be escaped when printing, and if any characters are added,
    // the map below must be updated.
    var jsxDoubleQuoteEscapedCharsRegExp = /[\"\u0000-\u001f\u2028\u2029\u0085]/g;
    var jsxSingleQuoteEscapedCharsRegExp = /[\'\u0000-\u001f\u2028\u2029\u0085]/g;
    var jsxEscapedCharsMap = ts.createMapFromTemplate({
        "\"": "&quot;",
        "\'": "&apos;"
    });
    function encodeJsxCharacterEntity(charCode) {
        var hexCharCode = charCode.toString(16).toUpperCase();
        return "&#x" + hexCharCode + ";";
    }
    function getJsxAttributeStringReplacement(c) {
        if (c.charCodeAt(0) === 0 /* nullCharacter */) {
            return "&#0;";
        }
        return jsxEscapedCharsMap.get(c) || encodeJsxCharacterEntity(c.charCodeAt(0));
    }
    function escapeJsxAttributeString(s, quoteChar) {
        var escapedCharsRegExp = quoteChar === 39 /* singleQuote */ ? jsxSingleQuoteEscapedCharsRegExp :
            jsxDoubleQuoteEscapedCharsRegExp;
        return s.replace(escapedCharsRegExp, getJsxAttributeStringReplacement);
    }
    ts.escapeJsxAttributeString = escapeJsxAttributeString;
    /**
     * Strip off existed surrounding single quotes, double quotes, or backticks from a given string
     *
     * @return non-quoted string
     */
    function stripQuotes(name) {
        var length = name.length;
        if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && isQuoteOrBacktick(name.charCodeAt(0))) {
            return name.substring(1, length - 1);
        }
        return name;
    }
    ts.stripQuotes = stripQuotes;
    function isQuoteOrBacktick(charCode) {
        return charCode === 39 /* singleQuote */ ||
            charCode === 34 /* doubleQuote */ ||
            charCode === 96 /* backtick */;
    }
    function isIntrinsicJsxName(name) {
        var ch = name.charCodeAt(0);
        return (ch >= 97 /* a */ && ch <= 122 /* z */) || ts.stringContains(name, "-");
    }
    ts.isIntrinsicJsxName = isIntrinsicJsxName;
    var indentStrings = ["", "    "];
    function getIndentString(level) {
        if (indentStrings[level] === undefined) {
            indentStrings[level] = getIndentString(level - 1) + indentStrings[1];
        }
        return indentStrings[level];
    }
    ts.getIndentString = getIndentString;
    function getIndentSize() {
        return indentStrings[1].length;
    }
    ts.getIndentSize = getIndentSize;
    function createTextWriter(newLine) {
        var output;
        var indent;
        var lineStart;
        var lineCount;
        var linePos;
        var hasTrailingComment = false;
        function updateLineCountAndPosFor(s) {
            var lineStartsOfS = ts.computeLineStarts(s);
            if (lineStartsOfS.length > 1) {
                lineCount = lineCount + lineStartsOfS.length - 1;
                linePos = output.length - s.length + ts.last(lineStartsOfS);
                lineStart = (linePos - output.length) === 0;
            }
            else {
                lineStart = false;
            }
        }
        function writeText(s) {
            if (s && s.length) {
                if (lineStart) {
                    s = getIndentString(indent) + s;
                    lineStart = false;
                }
                output += s;
                updateLineCountAndPosFor(s);
            }
        }
        function write(s) {
            if (s)
                hasTrailingComment = false;
            writeText(s);
        }
        function writeComment(s) {
            if (s)
                hasTrailingComment = true;
            writeText(s);
        }
        function reset() {
            output = "";
            indent = 0;
            lineStart = true;
            lineCount = 0;
            linePos = 0;
            hasTrailingComment = false;
        }
        function rawWrite(s) {
            if (s !== undefined) {
                output += s;
                updateLineCountAndPosFor(s);
                hasTrailingComment = false;
            }
        }
        function writeLiteral(s) {
            if (s && s.length) {
                write(s);
            }
        }
        function writeLine(force) {
            if (!lineStart || force) {
                output += newLine;
                lineCount++;
                linePos = output.length;
                lineStart = true;
                hasTrailingComment = false;
            }
        }
        function getTextPosWithWriteLine() {
            return lineStart ? output.length : (output.length + newLine.length);
        }
        reset();
        return {
            write: write,
            rawWrite: rawWrite,
            writeLiteral: writeLiteral,
            writeLine: writeLine,
            increaseIndent: function () { indent++; },
            decreaseIndent: function () { indent--; },
            getIndent: function () { return indent; },
            getTextPos: function () { return output.length; },
            getLine: function () { return lineCount; },
            getColumn: function () { return lineStart ? indent * getIndentSize() : output.length - linePos; },
            getText: function () { return output; },
            isAtStartOfLine: function () { return lineStart; },
            hasTrailingComment: function () { return hasTrailingComment; },
            hasTrailingWhitespace: function () { return !!output.length && ts.isWhiteSpaceLike(output.charCodeAt(output.length - 1)); },
            clear: reset,
            reportInaccessibleThisError: ts.noop,
            reportPrivateInBaseOfClassExpression: ts.noop,
            reportInaccessibleUniqueSymbolError: ts.noop,
            trackSymbol: ts.noop,
            writeKeyword: write,
            writeOperator: write,
            writeParameter: write,
            writeProperty: write,
            writePunctuation: write,
            writeSpace: write,
            writeStringLiteral: write,
            writeSymbol: function (s, _) { return write(s); },
            writeTrailingSemicolon: write,
            writeComment: writeComment,
            getTextPosWithWriteLine: getTextPosWithWriteLine
        };
    }
    ts.createTextWriter = createTextWriter;
    function getTrailingSemicolonDeferringWriter(writer) {
        var pendingTrailingSemicolon = false;
        function commitPendingTrailingSemicolon() {
            if (pendingTrailingSemicolon) {
                writer.writeTrailingSemicolon(";");
                pendingTrailingSemicolon = false;
            }
        }
        return __assign(__assign({}, writer), { writeTrailingSemicolon: function () {
                pendingTrailingSemicolon = true;
            },
            writeLiteral: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeLiteral(s);
            },
            writeStringLiteral: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeStringLiteral(s);
            },
            writeSymbol: function (s, sym) {
                commitPendingTrailingSemicolon();
                writer.writeSymbol(s, sym);
            },
            writePunctuation: function (s) {
                commitPendingTrailingSemicolon();
                writer.writePunctuation(s);
            },
            writeKeyword: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeKeyword(s);
            },
            writeOperator: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeOperator(s);
            },
            writeParameter: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeParameter(s);
            },
            writeSpace: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeSpace(s);
            },
            writeProperty: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeProperty(s);
            },
            writeComment: function (s) {
                commitPendingTrailingSemicolon();
                writer.writeComment(s);
            },
            writeLine: function () {
                commitPendingTrailingSemicolon();
                writer.writeLine();
            },
            increaseIndent: function () {
                commitPendingTrailingSemicolon();
                writer.increaseIndent();
            },
            decreaseIndent: function () {
                commitPendingTrailingSemicolon();
                writer.decreaseIndent();
            } });
    }
    ts.getTrailingSemicolonDeferringWriter = getTrailingSemicolonDeferringWriter;
    function hostUsesCaseSensitiveFileNames(host) {
        return host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false;
    }
    ts.hostUsesCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames;
    function hostGetCanonicalFileName(host) {
        return ts.createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host));
    }
    ts.hostGetCanonicalFileName = hostGetCanonicalFileName;
    function getResolvedExternalModuleName(host, file, referenceFile) {
        return file.moduleName || getExternalModuleNameFromPath(host, file.fileName, referenceFile && referenceFile.fileName);
    }
    ts.getResolvedExternalModuleName = getResolvedExternalModuleName;
    function getExternalModuleNameFromDeclaration(host, resolver, declaration) {
        var file = resolver.getExternalModuleFileFromDeclaration(declaration);
        if (!file || file.isDeclarationFile) {
            return undefined;
        }
        return getResolvedExternalModuleName(host, file);
    }
    ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration;
    /**
     * Resolves a local path to a path which is absolute to the base of the emit
     */
    function getExternalModuleNameFromPath(host, fileName, referencePath) {
        var getCanonicalFileName = function (f) { return host.getCanonicalFileName(f); };
        var dir = ts.toPath(referencePath ? ts.getDirectoryPath(referencePath) : host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName);
        var filePath = ts.getNormalizedAbsolutePath(fileName, host.getCurrentDirectory());
        var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
        var extensionless = removeFileExtension(relativePath);
        return referencePath ? ts.ensurePathIsNonModuleName(extensionless) : extensionless;
    }
    ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath;
    function getOwnEmitOutputFilePath(fileName, host, extension) {
        var compilerOptions = host.getCompilerOptions();
        var emitOutputFilePathWithoutExtension;
        if (compilerOptions.outDir) {
            emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(fileName, host, compilerOptions.outDir));
        }
        else {
            emitOutputFilePathWithoutExtension = removeFileExtension(fileName);
        }
        return emitOutputFilePathWithoutExtension + extension;
    }
    ts.getOwnEmitOutputFilePath = getOwnEmitOutputFilePath;
    function getDeclarationEmitOutputFilePath(fileName, host) {
        return getDeclarationEmitOutputFilePathWorker(fileName, host.getCompilerOptions(), host.getCurrentDirectory(), host.getCommonSourceDirectory(), function (f) { return host.getCanonicalFileName(f); });
    }
    ts.getDeclarationEmitOutputFilePath = getDeclarationEmitOutputFilePath;
    function getDeclarationEmitOutputFilePathWorker(fileName, options, currentDirectory, commonSourceDirectory, getCanonicalFileName) {
        var outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified
        var path = outputDir
            ? getSourceFilePathInNewDirWorker(fileName, outputDir, currentDirectory, commonSourceDirectory, getCanonicalFileName)
            : fileName;
        return removeFileExtension(path) + ".d.ts" /* Dts */;
    }
    ts.getDeclarationEmitOutputFilePathWorker = getDeclarationEmitOutputFilePathWorker;
    /**
     * Gets the source files that are expected to have an emit output.
     *
     * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support
     * transformations.
     *
     * @param host An EmitHost.
     * @param targetSourceFile An optional target source file to emit.
     */
    function getSourceFilesToEmit(host, targetSourceFile, forceDtsEmit) {
        var options = host.getCompilerOptions();
        if (options.outFile || options.out) {
            var moduleKind = getEmitModuleKind(options);
            var moduleEmitEnabled_1 = options.emitDeclarationOnly || moduleKind === ts.ModuleKind.AMD || moduleKind === ts.ModuleKind.System;
            // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified
            return ts.filter(host.getSourceFiles(), function (sourceFile) {
                return (moduleEmitEnabled_1 || !ts.isExternalModule(sourceFile)) &&
                    sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit);
            });
        }
        else {
            var sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile];
            return ts.filter(sourceFiles, function (sourceFile) { return sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit); });
        }
    }
    ts.getSourceFilesToEmit = getSourceFilesToEmit;
    /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */
    function sourceFileMayBeEmitted(sourceFile, host, forceDtsEmit) {
        var options = host.getCompilerOptions();
        return !(options.noEmitForJsFiles && isSourceFileJS(sourceFile)) &&
            !sourceFile.isDeclarationFile &&
            !host.isSourceFileFromExternalLibrary(sourceFile) &&
            !(isJsonSourceFile(sourceFile) && host.getResolvedProjectReferenceToRedirect(sourceFile.fileName)) &&
            (forceDtsEmit || !host.isSourceOfProjectReferenceRedirect(sourceFile.fileName));
    }
    ts.sourceFileMayBeEmitted = sourceFileMayBeEmitted;
    function getSourceFilePathInNewDir(fileName, host, newDirPath) {
        return getSourceFilePathInNewDirWorker(fileName, newDirPath, host.getCurrentDirectory(), host.getCommonSourceDirectory(), function (f) { return host.getCanonicalFileName(f); });
    }
    ts.getSourceFilePathInNewDir = getSourceFilePathInNewDir;
    function getSourceFilePathInNewDirWorker(fileName, newDirPath, currentDirectory, commonSourceDirectory, getCanonicalFileName) {
        var sourceFilePath = ts.getNormalizedAbsolutePath(fileName, currentDirectory);
        var isSourceFileInCommonSourceDirectory = getCanonicalFileName(sourceFilePath).indexOf(getCanonicalFileName(commonSourceDirectory)) === 0;
        sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath;
        return ts.combinePaths(newDirPath, sourceFilePath);
    }
    ts.getSourceFilePathInNewDirWorker = getSourceFilePathInNewDirWorker;
    function writeFile(host, diagnostics, fileName, data, writeByteOrderMark, sourceFiles) {
        host.writeFile(fileName, data, writeByteOrderMark, function (hostErrorMessage) {
            diagnostics.add(createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
        }, sourceFiles);
    }
    ts.writeFile = writeFile;
    function ensureDirectoriesExist(directoryPath, createDirectory, directoryExists) {
        if (directoryPath.length > ts.getRootLength(directoryPath) && !directoryExists(directoryPath)) {
            var parentDirectory = ts.getDirectoryPath(directoryPath);
            ensureDirectoriesExist(parentDirectory, createDirectory, directoryExists);
            createDirectory(directoryPath);
        }
    }
    function writeFileEnsuringDirectories(path, data, writeByteOrderMark, writeFile, createDirectory, directoryExists) {
        // PERF: Checking for directory existence is expensive.  Instead, assume the directory exists
        // and fall back to creating it if the file write fails.
        try {
            writeFile(path, data, writeByteOrderMark);
        }
        catch (_a) {
            ensureDirectoriesExist(ts.getDirectoryPath(ts.normalizePath(path)), createDirectory, directoryExists);
            writeFile(path, data, writeByteOrderMark);
        }
    }
    ts.writeFileEnsuringDirectories = writeFileEnsuringDirectories;
    function getLineOfLocalPosition(sourceFile, pos) {
        var lineStarts = ts.getLineStarts(sourceFile);
        return ts.computeLineOfPosition(lineStarts, pos);
    }
    ts.getLineOfLocalPosition = getLineOfLocalPosition;
    function getLineOfLocalPositionFromLineMap(lineMap, pos) {
        return ts.computeLineOfPosition(lineMap, pos);
    }
    ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap;
    function getFirstConstructorWithBody(node) {
        return ts.find(node.members, function (member) { return ts.isConstructorDeclaration(member) && nodeIsPresent(member.body); });
    }
    ts.getFirstConstructorWithBody = getFirstConstructorWithBody;
    function getSetAccessorValueParameter(accessor) {
        if (accessor && accessor.parameters.length > 0) {
            var hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]);
            return accessor.parameters[hasThis ? 1 : 0];
        }
    }
    ts.getSetAccessorValueParameter = getSetAccessorValueParameter;
    /** Get the type annotation for the value parameter. */
    function getSetAccessorTypeAnnotationNode(accessor) {
        var parameter = getSetAccessorValueParameter(accessor);
        return parameter && parameter.type;
    }
    ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode;
    function getThisParameter(signature) {
        // callback tags do not currently support this parameters
        if (signature.parameters.length && !ts.isJSDocSignature(signature)) {
            var thisParameter = signature.parameters[0];
            if (parameterIsThisKeyword(thisParameter)) {
                return thisParameter;
            }
        }
    }
    ts.getThisParameter = getThisParameter;
    function parameterIsThisKeyword(parameter) {
        return isThisIdentifier(parameter.name);
    }
    ts.parameterIsThisKeyword = parameterIsThisKeyword;
    function isThisIdentifier(node) {
        return !!node && node.kind === 75 /* Identifier */ && identifierIsThisKeyword(node);
    }
    ts.isThisIdentifier = isThisIdentifier;
    function identifierIsThisKeyword(id) {
        return id.originalKeywordKind === 104 /* ThisKeyword */;
    }
    ts.identifierIsThisKeyword = identifierIsThisKeyword;
    function getAllAccessorDeclarations(declarations, accessor) {
        // TODO: GH#18217
        var firstAccessor;
        var secondAccessor;
        var getAccessor;
        var setAccessor;
        if (hasDynamicName(accessor)) {
            firstAccessor = accessor;
            if (accessor.kind === 163 /* GetAccessor */) {
                getAccessor = accessor;
            }
            else if (accessor.kind === 164 /* SetAccessor */) {
                setAccessor = accessor;
            }
            else {
                ts.Debug.fail("Accessor has wrong kind");
            }
        }
        else {
            ts.forEach(declarations, function (member) {
                if (ts.isAccessor(member)
                    && hasModifier(member, 32 /* Static */) === hasModifier(accessor, 32 /* Static */)) {
                    var memberName = getPropertyNameForPropertyNameNode(member.name);
                    var accessorName = getPropertyNameForPropertyNameNode(accessor.name);
                    if (memberName === accessorName) {
                        if (!firstAccessor) {
                            firstAccessor = member;
                        }
                        else if (!secondAccessor) {
                            secondAccessor = member;
                        }
                        if (member.kind === 163 /* GetAccessor */ && !getAccessor) {
                            // eslint-disable-next-line
                            getAccessor = member;
                        }
                        if (member.kind === 164 /* SetAccessor */ && !setAccessor) {
                            // eslint-disable-next-line
                            setAccessor = member;
                        }
                    }
                }
            });
        }
        return {
            firstAccessor: firstAccessor,
            secondAccessor: secondAccessor,
            getAccessor: getAccessor,
            setAccessor: setAccessor
        };
    }
    ts.getAllAccessorDeclarations = getAllAccessorDeclarations;
    /**
     * Gets the effective type annotation of a variable, parameter, or property. If the node was
     * parsed in a JavaScript file, gets the type annotation from JSDoc.  Also gets the type of
     * functions only the JSDoc case.
     */
    function getEffectiveTypeAnnotationNode(node) {
        if (!isInJSFile(node) && ts.isFunctionDeclaration(node))
            return undefined;
        var type = node.type;
        if (type || !isInJSFile(node))
            return type;
        return ts.isJSDocPropertyLikeTag(node) ? node.typeExpression && node.typeExpression.type : ts.getJSDocType(node);
    }
    ts.getEffectiveTypeAnnotationNode = getEffectiveTypeAnnotationNode;
    function getTypeAnnotationNode(node) {
        return node.type;
    }
    ts.getTypeAnnotationNode = getTypeAnnotationNode;
    /**
     * Gets the effective return type annotation of a signature. If the node was parsed in a
     * JavaScript file, gets the return type annotation from JSDoc.
     */
    function getEffectiveReturnTypeNode(node) {
        return ts.isJSDocSignature(node) ?
            node.type && node.type.typeExpression && node.type.typeExpression.type :
            node.type || (isInJSFile(node) ? ts.getJSDocReturnType(node) : undefined);
    }
    ts.getEffectiveReturnTypeNode = getEffectiveReturnTypeNode;
    function getJSDocTypeParameterDeclarations(node) {
        return ts.flatMap(ts.getJSDocTags(node), function (tag) { return isNonTypeAliasTemplate(tag) ? tag.typeParameters : undefined; });
    }
    ts.getJSDocTypeParameterDeclarations = getJSDocTypeParameterDeclarations;
    /** template tags are only available when a typedef isn't already using them */
    function isNonTypeAliasTemplate(tag) {
        return ts.isJSDocTemplateTag(tag) && !(tag.parent.kind === 303 /* JSDocComment */ && tag.parent.tags.some(isJSDocTypeAlias));
    }
    /**
     * Gets the effective type annotation of the value parameter of a set accessor. If the node
     * was parsed in a JavaScript file, gets the type annotation from JSDoc.
     */
    function getEffectiveSetAccessorTypeAnnotationNode(node) {
        var parameter = getSetAccessorValueParameter(node);
        return parameter && getEffectiveTypeAnnotationNode(parameter);
    }
    ts.getEffectiveSetAccessorTypeAnnotationNode = getEffectiveSetAccessorTypeAnnotationNode;
    function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) {
        emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments);
    }
    ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments;
    function emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, pos, leadingComments) {
        // If the leading comments start on different line than the start of node, write new line
        if (leadingComments && leadingComments.length && pos !== leadingComments[0].pos &&
            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingCommentsOfPosition = emitNewLineBeforeLeadingCommentsOfPosition;
    function emitNewLineBeforeLeadingCommentOfPosition(lineMap, writer, pos, commentPos) {
        // If the leading comments start on different line than the start of node, write new line
        if (pos !== commentPos &&
            getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, commentPos)) {
            writer.writeLine();
        }
    }
    ts.emitNewLineBeforeLeadingCommentOfPosition = emitNewLineBeforeLeadingCommentOfPosition;
    function emitComments(text, lineMap, writer, comments, leadingSeparator, trailingSeparator, newLine, writeComment) {
        if (comments && comments.length > 0) {
            if (leadingSeparator) {
                writer.writeSpace(" ");
            }
            var emitInterveningSeparator = false;
            for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) {
                var comment = comments_1[_i];
                if (emitInterveningSeparator) {
                    writer.writeSpace(" ");
                    emitInterveningSeparator = false;
                }
                writeComment(text, lineMap, writer, comment.pos, comment.end, newLine);
                if (comment.hasTrailingNewLine) {
                    writer.writeLine();
                }
                else {
                    emitInterveningSeparator = true;
                }
            }
            if (emitInterveningSeparator && trailingSeparator) {
                writer.writeSpace(" ");
            }
        }
    }
    ts.emitComments = emitComments;
    /**
     * Detached comment is a comment at the top of file or function body that is separated from
     * the next statement by space.
     */
    function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) {
        var leadingComments;
        var currentDetachedCommentInfo;
        if (removeComments) {
            // removeComments is true, only reserve pinned comment at the top of file
            // For example:
            //      /*! Pinned Comment */
            //
            //      var x = 10;
            if (node.pos === 0) {
                leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal);
            }
        }
        else {
            // removeComments is false, just get detached as normal and bypass the process to filter comment
            leadingComments = ts.getLeadingCommentRanges(text, node.pos);
        }
        if (leadingComments) {
            var detachedComments = [];
            var lastComment = void 0;
            for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) {
                var comment = leadingComments_1[_i];
                if (lastComment) {
                    var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end);
                    var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos);
                    if (commentLine >= lastCommentLine + 2) {
                        // There was a blank line between the last comment and this comment.  This
                        // comment is not part of the copyright comments.  Return what we have so
                        // far.
                        break;
                    }
                }
                detachedComments.push(comment);
                lastComment = comment;
            }
            if (detachedComments.length) {
                // All comments look like they could have been part of the copyright header.  Make
                // sure there is at least one blank line between it and the node.  If not, it's not
                // a copyright header.
                var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.last(detachedComments).end);
                var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos));
                if (nodeLine >= lastCommentLine + 2) {
                    // Valid detachedComments
                    emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments);
                    emitComments(text, lineMap, writer, detachedComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment);
                    currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.last(detachedComments).end };
                }
            }
        }
        return currentDetachedCommentInfo;
        function isPinnedCommentLocal(comment) {
            return isPinnedComment(text, comment.pos);
        }
    }
    ts.emitDetachedComments = emitDetachedComments;
    function writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine) {
        if (text.charCodeAt(commentPos + 1) === 42 /* asterisk */) {
            var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, commentPos);
            var lineCount = lineMap.length;
            var firstCommentLineIndent = void 0;
            for (var pos = commentPos, currentLine = firstCommentLineAndCharacter.line; pos < commentEnd; currentLine++) {
                var nextLineStart = (currentLine + 1) === lineCount
                    ? text.length + 1
                    : lineMap[currentLine + 1];
                if (pos !== commentPos) {
                    // If we are not emitting first line, we need to write the spaces to adjust the alignment
                    if (firstCommentLineIndent === undefined) {
                        firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], commentPos);
                    }
                    // These are number of spaces writer is going to write at current indent
                    var currentWriterIndentSpacing = writer.getIndent() * getIndentSize();
                    // Number of spaces we want to be writing
                    // eg: Assume writer indent
                    // module m {
                    //         /* starts at character 9 this is line 1
                    //    * starts at character pos 4 line                        --1  = 8 - 8 + 3
                    //   More left indented comment */                            --2  = 8 - 8 + 2
                    //     class c { }
                    // }
                    // module m {
                    //     /* this is line 1 -- Assume current writer indent 8
                    //      * line                                                --3 = 8 - 4 + 5
                    //            More right indented comment */                  --4 = 8 - 4 + 11
                    //     class c { }
                    // }
                    var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart);
                    if (spacesToEmit > 0) {
                        var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize();
                        var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize());
                        // Write indent size string ( in eg 1: = "", 2: "" , 3: string with 8 spaces 4: string with 12 spaces
                        writer.rawWrite(indentSizeSpaceString);
                        // Emit the single spaces (in eg: 1: 3 spaces, 2: 2 spaces, 3: 1 space, 4: 3 spaces)
                        while (numberOfSingleSpacesToEmit) {
                            writer.rawWrite(" ");
                            numberOfSingleSpacesToEmit--;
                        }
                    }
                    else {
                        // No spaces to emit write empty string
                        writer.rawWrite("");
                    }
                }
                // Write the comment line text
                writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart);
                pos = nextLineStart;
            }
        }
        else {
            // Single line comment of style //....
            writer.writeComment(text.substring(commentPos, commentEnd));
        }
    }
    ts.writeCommentRange = writeCommentRange;
    function writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart) {
        var end = Math.min(commentEnd, nextLineStart - 1);
        var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, "");
        if (currentLineText) {
            // trimmed forward and ending spaces text
            writer.writeComment(currentLineText);
            if (end !== commentEnd) {
                writer.writeLine();
            }
        }
        else {
            // Empty string - make sure we write empty line
            writer.rawWrite(newLine);
        }
    }
    function calculateIndent(text, pos, end) {
        var currentLineIndent = 0;
        for (; pos < end && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++) {
            if (text.charCodeAt(pos) === 9 /* tab */) {
                // Tabs = TabSize = indent size and go to next tabStop
                currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize());
            }
            else {
                // Single space
                currentLineIndent++;
            }
        }
        return currentLineIndent;
    }
    function hasModifiers(node) {
        return getModifierFlags(node) !== 0 /* None */;
    }
    ts.hasModifiers = hasModifiers;
    function hasModifier(node, flags) {
        return !!getSelectedModifierFlags(node, flags);
    }
    ts.hasModifier = hasModifier;
    function hasStaticModifier(node) {
        return hasModifier(node, 32 /* Static */);
    }
    ts.hasStaticModifier = hasStaticModifier;
    function hasReadonlyModifier(node) {
        return hasModifier(node, 64 /* Readonly */);
    }
    ts.hasReadonlyModifier = hasReadonlyModifier;
    function getSelectedModifierFlags(node, flags) {
        return getModifierFlags(node) & flags;
    }
    ts.getSelectedModifierFlags = getSelectedModifierFlags;
    function getModifierFlags(node) {
        if (node.kind >= 0 /* FirstToken */ && node.kind <= 152 /* LastToken */) {
            return 0 /* None */;
        }
        if (node.modifierFlagsCache & 536870912 /* HasComputedFlags */) {
            return node.modifierFlagsCache & ~536870912 /* HasComputedFlags */;
        }
        var flags = getModifierFlagsNoCache(node);
        node.modifierFlagsCache = flags | 536870912 /* HasComputedFlags */;
        return flags;
    }
    ts.getModifierFlags = getModifierFlags;
    function getModifierFlagsNoCache(node) {
        var flags = 0 /* None */;
        if (node.modifiers) {
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                flags |= modifierToFlag(modifier.kind);
            }
        }
        if (isInJSFile(node) && !!node.parent) {
            // getModifierFlagsNoCache should only be called when parent pointers are set,
            // or when !(node.flags & NodeFlags.Synthesized) && node.kind !== SyntaxKind.SourceFile)
            var tags = (ts.getJSDocPublicTag(node) ? 4 /* Public */ : 0 /* None */)
                | (ts.getJSDocPrivateTag(node) ? 8 /* Private */ : 0 /* None */)
                | (ts.getJSDocProtectedTag(node) ? 16 /* Protected */ : 0 /* None */)
                | (ts.getJSDocReadonlyTag(node) ? 64 /* Readonly */ : 0 /* None */);
            flags |= tags;
        }
        if (node.flags & 4 /* NestedNamespace */ || (node.kind === 75 /* Identifier */ && node.isInJSDocNamespace)) {
            flags |= 1 /* Export */;
        }
        return flags;
    }
    ts.getModifierFlagsNoCache = getModifierFlagsNoCache;
    function modifierToFlag(token) {
        switch (token) {
            case 120 /* StaticKeyword */: return 32 /* Static */;
            case 119 /* PublicKeyword */: return 4 /* Public */;
            case 118 /* ProtectedKeyword */: return 16 /* Protected */;
            case 117 /* PrivateKeyword */: return 8 /* Private */;
            case 122 /* AbstractKeyword */: return 128 /* Abstract */;
            case 89 /* ExportKeyword */: return 1 /* Export */;
            case 130 /* DeclareKeyword */: return 2 /* Ambient */;
            case 81 /* ConstKeyword */: return 2048 /* Const */;
            case 84 /* DefaultKeyword */: return 512 /* Default */;
            case 126 /* AsyncKeyword */: return 256 /* Async */;
            case 138 /* ReadonlyKeyword */: return 64 /* Readonly */;
        }
        return 0 /* None */;
    }
    ts.modifierToFlag = modifierToFlag;
    function isLogicalOperator(token) {
        return token === 56 /* BarBarToken */
            || token === 55 /* AmpersandAmpersandToken */
            || token === 53 /* ExclamationToken */;
    }
    ts.isLogicalOperator = isLogicalOperator;
    function isAssignmentOperator(token) {
        return token >= 62 /* FirstAssignment */ && token <= 74 /* LastAssignment */;
    }
    ts.isAssignmentOperator = isAssignmentOperator;
    /** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */
    function tryGetClassExtendingExpressionWithTypeArguments(node) {
        var cls = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
        return cls && !cls.isImplements ? cls.class : undefined;
    }
    ts.tryGetClassExtendingExpressionWithTypeArguments = tryGetClassExtendingExpressionWithTypeArguments;
    function tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node) {
        return ts.isExpressionWithTypeArguments(node)
            && ts.isHeritageClause(node.parent)
            && ts.isClassLike(node.parent.parent)
            ? { class: node.parent.parent, isImplements: node.parent.token === 113 /* ImplementsKeyword */ }
            : undefined;
    }
    ts.tryGetClassImplementingOrExtendingExpressionWithTypeArguments = tryGetClassImplementingOrExtendingExpressionWithTypeArguments;
    function isAssignmentExpression(node, excludeCompoundAssignment) {
        return ts.isBinaryExpression(node)
            && (excludeCompoundAssignment
                ? node.operatorToken.kind === 62 /* EqualsToken */
                : isAssignmentOperator(node.operatorToken.kind))
            && ts.isLeftHandSideExpression(node.left);
    }
    ts.isAssignmentExpression = isAssignmentExpression;
    function isDestructuringAssignment(node) {
        if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
            var kind = node.left.kind;
            return kind === 193 /* ObjectLiteralExpression */
                || kind === 192 /* ArrayLiteralExpression */;
        }
        return false;
    }
    ts.isDestructuringAssignment = isDestructuringAssignment;
    function isExpressionWithTypeArgumentsInClassExtendsClause(node) {
        return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
    }
    ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause;
    function isEntityNameExpression(node) {
        return node.kind === 75 /* Identifier */ || isPropertyAccessEntityNameExpression(node);
    }
    ts.isEntityNameExpression = isEntityNameExpression;
    function getFirstIdentifier(node) {
        switch (node.kind) {
            case 75 /* Identifier */:
                return node;
            case 153 /* QualifiedName */:
                do {
                    node = node.left;
                } while (node.kind !== 75 /* Identifier */);
                return node;
            case 194 /* PropertyAccessExpression */:
                do {
                    node = node.expression;
                } while (node.kind !== 75 /* Identifier */);
                return node;
        }
    }
    ts.getFirstIdentifier = getFirstIdentifier;
    function isDottedName(node) {
        return node.kind === 75 /* Identifier */ || node.kind === 104 /* ThisKeyword */ || node.kind === 102 /* SuperKeyword */ ||
            node.kind === 194 /* PropertyAccessExpression */ && isDottedName(node.expression) ||
            node.kind === 200 /* ParenthesizedExpression */ && isDottedName(node.expression);
    }
    ts.isDottedName = isDottedName;
    function isPropertyAccessEntityNameExpression(node) {
        return ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.name) && isEntityNameExpression(node.expression);
    }
    ts.isPropertyAccessEntityNameExpression = isPropertyAccessEntityNameExpression;
    function tryGetPropertyAccessOrIdentifierToString(expr) {
        if (ts.isPropertyAccessExpression(expr)) {
            var baseStr = tryGetPropertyAccessOrIdentifierToString(expr.expression);
            if (baseStr !== undefined) {
                return baseStr + "." + expr.name;
            }
        }
        else if (ts.isIdentifier(expr)) {
            return ts.unescapeLeadingUnderscores(expr.escapedText);
        }
        return undefined;
    }
    ts.tryGetPropertyAccessOrIdentifierToString = tryGetPropertyAccessOrIdentifierToString;
    function isPrototypeAccess(node) {
        return isBindableStaticAccessExpression(node) && getElementOrPropertyAccessName(node) === "prototype";
    }
    ts.isPrototypeAccess = isPrototypeAccess;
    function isRightSideOfQualifiedNameOrPropertyAccess(node) {
        return (node.parent.kind === 153 /* QualifiedName */ && node.parent.right === node) ||
            (node.parent.kind === 194 /* PropertyAccessExpression */ && node.parent.name === node);
    }
    ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess;
    function isEmptyObjectLiteral(expression) {
        return expression.kind === 193 /* ObjectLiteralExpression */ &&
            expression.properties.length === 0;
    }
    ts.isEmptyObjectLiteral = isEmptyObjectLiteral;
    function isEmptyArrayLiteral(expression) {
        return expression.kind === 192 /* ArrayLiteralExpression */ &&
            expression.elements.length === 0;
    }
    ts.isEmptyArrayLiteral = isEmptyArrayLiteral;
    function getLocalSymbolForExportDefault(symbol) {
        return isExportDefaultSymbol(symbol) ? symbol.declarations[0].localSymbol : undefined;
    }
    ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault;
    function isExportDefaultSymbol(symbol) {
        return symbol && ts.length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], 512 /* Default */);
    }
    /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */
    function tryExtractTSExtension(fileName) {
        return ts.find(ts.supportedTSExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.tryExtractTSExtension = tryExtractTSExtension;
    /**
     * Replace each instance of non-ascii characters by one, two, three, or four escape sequences
     * representing the UTF-8 encoding of the character, and return the expanded char code list.
     */
    function getExpandedCharCodes(input) {
        var output = [];
        var length = input.length;
        for (var i = 0; i < length; i++) {
            var charCode = input.charCodeAt(i);
            // handle utf8
            if (charCode < 0x80) {
                output.push(charCode);
            }
            else if (charCode < 0x800) {
                output.push((charCode >> 6) | 192);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x10000) {
                output.push((charCode >> 12) | 224);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else if (charCode < 0x20000) {
                output.push((charCode >> 18) | 240);
                output.push(((charCode >> 12) & 63) | 128);
                output.push(((charCode >> 6) & 63) | 128);
                output.push((charCode & 63) | 128);
            }
            else {
                ts.Debug.assert(false, "Unexpected code point");
            }
        }
        return output;
    }
    var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    /**
     * Converts a string to a base-64 encoded ASCII string.
     */
    function convertToBase64(input) {
        var result = "";
        var charCodes = getExpandedCharCodes(input);
        var i = 0;
        var length = charCodes.length;
        var byte1, byte2, byte3, byte4;
        while (i < length) {
            // Convert every 6-bits in the input 3 character points
            // into a base64 digit
            byte1 = charCodes[i] >> 2;
            byte2 = (charCodes[i] & 3) << 4 | charCodes[i + 1] >> 4;
            byte3 = (charCodes[i + 1] & 15) << 2 | charCodes[i + 2] >> 6;
            byte4 = charCodes[i + 2] & 63;
            // We are out of characters in the input, set the extra
            // digits to 64 (padding character).
            if (i + 1 >= length) {
                byte3 = byte4 = 64;
            }
            else if (i + 2 >= length) {
                byte4 = 64;
            }
            // Write to the output
            result += base64Digits.charAt(byte1) + base64Digits.charAt(byte2) + base64Digits.charAt(byte3) + base64Digits.charAt(byte4);
            i += 3;
        }
        return result;
    }
    ts.convertToBase64 = convertToBase64;
    function getStringFromExpandedCharCodes(codes) {
        var output = "";
        var i = 0;
        var length = codes.length;
        while (i < length) {
            var charCode = codes[i];
            if (charCode < 0x80) {
                output += String.fromCharCode(charCode);
                i++;
            }
            else if ((charCode & 192) === 192) {
                var value = charCode & 63;
                i++;
                var nextCode = codes[i];
                while ((nextCode & 192) === 128) {
                    value = (value << 6) | (nextCode & 63);
                    i++;
                    nextCode = codes[i];
                }
                // `value` may be greater than 10FFFF (the maximum unicode codepoint) - JS will just make this into an invalid character for us
                output += String.fromCharCode(value);
            }
            else {
                // We don't want to kill the process when decoding fails (due to a following char byte not
                // following a leading char), so we just print the (bad) value
                output += String.fromCharCode(charCode);
                i++;
            }
        }
        return output;
    }
    function base64encode(host, input) {
        if (host && host.base64encode) {
            return host.base64encode(input);
        }
        return convertToBase64(input);
    }
    ts.base64encode = base64encode;
    function base64decode(host, input) {
        if (host && host.base64decode) {
            return host.base64decode(input);
        }
        var length = input.length;
        var expandedCharCodes = [];
        var i = 0;
        while (i < length) {
            // Stop decoding once padding characters are present
            if (input.charCodeAt(i) === base64Digits.charCodeAt(64)) {
                break;
            }
            // convert 4 input digits into three characters, ignoring padding characters at the end
            var ch1 = base64Digits.indexOf(input[i]);
            var ch2 = base64Digits.indexOf(input[i + 1]);
            var ch3 = base64Digits.indexOf(input[i + 2]);
            var ch4 = base64Digits.indexOf(input[i + 3]);
            var code1 = ((ch1 & 63) << 2) | ((ch2 >> 4) & 3);
            var code2 = ((ch2 & 15) << 4) | ((ch3 >> 2) & 15);
            var code3 = ((ch3 & 3) << 6) | (ch4 & 63);
            if (code2 === 0 && ch3 !== 0) { // code2 decoded to zero, but ch3 was padding - elide code2 and code3
                expandedCharCodes.push(code1);
            }
            else if (code3 === 0 && ch4 !== 0) { // code3 decoded to zero, but ch4 was padding, elide code3
                expandedCharCodes.push(code1, code2);
            }
            else {
                expandedCharCodes.push(code1, code2, code3);
            }
            i += 4;
        }
        return getStringFromExpandedCharCodes(expandedCharCodes);
    }
    ts.base64decode = base64decode;
    function readJson(path, host) {
        try {
            var jsonText = host.readFile(path);
            if (!jsonText)
                return {};
            var result = ts.parseConfigFileTextToJson(path, jsonText);
            if (result.error) {
                return {};
            }
            return result.config;
        }
        catch (e) {
            // gracefully handle if readFile fails or returns not JSON
            return {};
        }
    }
    ts.readJson = readJson;
    function directoryProbablyExists(directoryName, host) {
        // if host does not support 'directoryExists' assume that directory will exist
        return !host.directoryExists || host.directoryExists(directoryName);
    }
    ts.directoryProbablyExists = directoryProbablyExists;
    var carriageReturnLineFeed = "\r\n";
    var lineFeed = "\n";
    function getNewLineCharacter(options, getNewLine) {
        switch (options.newLine) {
            case 0 /* CarriageReturnLineFeed */:
                return carriageReturnLineFeed;
            case 1 /* LineFeed */:
                return lineFeed;
        }
        return getNewLine ? getNewLine() : ts.sys ? ts.sys.newLine : carriageReturnLineFeed;
    }
    ts.getNewLineCharacter = getNewLineCharacter;
    /**
     * Creates a new TextRange from the provided pos and end.
     *
     * @param pos The start position.
     * @param end The end position.
     */
    function createRange(pos, end) {
        if (end === void 0) { end = pos; }
        ts.Debug.assert(end >= pos || end === -1);
        return { pos: pos, end: end };
    }
    ts.createRange = createRange;
    /**
     * Creates a new TextRange from a provided range with a new end position.
     *
     * @param range A TextRange.
     * @param end The new end position.
     */
    function moveRangeEnd(range, end) {
        return createRange(range.pos, end);
    }
    ts.moveRangeEnd = moveRangeEnd;
    /**
     * Creates a new TextRange from a provided range with a new start position.
     *
     * @param range A TextRange.
     * @param pos The new Start position.
     */
    function moveRangePos(range, pos) {
        return createRange(pos, range.end);
    }
    ts.moveRangePos = moveRangePos;
    /**
     * Moves the start position of a range past any decorators.
     */
    function moveRangePastDecorators(node) {
        return node.decorators && node.decorators.length > 0
            ? moveRangePos(node, node.decorators.end)
            : node;
    }
    ts.moveRangePastDecorators = moveRangePastDecorators;
    /**
     * Moves the start position of a range past any decorators or modifiers.
     */
    function moveRangePastModifiers(node) {
        return node.modifiers && node.modifiers.length > 0
            ? moveRangePos(node, node.modifiers.end)
            : moveRangePastDecorators(node);
    }
    ts.moveRangePastModifiers = moveRangePastModifiers;
    /**
     * Determines whether a TextRange has the same start and end positions.
     *
     * @param range A TextRange.
     */
    function isCollapsedRange(range) {
        return range.pos === range.end;
    }
    ts.isCollapsedRange = isCollapsedRange;
    /**
     * Creates a new TextRange for a token at the provides start position.
     *
     * @param pos The start position.
     * @param token The token.
     */
    function createTokenRange(pos, token) {
        return createRange(pos, pos + ts.tokenToString(token).length);
    }
    ts.createTokenRange = createTokenRange;
    function rangeIsOnSingleLine(range, sourceFile) {
        return rangeStartIsOnSameLineAsRangeEnd(range, range, sourceFile);
    }
    ts.rangeIsOnSingleLine = rangeIsOnSingleLine;
    function rangeStartPositionsAreOnSameLine(range1, range2, sourceFile) {
        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile, /*includeComments*/ false), getStartPositionOfRange(range2, sourceFile, /*includeComments*/ false), sourceFile);
    }
    ts.rangeStartPositionsAreOnSameLine = rangeStartPositionsAreOnSameLine;
    function rangeEndPositionsAreOnSameLine(range1, range2, sourceFile) {
        return positionsAreOnSameLine(range1.end, range2.end, sourceFile);
    }
    ts.rangeEndPositionsAreOnSameLine = rangeEndPositionsAreOnSameLine;
    function rangeStartIsOnSameLineAsRangeEnd(range1, range2, sourceFile) {
        return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile, /*includeComments*/ false), range2.end, sourceFile);
    }
    ts.rangeStartIsOnSameLineAsRangeEnd = rangeStartIsOnSameLineAsRangeEnd;
    function rangeEndIsOnSameLineAsRangeStart(range1, range2, sourceFile) {
        return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile, /*includeComments*/ false), sourceFile);
    }
    ts.rangeEndIsOnSameLineAsRangeStart = rangeEndIsOnSameLineAsRangeStart;
    function getLinesBetweenRangeEndAndRangeStart(range1, range2, sourceFile, includeSecondRangeComments) {
        var range2Start = getStartPositionOfRange(range2, sourceFile, includeSecondRangeComments);
        return ts.getLinesBetweenPositions(sourceFile, range1.end, range2Start);
    }
    ts.getLinesBetweenRangeEndAndRangeStart = getLinesBetweenRangeEndAndRangeStart;
    function getLinesBetweenRangeEndPositions(range1, range2, sourceFile) {
        return ts.getLinesBetweenPositions(sourceFile, range1.end, range2.end);
    }
    ts.getLinesBetweenRangeEndPositions = getLinesBetweenRangeEndPositions;
    function isNodeArrayMultiLine(list, sourceFile) {
        return !positionsAreOnSameLine(list.pos, list.end, sourceFile);
    }
    ts.isNodeArrayMultiLine = isNodeArrayMultiLine;
    function positionsAreOnSameLine(pos1, pos2, sourceFile) {
        return ts.getLinesBetweenPositions(sourceFile, pos1, pos2) === 0;
    }
    ts.positionsAreOnSameLine = positionsAreOnSameLine;
    function getStartPositionOfRange(range, sourceFile, includeComments) {
        return positionIsSynthesized(range.pos) ? -1 : ts.skipTrivia(sourceFile.text, range.pos, /*stopAfterLineBreak*/ false, includeComments);
    }
    ts.getStartPositionOfRange = getStartPositionOfRange;
    function getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(pos, stopPos, sourceFile, includeComments) {
        var startPos = ts.skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments);
        var prevPos = getPreviousNonWhitespacePosition(startPos, stopPos, sourceFile);
        return ts.getLinesBetweenPositions(sourceFile, prevPos !== null && prevPos !== void 0 ? prevPos : stopPos, startPos);
    }
    ts.getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter = getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter;
    function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos, stopPos, sourceFile, includeComments) {
        var nextPos = ts.skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments);
        return ts.getLinesBetweenPositions(sourceFile, pos, Math.min(stopPos, nextPos));
    }
    ts.getLinesBetweenPositionAndNextNonWhitespaceCharacter = getLinesBetweenPositionAndNextNonWhitespaceCharacter;
    function getPreviousNonWhitespacePosition(pos, stopPos, sourceFile) {
        if (stopPos === void 0) { stopPos = 0; }
        while (pos-- > stopPos) {
            if (!ts.isWhiteSpaceLike(sourceFile.text.charCodeAt(pos))) {
                return pos;
            }
        }
    }
    /**
     * Determines whether a name was originally the declaration name of an enum or namespace
     * declaration.
     */
    function isDeclarationNameOfEnumOrNamespace(node) {
        var parseNode = ts.getParseTreeNode(node);
        if (parseNode) {
            switch (parseNode.parent.kind) {
                case 248 /* EnumDeclaration */:
                case 249 /* ModuleDeclaration */:
                    return parseNode === parseNode.parent.name;
            }
        }
        return false;
    }
    ts.isDeclarationNameOfEnumOrNamespace = isDeclarationNameOfEnumOrNamespace;
    function getInitializedVariables(node) {
        return ts.filter(node.declarations, isInitializedVariable);
    }
    ts.getInitializedVariables = getInitializedVariables;
    function isInitializedVariable(node) {
        return node.initializer !== undefined;
    }
    function isWatchSet(options) {
        // Firefox has Object.prototype.watch
        return options.watch && options.hasOwnProperty("watch");
    }
    ts.isWatchSet = isWatchSet;
    function closeFileWatcher(watcher) {
        watcher.close();
    }
    ts.closeFileWatcher = closeFileWatcher;
    function getCheckFlags(symbol) {
        return symbol.flags & 33554432 /* Transient */ ? symbol.checkFlags : 0;
    }
    ts.getCheckFlags = getCheckFlags;
    function getDeclarationModifierFlagsFromSymbol(s) {
        if (s.valueDeclaration) {
            var flags = ts.getCombinedModifierFlags(s.valueDeclaration);
            return s.parent && s.parent.flags & 32 /* Class */ ? flags : flags & ~28 /* AccessibilityModifier */;
        }
        if (getCheckFlags(s) & 6 /* Synthetic */) {
            var checkFlags = s.checkFlags;
            var accessModifier = checkFlags & 1024 /* ContainsPrivate */ ? 8 /* Private */ :
                checkFlags & 256 /* ContainsPublic */ ? 4 /* Public */ :
                    16 /* Protected */;
            var staticModifier = checkFlags & 2048 /* ContainsStatic */ ? 32 /* Static */ : 0;
            return accessModifier | staticModifier;
        }
        if (s.flags & 4194304 /* Prototype */) {
            return 4 /* Public */ | 32 /* Static */;
        }
        return 0;
    }
    ts.getDeclarationModifierFlagsFromSymbol = getDeclarationModifierFlagsFromSymbol;
    function skipAlias(symbol, checker) {
        return symbol.flags & 2097152 /* Alias */ ? checker.getAliasedSymbol(symbol) : symbol;
    }
    ts.skipAlias = skipAlias;
    /** See comment on `declareModuleMember` in `binder.ts`. */
    function getCombinedLocalAndExportSymbolFlags(symbol) {
        return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
    }
    ts.getCombinedLocalAndExportSymbolFlags = getCombinedLocalAndExportSymbolFlags;
    function isWriteOnlyAccess(node) {
        return accessKind(node) === 1 /* Write */;
    }
    ts.isWriteOnlyAccess = isWriteOnlyAccess;
    function isWriteAccess(node) {
        return accessKind(node) !== 0 /* Read */;
    }
    ts.isWriteAccess = isWriteAccess;
    var AccessKind;
    (function (AccessKind) {
        /** Only reads from a variable. */
        AccessKind[AccessKind["Read"] = 0] = "Read";
        /** Only writes to a variable without using the result. E.g.: `x++;`. */
        AccessKind[AccessKind["Write"] = 1] = "Write";
        /** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */
        AccessKind[AccessKind["ReadWrite"] = 2] = "ReadWrite";
    })(AccessKind || (AccessKind = {}));
    function accessKind(node) {
        var parent = node.parent;
        if (!parent)
            return 0 /* Read */;
        switch (parent.kind) {
            case 200 /* ParenthesizedExpression */:
                return accessKind(parent);
            case 208 /* PostfixUnaryExpression */:
            case 207 /* PrefixUnaryExpression */:
                var operator = parent.operator;
                return operator === 45 /* PlusPlusToken */ || operator === 46 /* MinusMinusToken */ ? writeOrReadWrite() : 0 /* Read */;
            case 209 /* BinaryExpression */:
                var _a = parent, left = _a.left, operatorToken = _a.operatorToken;
                return left === node && isAssignmentOperator(operatorToken.kind) ?
                    operatorToken.kind === 62 /* EqualsToken */ ? 1 /* Write */ : writeOrReadWrite()
                    : 0 /* Read */;
            case 194 /* PropertyAccessExpression */:
                return parent.name !== node ? 0 /* Read */ : accessKind(parent);
            case 281 /* PropertyAssignment */: {
                var parentAccess = accessKind(parent.parent);
                // In `({ x: varname }) = { x: 1 }`, the left `x` is a read, the right `x` is a write.
                return node === parent.name ? reverseAccessKind(parentAccess) : parentAccess;
            }
            case 282 /* ShorthandPropertyAssignment */:
                // Assume it's the local variable being accessed, since we don't check public properties for --noUnusedLocals.
                return node === parent.objectAssignmentInitializer ? 0 /* Read */ : accessKind(parent.parent);
            case 192 /* ArrayLiteralExpression */:
                return accessKind(parent);
            default:
                return 0 /* Read */;
        }
        function writeOrReadWrite() {
            // If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect.
            return parent.parent && skipParenthesesUp(parent.parent).kind === 226 /* ExpressionStatement */ ? 1 /* Write */ : 2 /* ReadWrite */;
        }
    }
    function reverseAccessKind(a) {
        switch (a) {
            case 0 /* Read */:
                return 1 /* Write */;
            case 1 /* Write */:
                return 0 /* Read */;
            case 2 /* ReadWrite */:
                return 2 /* ReadWrite */;
            default:
                return ts.Debug.assertNever(a);
        }
    }
    function compareDataObjects(dst, src) {
        if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) {
            return false;
        }
        for (var e in dst) {
            if (typeof dst[e] === "object") {
                if (!compareDataObjects(dst[e], src[e])) {
                    return false;
                }
            }
            else if (typeof dst[e] !== "function") {
                if (dst[e] !== src[e]) {
                    return false;
                }
            }
        }
        return true;
    }
    ts.compareDataObjects = compareDataObjects;
    /**
     * clears already present map by calling onDeleteExistingValue callback before deleting that key/value
     */
    function clearMap(map, onDeleteValue) {
        // Remove all
        map.forEach(onDeleteValue);
        map.clear();
    }
    ts.clearMap = clearMap;
    /**
     * Mutates the map with newMap such that keys in map will be same as newMap.
     */
    function mutateMapSkippingNewValues(map, newMap, options) {
        var onDeleteValue = options.onDeleteValue, onExistingValue = options.onExistingValue;
        // Needs update
        map.forEach(function (existingValue, key) {
            var valueInNewMap = newMap.get(key);
            // Not present any more in new map, remove it
            if (valueInNewMap === undefined) {
                map.delete(key);
                onDeleteValue(existingValue, key);
            }
            // If present notify about existing values
            else if (onExistingValue) {
                onExistingValue(existingValue, valueInNewMap, key);
            }
        });
    }
    ts.mutateMapSkippingNewValues = mutateMapSkippingNewValues;
    /**
     * Mutates the map with newMap such that keys in map will be same as newMap.
     */
    function mutateMap(map, newMap, options) {
        // Needs update
        mutateMapSkippingNewValues(map, newMap, options);
        var createNewValue = options.createNewValue;
        // Add new values that are not already present
        newMap.forEach(function (valueInNewMap, key) {
            if (!map.has(key)) {
                // New values
                map.set(key, createNewValue(key, valueInNewMap));
            }
        });
    }
    ts.mutateMap = mutateMap;
    // Return true if the given type is the constructor type for an abstract class
    function isAbstractConstructorType(type) {
        return !!(getObjectFlags(type) & 16 /* Anonymous */) && !!type.symbol && isAbstractConstructorSymbol(type.symbol);
    }
    ts.isAbstractConstructorType = isAbstractConstructorType;
    function isAbstractConstructorSymbol(symbol) {
        if (symbol.flags & 32 /* Class */) {
            var declaration = getClassLikeDeclarationOfSymbol(symbol);
            return !!declaration && hasModifier(declaration, 128 /* Abstract */);
        }
        return false;
    }
    ts.isAbstractConstructorSymbol = isAbstractConstructorSymbol;
    function getClassLikeDeclarationOfSymbol(symbol) {
        return ts.find(symbol.declarations, ts.isClassLike);
    }
    ts.getClassLikeDeclarationOfSymbol = getClassLikeDeclarationOfSymbol;
    function getObjectFlags(type) {
        return type.flags & 3899393 /* ObjectFlagsType */ ? type.objectFlags : 0;
    }
    ts.getObjectFlags = getObjectFlags;
    function typeHasCallOrConstructSignatures(type, checker) {
        return checker.getSignaturesOfType(type, 0 /* Call */).length !== 0 || checker.getSignaturesOfType(type, 1 /* Construct */).length !== 0;
    }
    ts.typeHasCallOrConstructSignatures = typeHasCallOrConstructSignatures;
    function forSomeAncestorDirectory(directory, callback) {
        return !!ts.forEachAncestorDirectory(directory, function (d) { return callback(d) ? true : undefined; });
    }
    ts.forSomeAncestorDirectory = forSomeAncestorDirectory;
    function isUMDExportSymbol(symbol) {
        return !!symbol && !!symbol.declarations && !!symbol.declarations[0] && ts.isNamespaceExportDeclaration(symbol.declarations[0]);
    }
    ts.isUMDExportSymbol = isUMDExportSymbol;
    function showModuleSpecifier(_a) {
        var moduleSpecifier = _a.moduleSpecifier;
        return ts.isStringLiteral(moduleSpecifier) ? moduleSpecifier.text : getTextOfNode(moduleSpecifier);
    }
    ts.showModuleSpecifier = showModuleSpecifier;
    function getLastChild(node) {
        var lastChild;
        ts.forEachChild(node, function (child) {
            if (nodeIsPresent(child))
                lastChild = child;
        }, function (children) {
            // As an optimization, jump straight to the end of the list.
            for (var i = children.length - 1; i >= 0; i--) {
                if (nodeIsPresent(children[i])) {
                    lastChild = children[i];
                    break;
                }
            }
        });
        return lastChild;
    }
    ts.getLastChild = getLastChild;
    function addToSeen(seen, key, value) {
        if (value === void 0) { value = true; }
        key = String(key);
        if (seen.has(key)) {
            return false;
        }
        seen.set(key, value);
        return true;
    }
    ts.addToSeen = addToSeen;
    function isObjectTypeDeclaration(node) {
        return ts.isClassLike(node) || ts.isInterfaceDeclaration(node) || ts.isTypeLiteralNode(node);
    }
    ts.isObjectTypeDeclaration = isObjectTypeDeclaration;
    function isTypeNodeKind(kind) {
        return (kind >= 168 /* FirstTypeNode */ && kind <= 188 /* LastTypeNode */)
            || kind === 125 /* AnyKeyword */
            || kind === 148 /* UnknownKeyword */
            || kind === 140 /* NumberKeyword */
            || kind === 151 /* BigIntKeyword */
            || kind === 141 /* ObjectKeyword */
            || kind === 128 /* BooleanKeyword */
            || kind === 143 /* StringKeyword */
            || kind === 144 /* SymbolKeyword */
            || kind === 104 /* ThisKeyword */
            || kind === 110 /* VoidKeyword */
            || kind === 146 /* UndefinedKeyword */
            || kind === 100 /* NullKeyword */
            || kind === 137 /* NeverKeyword */
            || kind === 216 /* ExpressionWithTypeArguments */
            || kind === 295 /* JSDocAllType */
            || kind === 296 /* JSDocUnknownType */
            || kind === 297 /* JSDocNullableType */
            || kind === 298 /* JSDocNonNullableType */
            || kind === 299 /* JSDocOptionalType */
            || kind === 300 /* JSDocFunctionType */
            || kind === 301 /* JSDocVariadicType */;
    }
    ts.isTypeNodeKind = isTypeNodeKind;
    function isAccessExpression(node) {
        return node.kind === 194 /* PropertyAccessExpression */ || node.kind === 195 /* ElementAccessExpression */;
    }
    ts.isAccessExpression = isAccessExpression;
    function getNameOfAccessExpression(node) {
        if (node.kind === 194 /* PropertyAccessExpression */) {
            return node.name;
        }
        ts.Debug.assert(node.kind === 195 /* ElementAccessExpression */);
        return node.argumentExpression;
    }
    ts.getNameOfAccessExpression = getNameOfAccessExpression;
    function isBundleFileTextLike(section) {
        switch (section.kind) {
            case "text" /* Text */:
            case "internal" /* Internal */:
                return true;
            default:
                return false;
        }
    }
    ts.isBundleFileTextLike = isBundleFileTextLike;
    function isNamedImportsOrExports(node) {
        return node.kind === 257 /* NamedImports */ || node.kind === 261 /* NamedExports */;
    }
    ts.isNamedImportsOrExports = isNamedImportsOrExports;
    function Symbol(flags, name) {
        this.flags = flags;
        this.escapedName = name;
        this.declarations = undefined;
        this.valueDeclaration = undefined;
        this.id = undefined;
        this.mergeId = undefined;
        this.parent = undefined;
    }
    function Type(checker, flags) {
        this.flags = flags;
        if (ts.Debug.isDebugging) {
            this.checker = checker;
        }
    }
    function Signature(checker, flags) {
        this.flags = flags;
        if (ts.Debug.isDebugging) {
            this.checker = checker;
        }
    }
    function Node(kind, pos, end) {
        this.pos = pos;
        this.end = end;
        this.kind = kind;
        this.id = 0;
        this.flags = 0 /* None */;
        this.modifierFlagsCache = 0 /* None */;
        this.transformFlags = 0 /* None */;
        this.parent = undefined;
        this.original = undefined;
    }
    function Token(kind, pos, end) {
        this.pos = pos;
        this.end = end;
        this.kind = kind;
        this.id = 0;
        this.flags = 0 /* None */;
        this.transformFlags = 0 /* None */;
        this.parent = undefined;
    }
    function Identifier(kind, pos, end) {
        this.pos = pos;
        this.end = end;
        this.kind = kind;
        this.id = 0;
        this.flags = 0 /* None */;
        this.transformFlags = 0 /* None */;
        this.parent = undefined;
        this.original = undefined;
        this.flowNode = undefined;
    }
    function SourceMapSource(fileName, text, skipTrivia) {
        this.fileName = fileName;
        this.text = text;
        this.skipTrivia = skipTrivia || (function (pos) { return pos; });
    }
    // eslint-disable-next-line prefer-const
    ts.objectAllocator = {
        getNodeConstructor: function () { return Node; },
        getTokenConstructor: function () { return Token; },
        getIdentifierConstructor: function () { return Identifier; },
        getPrivateIdentifierConstructor: function () { return Node; },
        getSourceFileConstructor: function () { return Node; },
        getSymbolConstructor: function () { return Symbol; },
        getTypeConstructor: function () { return Type; },
        getSignatureConstructor: function () { return Signature; },
        getSourceMapSourceConstructor: function () { return SourceMapSource; },
    };
    function setObjectAllocator(alloc) {
        ts.objectAllocator = alloc;
    }
    ts.setObjectAllocator = setObjectAllocator;
    function formatStringFromArgs(text, args, baseIndex) {
        if (baseIndex === void 0) { baseIndex = 0; }
        return text.replace(/{(\d+)}/g, function (_match, index) { return "" + ts.Debug.checkDefined(args[+index + baseIndex]); });
    }
    ts.formatStringFromArgs = formatStringFromArgs;
    /* @internal */
    function setLocalizedDiagnosticMessages(messages) {
        ts.localizedDiagnosticMessages = messages;
    }
    ts.setLocalizedDiagnosticMessages = setLocalizedDiagnosticMessages;
    function getLocaleSpecificMessage(message) {
        return ts.localizedDiagnosticMessages && ts.localizedDiagnosticMessages[message.key] || message.message;
    }
    ts.getLocaleSpecificMessage = getLocaleSpecificMessage;
    function createFileDiagnostic(file, start, length, message) {
        ts.Debug.assertGreaterThanOrEqual(start, 0);
        ts.Debug.assertGreaterThanOrEqual(length, 0);
        if (file) {
            ts.Debug.assertLessThanOrEqual(start, file.text.length);
            ts.Debug.assertLessThanOrEqual(start + length, file.text.length);
        }
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 4) {
            text = formatStringFromArgs(text, arguments, 4);
        }
        return {
            file: file,
            start: start,
            length: length,
            messageText: text,
            category: message.category,
            code: message.code,
            reportsUnnecessary: message.reportsUnnecessary,
        };
    }
    ts.createFileDiagnostic = createFileDiagnostic;
    function formatMessage(_dummy, message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 2) {
            text = formatStringFromArgs(text, arguments, 2);
        }
        return text;
    }
    ts.formatMessage = formatMessage;
    function createCompilerDiagnostic(message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 1) {
            text = formatStringFromArgs(text, arguments, 1);
        }
        return {
            file: undefined,
            start: undefined,
            length: undefined,
            messageText: text,
            category: message.category,
            code: message.code,
            reportsUnnecessary: message.reportsUnnecessary,
        };
    }
    ts.createCompilerDiagnostic = createCompilerDiagnostic;
    function createCompilerDiagnosticFromMessageChain(chain) {
        return {
            file: undefined,
            start: undefined,
            length: undefined,
            code: chain.code,
            category: chain.category,
            messageText: chain.next ? chain : chain.messageText,
        };
    }
    ts.createCompilerDiagnosticFromMessageChain = createCompilerDiagnosticFromMessageChain;
    function chainDiagnosticMessages(details, message) {
        var text = getLocaleSpecificMessage(message);
        if (arguments.length > 2) {
            text = formatStringFromArgs(text, arguments, 2);
        }
        return {
            messageText: text,
            category: message.category,
            code: message.code,
            next: details === undefined || Array.isArray(details) ? details : [details]
        };
    }
    ts.chainDiagnosticMessages = chainDiagnosticMessages;
    function concatenateDiagnosticMessageChains(headChain, tailChain) {
        var lastChain = headChain;
        while (lastChain.next) {
            lastChain = lastChain.next[0];
        }
        lastChain.next = [tailChain];
    }
    ts.concatenateDiagnosticMessageChains = concatenateDiagnosticMessageChains;
    function getDiagnosticFilePath(diagnostic) {
        return diagnostic.file ? diagnostic.file.path : undefined;
    }
    function compareDiagnostics(d1, d2) {
        return compareDiagnosticsSkipRelatedInformation(d1, d2) ||
            compareRelatedInformation(d1, d2) ||
            0 /* EqualTo */;
    }
    ts.compareDiagnostics = compareDiagnostics;
    function compareDiagnosticsSkipRelatedInformation(d1, d2) {
        return ts.compareStringsCaseSensitive(getDiagnosticFilePath(d1), getDiagnosticFilePath(d2)) ||
            ts.compareValues(d1.start, d2.start) ||
            ts.compareValues(d1.length, d2.length) ||
            ts.compareValues(d1.code, d2.code) ||
            compareMessageText(d1.messageText, d2.messageText) ||
            0 /* EqualTo */;
    }
    ts.compareDiagnosticsSkipRelatedInformation = compareDiagnosticsSkipRelatedInformation;
    function compareRelatedInformation(d1, d2) {
        if (!d1.relatedInformation && !d2.relatedInformation) {
            return 0 /* EqualTo */;
        }
        if (d1.relatedInformation && d2.relatedInformation) {
            return ts.compareValues(d1.relatedInformation.length, d2.relatedInformation.length) || ts.forEach(d1.relatedInformation, function (d1i, index) {
                var d2i = d2.relatedInformation[index];
                return compareDiagnostics(d1i, d2i); // EqualTo is 0, so falsy, and will cause the next item to be compared
            }) || 0 /* EqualTo */;
        }
        return d1.relatedInformation ? -1 /* LessThan */ : 1 /* GreaterThan */;
    }
    function compareMessageText(t1, t2) {
        if (typeof t1 === "string" && typeof t2 === "string") {
            return ts.compareStringsCaseSensitive(t1, t2);
        }
        else if (typeof t1 === "string") {
            return -1 /* LessThan */;
        }
        else if (typeof t2 === "string") {
            return 1 /* GreaterThan */;
        }
        var res = ts.compareStringsCaseSensitive(t1.messageText, t2.messageText);
        if (res) {
            return res;
        }
        if (!t1.next && !t2.next) {
            return 0 /* EqualTo */;
        }
        if (!t1.next) {
            return -1 /* LessThan */;
        }
        if (!t2.next) {
            return 1 /* GreaterThan */;
        }
        var len = Math.min(t1.next.length, t2.next.length);
        for (var i = 0; i < len; i++) {
            res = compareMessageText(t1.next[i], t2.next[i]);
            if (res) {
                return res;
            }
        }
        if (t1.next.length < t2.next.length) {
            return -1 /* LessThan */;
        }
        else if (t1.next.length > t2.next.length) {
            return 1 /* GreaterThan */;
        }
        return 0 /* EqualTo */;
    }
    function getEmitScriptTarget(compilerOptions) {
        return compilerOptions.target || 0 /* ES3 */;
    }
    ts.getEmitScriptTarget = getEmitScriptTarget;
    function getEmitModuleKind(compilerOptions) {
        return typeof compilerOptions.module === "number" ?
            compilerOptions.module :
            getEmitScriptTarget(compilerOptions) >= 2 /* ES2015 */ ? ts.ModuleKind.ES2015 : ts.ModuleKind.CommonJS;
    }
    ts.getEmitModuleKind = getEmitModuleKind;
    function getEmitModuleResolutionKind(compilerOptions) {
        var moduleResolution = compilerOptions.moduleResolution;
        if (moduleResolution === undefined) {
            moduleResolution = getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
        }
        return moduleResolution;
    }
    ts.getEmitModuleResolutionKind = getEmitModuleResolutionKind;
    function hasJsonModuleEmitEnabled(options) {
        switch (getEmitModuleKind(options)) {
            case ts.ModuleKind.CommonJS:
            case ts.ModuleKind.AMD:
            case ts.ModuleKind.ES2015:
            case ts.ModuleKind.ES2020:
            case ts.ModuleKind.ESNext:
                return true;
            default:
                return false;
        }
    }
    ts.hasJsonModuleEmitEnabled = hasJsonModuleEmitEnabled;
    function unreachableCodeIsError(options) {
        return options.allowUnreachableCode === false;
    }
    ts.unreachableCodeIsError = unreachableCodeIsError;
    function unusedLabelIsError(options) {
        return options.allowUnusedLabels === false;
    }
    ts.unusedLabelIsError = unusedLabelIsError;
    function getAreDeclarationMapsEnabled(options) {
        return !!(getEmitDeclarations(options) && options.declarationMap);
    }
    ts.getAreDeclarationMapsEnabled = getAreDeclarationMapsEnabled;
    function getAllowSyntheticDefaultImports(compilerOptions) {
        var moduleKind = getEmitModuleKind(compilerOptions);
        return compilerOptions.allowSyntheticDefaultImports !== undefined
            ? compilerOptions.allowSyntheticDefaultImports
            : compilerOptions.esModuleInterop ||
                moduleKind === ts.ModuleKind.System;
    }
    ts.getAllowSyntheticDefaultImports = getAllowSyntheticDefaultImports;
    function getEmitDeclarations(compilerOptions) {
        return !!(compilerOptions.declaration || compilerOptions.composite);
    }
    ts.getEmitDeclarations = getEmitDeclarations;
    function isIncrementalCompilation(options) {
        return !!(options.incremental || options.composite);
    }
    ts.isIncrementalCompilation = isIncrementalCompilation;
    function getStrictOptionValue(compilerOptions, flag) {
        return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
    }
    ts.getStrictOptionValue = getStrictOptionValue;
    function compilerOptionsAffectSemanticDiagnostics(newOptions, oldOptions) {
        return oldOptions !== newOptions &&
            ts.semanticDiagnosticsOptionDeclarations.some(function (option) { return !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)); });
    }
    ts.compilerOptionsAffectSemanticDiagnostics = compilerOptionsAffectSemanticDiagnostics;
    function compilerOptionsAffectEmit(newOptions, oldOptions) {
        return oldOptions !== newOptions &&
            ts.affectsEmitOptionDeclarations.some(function (option) { return !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)); });
    }
    ts.compilerOptionsAffectEmit = compilerOptionsAffectEmit;
    function getCompilerOptionValue(options, option) {
        return option.strictFlag ? getStrictOptionValue(options, option.name) : options[option.name];
    }
    ts.getCompilerOptionValue = getCompilerOptionValue;
    function hasZeroOrOneAsteriskCharacter(str) {
        var seenAsterisk = false;
        for (var i = 0; i < str.length; i++) {
            if (str.charCodeAt(i) === 42 /* asterisk */) {
                if (!seenAsterisk) {
                    seenAsterisk = true;
                }
                else {
                    // have already seen asterisk
                    return false;
                }
            }
        }
        return true;
    }
    ts.hasZeroOrOneAsteriskCharacter = hasZeroOrOneAsteriskCharacter;
    function discoverProbableSymlinks(files, getCanonicalFileName, cwd) {
        var result = ts.createMap();
        var symlinks = ts.flatten(ts.mapDefined(files, function (sf) {
            return sf.resolvedModules && ts.compact(ts.arrayFrom(ts.mapIterator(sf.resolvedModules.values(), function (res) {
                return res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined;
            })));
        }));
        for (var _i = 0, symlinks_1 = symlinks; _i < symlinks_1.length; _i++) {
            var _a = symlinks_1[_i], resolvedPath = _a[0], originalPath = _a[1];
            var _b = guessDirectorySymlink(resolvedPath, originalPath, cwd, getCanonicalFileName), commonResolved = _b[0], commonOriginal = _b[1];
            result.set(commonOriginal, commonResolved);
        }
        return result;
    }
    ts.discoverProbableSymlinks = discoverProbableSymlinks;
    function guessDirectorySymlink(a, b, cwd, getCanonicalFileName) {
        var aParts = ts.getPathComponents(ts.toPath(a, cwd, getCanonicalFileName));
        var bParts = ts.getPathComponents(ts.toPath(b, cwd, getCanonicalFileName));
        while (!isNodeModulesOrScopedPackageDirectory(aParts[aParts.length - 2], getCanonicalFileName) &&
            !isNodeModulesOrScopedPackageDirectory(bParts[bParts.length - 2], getCanonicalFileName) &&
            getCanonicalFileName(aParts[aParts.length - 1]) === getCanonicalFileName(bParts[bParts.length - 1])) {
            aParts.pop();
            bParts.pop();
        }
        return [ts.getPathFromPathComponents(aParts), ts.getPathFromPathComponents(bParts)];
    }
    // KLUDGE: Don't assume one 'node_modules' links to another. More likely a single directory inside the node_modules is the symlink.
    // ALso, don't assume that an `@foo` directory is linked. More likely the contents of that are linked.
    function isNodeModulesOrScopedPackageDirectory(s, getCanonicalFileName) {
        return getCanonicalFileName(s) === "node_modules" || ts.startsWith(s, "@");
    }
    function stripLeadingDirectorySeparator(s) {
        return ts.isAnyDirectorySeparator(s.charCodeAt(0)) ? s.slice(1) : undefined;
    }
    function tryRemoveDirectoryPrefix(path, dirPath, getCanonicalFileName) {
        var withoutPrefix = ts.tryRemovePrefix(path, dirPath, getCanonicalFileName);
        return withoutPrefix === undefined ? undefined : stripLeadingDirectorySeparator(withoutPrefix);
    }
    ts.tryRemoveDirectoryPrefix = tryRemoveDirectoryPrefix;
    // Reserved characters, forces escaping of any non-word (or digit), non-whitespace character.
    // It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future
    // proof.
    var reservedCharacterPattern = /[^\w\s\/]/g;
    function regExpEscape(text) {
        return text.replace(reservedCharacterPattern, escapeRegExpCharacter);
    }
    ts.regExpEscape = regExpEscape;
    function escapeRegExpCharacter(match) {
        return "\\" + match;
    }
    var wildcardCharCodes = [42 /* asterisk */, 63 /* question */];
    ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"];
    var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))";
    var filesMatcher = {
        /**
         * Matches any single directory segment unless it is the last segment and a .min.js file
         * Breakdown:
         *  [^./]                   # matches everything up to the first . character (excluding directory separators)
         *  (\\.(?!min\\.js$))?     # matches . characters but not if they are part of the .min.js file extension
         */
        singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*",
        /**
         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
         * files or directories, does not match subdirectories that start with a . character
         */
        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); }
    };
    var directoriesMatcher = {
        singleAsteriskRegexFragment: "[^/]*",
        /**
         * Regex for the ** wildcard. Matches any number of subdirectories. When used for including
         * files or directories, does not match subdirectories that start with a . character
         */
        doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); }
    };
    var excludeMatcher = {
        singleAsteriskRegexFragment: "[^/]*",
        doubleAsteriskRegexFragment: "(/.+?)?",
        replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); }
    };
    var wildcardMatchers = {
        files: filesMatcher,
        directories: directoriesMatcher,
        exclude: excludeMatcher
    };
    function getRegularExpressionForWildcard(specs, basePath, usage) {
        var patterns = getRegularExpressionsForWildcards(specs, basePath, usage);
        if (!patterns || !patterns.length) {
            return undefined;
        }
        var pattern = patterns.map(function (pattern) { return "(" + pattern + ")"; }).join("|");
        // If excluding, match "foo/bar/baz...", but if including, only allow "foo".
        var terminator = usage === "exclude" ? "($|/)" : "$";
        return "^(" + pattern + ")" + terminator;
    }
    ts.getRegularExpressionForWildcard = getRegularExpressionForWildcard;
    function getRegularExpressionsForWildcards(specs, basePath, usage) {
        if (specs === undefined || specs.length === 0) {
            return undefined;
        }
        return ts.flatMap(specs, function (spec) {
            return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]);
        });
    }
    ts.getRegularExpressionsForWildcards = getRegularExpressionsForWildcards;
    /**
     * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
     * and does not contain any glob characters itself.
     */
    function isImplicitGlob(lastPathComponent) {
        return !/[.*?]/.test(lastPathComponent);
    }
    ts.isImplicitGlob = isImplicitGlob;
    function getSubPatternFromSpec(spec, basePath, usage, _a) {
        var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter;
        var subpattern = "";
        var hasWrittenComponent = false;
        var components = ts.getNormalizedPathComponents(spec, basePath);
        var lastComponent = ts.last(components);
        if (usage !== "exclude" && lastComponent === "**") {
            return undefined;
        }
        // getNormalizedPathComponents includes the separator for the root component.
        // We need to remove to create our regex correctly.
        components[0] = ts.removeTrailingDirectorySeparator(components[0]);
        if (isImplicitGlob(lastComponent)) {
            components.push("**", "*");
        }
        var optionalCount = 0;
        for (var _i = 0, components_1 = components; _i < components_1.length; _i++) {
            var component = components_1[_i];
            if (component === "**") {
                subpattern += doubleAsteriskRegexFragment;
            }
            else {
                if (usage === "directories") {
                    subpattern += "(";
                    optionalCount++;
                }
                if (hasWrittenComponent) {
                    subpattern += ts.directorySeparator;
                }
                if (usage !== "exclude") {
                    var componentPattern = "";
                    // The * and ? wildcards should not match directories or files that start with . if they
                    // appear first in a component. Dotted directories and files can be included explicitly
                    // like so: **/.*/.*
                    if (component.charCodeAt(0) === 42 /* asterisk */) {
                        componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?";
                        component = component.substr(1);
                    }
                    else if (component.charCodeAt(0) === 63 /* question */) {
                        componentPattern += "[^./]";
                        component = component.substr(1);
                    }
                    componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                    // Patterns should not include subfolders like node_modules unless they are
                    // explicitly included as part of the path.
                    //
                    // As an optimization, if the component pattern is the same as the component,
                    // then there definitely were no wildcard characters and we do not need to
                    // add the exclusion pattern.
                    if (componentPattern !== component) {
                        subpattern += implicitExcludePathRegexPattern;
                    }
                    subpattern += componentPattern;
                }
                else {
                    subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
                }
            }
            hasWrittenComponent = true;
        }
        while (optionalCount > 0) {
            subpattern += ")?";
            optionalCount--;
        }
        return subpattern;
    }
    function replaceWildcardCharacter(match, singleAsteriskRegexFragment) {
        return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match;
    }
    /** @param path directory of the tsconfig.json */
    function getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory) {
        path = ts.normalizePath(path);
        currentDirectory = ts.normalizePath(currentDirectory);
        var absolutePath = ts.combinePaths(currentDirectory, path);
        return {
            includeFilePatterns: ts.map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), function (pattern) { return "^" + pattern + "$"; }),
            includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"),
            includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"),
            excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"),
            basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames)
        };
    }
    ts.getFileMatcherPatterns = getFileMatcherPatterns;
    function getRegexFromPattern(pattern, useCaseSensitiveFileNames) {
        return new RegExp(pattern, useCaseSensitiveFileNames ? "" : "i");
    }
    ts.getRegexFromPattern = getRegexFromPattern;
    /** @param path directory of the tsconfig.json */
    function matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath) {
        path = ts.normalizePath(path);
        currentDirectory = ts.normalizePath(currentDirectory);
        var patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
        var includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(function (pattern) { return getRegexFromPattern(pattern, useCaseSensitiveFileNames); });
        var includeDirectoryRegex = patterns.includeDirectoryPattern && getRegexFromPattern(patterns.includeDirectoryPattern, useCaseSensitiveFileNames);
        var excludeRegex = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, useCaseSensitiveFileNames);
        // Associate an array of results with each include regex. This keeps results in order of the "include" order.
        // If there are no "includes", then just put everything in results[0].
        var results = includeFileRegexes ? includeFileRegexes.map(function () { return []; }) : [[]];
        var visited = ts.createMap();
        var toCanonical = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        for (var _i = 0, _a = patterns.basePaths; _i < _a.length; _i++) {
            var basePath = _a[_i];
            visitDirectory(basePath, ts.combinePaths(currentDirectory, basePath), depth);
        }
        return ts.flatten(results);
        function visitDirectory(path, absolutePath, depth) {
            var canonicalPath = toCanonical(realpath(absolutePath));
            if (visited.has(canonicalPath))
                return;
            visited.set(canonicalPath, true);
            var _a = getFileSystemEntries(path), files = _a.files, directories = _a.directories;
            var _loop_1 = function (current) {
                var name = ts.combinePaths(path, current);
                var absoluteName = ts.combinePaths(absolutePath, current);
                if (extensions && !ts.fileExtensionIsOneOf(name, extensions))
                    return "continue";
                if (excludeRegex && excludeRegex.test(absoluteName))
                    return "continue";
                if (!includeFileRegexes) {
                    results[0].push(name);
                }
                else {
                    var includeIndex = ts.findIndex(includeFileRegexes, function (re) { return re.test(absoluteName); });
                    if (includeIndex !== -1) {
                        results[includeIndex].push(name);
                    }
                }
            };
            for (var _i = 0, _b = ts.sort(files, ts.compareStringsCaseSensitive); _i < _b.length; _i++) {
                var current = _b[_i];
                _loop_1(current);
            }
            if (depth !== undefined) {
                depth--;
                if (depth === 0) {
                    return;
                }
            }
            for (var _c = 0, _d = ts.sort(directories, ts.compareStringsCaseSensitive); _c < _d.length; _c++) {
                var current = _d[_c];
                var name = ts.combinePaths(path, current);
                var absoluteName = ts.combinePaths(absolutePath, current);
                if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
                    (!excludeRegex || !excludeRegex.test(absoluteName))) {
                    visitDirectory(name, absoluteName, depth);
                }
            }
        }
    }
    ts.matchFiles = matchFiles;
    /**
     * Computes the unique non-wildcard base paths amongst the provided include patterns.
     */
    function getBasePaths(path, includes, useCaseSensitiveFileNames) {
        // Storage for our results in the form of literal paths (e.g. the paths as written by the user).
        var basePaths = [path];
        if (includes) {
            // Storage for literal base paths amongst the include patterns.
            var includeBasePaths = [];
            for (var _i = 0, includes_1 = includes; _i < includes_1.length; _i++) {
                var include = includes_1[_i];
                // We also need to check the relative paths by converting them to absolute and normalizing
                // in case they escape the base path (e.g "..\somedirectory")
                var absolute = ts.isRootedDiskPath(include) ? include : ts.normalizePath(ts.combinePaths(path, include));
                // Append the literal and canonical candidate base paths.
                includeBasePaths.push(getIncludeBasePath(absolute));
            }
            // Sort the offsets array using either the literal or canonical path representations.
            includeBasePaths.sort(ts.getStringComparer(!useCaseSensitiveFileNames));
            var _loop_2 = function (includeBasePath) {
                if (ts.every(basePaths, function (basePath) { return !ts.containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames); })) {
                    basePaths.push(includeBasePath);
                }
            };
            // Iterate over each include base path and include unique base paths that are not a
            // subpath of an existing base path
            for (var _a = 0, includeBasePaths_1 = includeBasePaths; _a < includeBasePaths_1.length; _a++) {
                var includeBasePath = includeBasePaths_1[_a];
                _loop_2(includeBasePath);
            }
        }
        return basePaths;
    }
    function getIncludeBasePath(absolute) {
        var wildcardOffset = ts.indexOfAnyCharCode(absolute, wildcardCharCodes);
        if (wildcardOffset < 0) {
            // No "*" or "?" in the path
            return !ts.hasExtension(absolute)
                ? absolute
                : ts.removeTrailingDirectorySeparator(ts.getDirectoryPath(absolute));
        }
        return absolute.substring(0, absolute.lastIndexOf(ts.directorySeparator, wildcardOffset));
    }
    function ensureScriptKind(fileName, scriptKind) {
        // Using scriptKind as a condition handles both:
        // - 'scriptKind' is unspecified and thus it is `undefined`
        // - 'scriptKind' is set and it is `Unknown` (0)
        // If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt
        // to get the ScriptKind from the file name. If it cannot be resolved
        // from the file name then the default 'TS' script kind is returned.
        return scriptKind || getScriptKindFromFileName(fileName) || 3 /* TS */;
    }
    ts.ensureScriptKind = ensureScriptKind;
    function getScriptKindFromFileName(fileName) {
        var ext = fileName.substr(fileName.lastIndexOf("."));
        switch (ext.toLowerCase()) {
            case ".js" /* Js */:
                return 1 /* JS */;
            case ".jsx" /* Jsx */:
                return 2 /* JSX */;
            case ".ts" /* Ts */:
                return 3 /* TS */;
            case ".tsx" /* Tsx */:
                return 4 /* TSX */;
            case ".json" /* Json */:
                return 6 /* JSON */;
            default:
                return 0 /* Unknown */;
        }
    }
    ts.getScriptKindFromFileName = getScriptKindFromFileName;
    /**
     *  List of supported extensions in order of file resolution precedence.
     */
    ts.supportedTSExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */];
    ts.supportedTSExtensionsWithJson = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */, ".json" /* Json */];
    /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
    ts.supportedTSExtensionsForExtractExtension = [".d.ts" /* Dts */, ".ts" /* Ts */, ".tsx" /* Tsx */];
    ts.supportedJSExtensions = [".js" /* Js */, ".jsx" /* Jsx */];
    ts.supportedJSAndJsonExtensions = [".js" /* Js */, ".jsx" /* Jsx */, ".json" /* Json */];
    var allSupportedExtensions = __spreadArrays(ts.supportedTSExtensions, ts.supportedJSExtensions);
    var allSupportedExtensionsWithJson = __spreadArrays(ts.supportedTSExtensions, ts.supportedJSExtensions, [".json" /* Json */]);
    function getSupportedExtensions(options, extraFileExtensions) {
        var needJsExtensions = options && options.allowJs;
        if (!extraFileExtensions || extraFileExtensions.length === 0) {
            return needJsExtensions ? allSupportedExtensions : ts.supportedTSExtensions;
        }
        var extensions = __spreadArrays(needJsExtensions ? allSupportedExtensions : ts.supportedTSExtensions, ts.mapDefined(extraFileExtensions, function (x) { return x.scriptKind === 7 /* Deferred */ || needJsExtensions && isJSLike(x.scriptKind) ? x.extension : undefined; }));
        return ts.deduplicate(extensions, ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive);
    }
    ts.getSupportedExtensions = getSupportedExtensions;
    function getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions) {
        if (!options || !options.resolveJsonModule) {
            return supportedExtensions;
        }
        if (supportedExtensions === allSupportedExtensions) {
            return allSupportedExtensionsWithJson;
        }
        if (supportedExtensions === ts.supportedTSExtensions) {
            return ts.supportedTSExtensionsWithJson;
        }
        return __spreadArrays(supportedExtensions, [".json" /* Json */]);
    }
    ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule;
    function isJSLike(scriptKind) {
        return scriptKind === 1 /* JS */ || scriptKind === 2 /* JSX */;
    }
    function hasJSFileExtension(fileName) {
        return ts.some(ts.supportedJSExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.hasJSFileExtension = hasJSFileExtension;
    function hasTSFileExtension(fileName) {
        return ts.some(ts.supportedTSExtensions, function (extension) { return ts.fileExtensionIs(fileName, extension); });
    }
    ts.hasTSFileExtension = hasTSFileExtension;
    function isSupportedSourceFileName(fileName, compilerOptions, extraFileExtensions) {
        if (!fileName) {
            return false;
        }
        var supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions);
        for (var _i = 0, _a = getSuppoertedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions); _i < _a.length; _i++) {
            var extension = _a[_i];
            if (ts.fileExtensionIs(fileName, extension)) {
                return true;
            }
        }
        return false;
    }
    ts.isSupportedSourceFileName = isSupportedSourceFileName;
    /**
     * Extension boundaries by priority. Lower numbers indicate higher priorities, and are
     * aligned to the offset of the highest priority extension in the
     * allSupportedExtensions array.
     */
    var ExtensionPriority;
    (function (ExtensionPriority) {
        ExtensionPriority[ExtensionPriority["TypeScriptFiles"] = 0] = "TypeScriptFiles";
        ExtensionPriority[ExtensionPriority["DeclarationAndJavaScriptFiles"] = 2] = "DeclarationAndJavaScriptFiles";
        ExtensionPriority[ExtensionPriority["Highest"] = 0] = "Highest";
        ExtensionPriority[ExtensionPriority["Lowest"] = 2] = "Lowest";
    })(ExtensionPriority = ts.ExtensionPriority || (ts.ExtensionPriority = {}));
    function getExtensionPriority(path, supportedExtensions) {
        for (var i = supportedExtensions.length - 1; i >= 0; i--) {
            if (ts.fileExtensionIs(path, supportedExtensions[i])) {
                return adjustExtensionPriority(i, supportedExtensions);
            }
        }
        // If its not in the list of supported extensions, this is likely a
        // TypeScript file with a non-ts extension
        return 0 /* Highest */;
    }
    ts.getExtensionPriority = getExtensionPriority;
    /**
     * Adjusts an extension priority to be the highest priority within the same range.
     */
    function adjustExtensionPriority(extensionPriority, supportedExtensions) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 0 /* TypeScriptFiles */;
        }
        else if (extensionPriority < supportedExtensions.length) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return supportedExtensions.length;
        }
    }
    ts.adjustExtensionPriority = adjustExtensionPriority;
    /**
     * Gets the next lowest extension priority for a given priority.
     */
    function getNextLowestExtensionPriority(extensionPriority, supportedExtensions) {
        if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) {
            return 2 /* DeclarationAndJavaScriptFiles */;
        }
        else {
            return supportedExtensions.length;
        }
    }
    ts.getNextLowestExtensionPriority = getNextLowestExtensionPriority;
    var extensionsToRemove = [".d.ts" /* Dts */, ".ts" /* Ts */, ".js" /* Js */, ".tsx" /* Tsx */, ".jsx" /* Jsx */, ".json" /* Json */];
    function removeFileExtension(path) {
        for (var _i = 0, extensionsToRemove_1 = extensionsToRemove; _i < extensionsToRemove_1.length; _i++) {
            var ext = extensionsToRemove_1[_i];
            var extensionless = tryRemoveExtension(path, ext);
            if (extensionless !== undefined) {
                return extensionless;
            }
        }
        return path;
    }
    ts.removeFileExtension = removeFileExtension;
    function tryRemoveExtension(path, extension) {
        return ts.fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined;
    }
    ts.tryRemoveExtension = tryRemoveExtension;
    function removeExtension(path, extension) {
        return path.substring(0, path.length - extension.length);
    }
    ts.removeExtension = removeExtension;
    function changeExtension(path, newExtension) {
        return ts.changeAnyExtension(path, newExtension, extensionsToRemove, /*ignoreCase*/ false);
    }
    ts.changeExtension = changeExtension;
    function tryParsePattern(pattern) {
        // This should be verified outside of here and a proper error thrown.
        ts.Debug.assert(hasZeroOrOneAsteriskCharacter(pattern));
        var indexOfStar = pattern.indexOf("*");
        return indexOfStar === -1 ? undefined : {
            prefix: pattern.substr(0, indexOfStar),
            suffix: pattern.substr(indexOfStar + 1)
        };
    }
    ts.tryParsePattern = tryParsePattern;
    function positionIsSynthesized(pos) {
        // This is a fast way of testing the following conditions:
        //  pos === undefined || pos === null || isNaN(pos) || pos < 0;
        return !(pos >= 0);
    }
    ts.positionIsSynthesized = positionIsSynthesized;
    /** True if an extension is one of the supported TypeScript extensions. */
    function extensionIsTS(ext) {
        return ext === ".ts" /* Ts */ || ext === ".tsx" /* Tsx */ || ext === ".d.ts" /* Dts */;
    }
    ts.extensionIsTS = extensionIsTS;
    function resolutionExtensionIsTSOrJson(ext) {
        return extensionIsTS(ext) || ext === ".json" /* Json */;
    }
    ts.resolutionExtensionIsTSOrJson = resolutionExtensionIsTSOrJson;
    /**
     * Gets the extension from a path.
     * Path must have a valid extension.
     */
    function extensionFromPath(path) {
        var ext = tryGetExtensionFromPath(path);
        return ext !== undefined ? ext : ts.Debug.fail("File " + path + " has unknown extension.");
    }
    ts.extensionFromPath = extensionFromPath;
    function isAnySupportedFileExtension(path) {
        return tryGetExtensionFromPath(path) !== undefined;
    }
    ts.isAnySupportedFileExtension = isAnySupportedFileExtension;
    function tryGetExtensionFromPath(path) {
        return ts.find(extensionsToRemove, function (e) { return ts.fileExtensionIs(path, e); });
    }
    ts.tryGetExtensionFromPath = tryGetExtensionFromPath;
    function isCheckJsEnabledForFile(sourceFile, compilerOptions) {
        return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
    }
    ts.isCheckJsEnabledForFile = isCheckJsEnabledForFile;
    ts.emptyFileSystemEntries = {
        files: ts.emptyArray,
        directories: ts.emptyArray
    };
    /**
     * patternStrings contains both pattern strings (containing "*") and regular strings.
     * Return an exact match if possible, or a pattern match, or undefined.
     * (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
     */
    function matchPatternOrExact(patternStrings, candidate) {
        var patterns = [];
        for (var _i = 0, patternStrings_1 = patternStrings; _i < patternStrings_1.length; _i++) {
            var patternString = patternStrings_1[_i];
            if (!hasZeroOrOneAsteriskCharacter(patternString))
                continue;
            var pattern = tryParsePattern(patternString);
            if (pattern) {
                patterns.push(pattern);
            }
            else if (patternString === candidate) {
                // pattern was matched as is - no need to search further
                return patternString;
            }
        }
        return ts.findBestPatternMatch(patterns, function (_) { return _; }, candidate);
    }
    ts.matchPatternOrExact = matchPatternOrExact;
    function sliceAfter(arr, value) {
        var index = arr.indexOf(value);
        ts.Debug.assert(index !== -1);
        return arr.slice(index);
    }
    ts.sliceAfter = sliceAfter;
    function addRelatedInfo(diagnostic) {
        var _a;
        var relatedInformation = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            relatedInformation[_i - 1] = arguments[_i];
        }
        if (!relatedInformation.length) {
            return diagnostic;
        }
        if (!diagnostic.relatedInformation) {
            diagnostic.relatedInformation = [];
        }
        (_a = diagnostic.relatedInformation).push.apply(_a, relatedInformation);
        return diagnostic;
    }
    ts.addRelatedInfo = addRelatedInfo;
    function minAndMax(arr, getValue) {
        ts.Debug.assert(arr.length !== 0);
        var min = getValue(arr[0]);
        var max = min;
        for (var i = 1; i < arr.length; i++) {
            var value = getValue(arr[i]);
            if (value < min) {
                min = value;
            }
            else if (value > max) {
                max = value;
            }
        }
        return { min: min, max: max };
    }
    ts.minAndMax = minAndMax;
    var NodeSet = /** @class */ (function () {
        function NodeSet() {
            this.map = ts.createMap();
        }
        NodeSet.prototype.add = function (node) {
            this.map.set(String(ts.getNodeId(node)), node);
        };
        NodeSet.prototype.tryAdd = function (node) {
            if (this.has(node))
                return false;
            this.add(node);
            return true;
        };
        NodeSet.prototype.has = function (node) {
            return this.map.has(String(ts.getNodeId(node)));
        };
        NodeSet.prototype.forEach = function (cb) {
            this.map.forEach(cb);
        };
        NodeSet.prototype.some = function (pred) {
            return forEachEntry(this.map, pred) || false;
        };
        return NodeSet;
    }());
    ts.NodeSet = NodeSet;
    var NodeMap = /** @class */ (function () {
        function NodeMap() {
            this.map = ts.createMap();
        }
        NodeMap.prototype.get = function (node) {
            var res = this.map.get(String(ts.getNodeId(node)));
            return res && res.value;
        };
        NodeMap.prototype.getOrUpdate = function (node, setValue) {
            var res = this.get(node);
            if (res)
                return res;
            var value = setValue();
            this.set(node, value);
            return value;
        };
        NodeMap.prototype.set = function (node, value) {
            this.map.set(String(ts.getNodeId(node)), { node: node, value: value });
        };
        NodeMap.prototype.has = function (node) {
            return this.map.has(String(ts.getNodeId(node)));
        };
        NodeMap.prototype.forEach = function (cb) {
            this.map.forEach(function (_a) {
                var node = _a.node, value = _a.value;
                return cb(value, node);
            });
        };
        return NodeMap;
    }());
    ts.NodeMap = NodeMap;
    function rangeOfNode(node) {
        return { pos: getTokenPosOfNode(node), end: node.end };
    }
    ts.rangeOfNode = rangeOfNode;
    function rangeOfTypeParameters(typeParameters) {
        // Include the `<>`
        return { pos: typeParameters.pos - 1, end: typeParameters.end + 1 };
    }
    ts.rangeOfTypeParameters = rangeOfTypeParameters;
    function skipTypeChecking(sourceFile, options, host) {
        // If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
        // If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
        // '/// <reference no-default-lib="true"/>' directive.
        return (options.skipLibCheck && sourceFile.isDeclarationFile ||
            options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) ||
            host.isSourceOfProjectReferenceRedirect(sourceFile.fileName);
    }
    ts.skipTypeChecking = skipTypeChecking;
    function isJsonEqual(a, b) {
        // eslint-disable-next-line no-null/no-null
        return a === b || typeof a === "object" && a !== null && typeof b === "object" && b !== null && ts.equalOwnProperties(a, b, isJsonEqual);
    }
    ts.isJsonEqual = isJsonEqual;
    function getOrUpdate(map, key, getDefault) {
        var got = map.get(key);
        if (got === undefined) {
            var value = getDefault();
            map.set(key, value);
            return value;
        }
        else {
            return got;
        }
    }
    ts.getOrUpdate = getOrUpdate;
    /**
     * Converts a bigint literal string, e.g. `0x1234n`,
     * to its decimal string representation, e.g. `4660`.
     */
    function parsePseudoBigInt(stringValue) {
        var log2Base;
        switch (stringValue.charCodeAt(1)) { // "x" in "0x123"
            case 98 /* b */:
            case 66 /* B */: // 0b or 0B
                log2Base = 1;
                break;
            case 111 /* o */:
            case 79 /* O */: // 0o or 0O
                log2Base = 3;
                break;
            case 120 /* x */:
            case 88 /* X */: // 0x or 0X
                log2Base = 4;
                break;
            default: // already in decimal; omit trailing "n"
                var nIndex = stringValue.length - 1;
                // Skip leading 0s
                var nonZeroStart = 0;
                while (stringValue.charCodeAt(nonZeroStart) === 48 /* _0 */) {
                    nonZeroStart++;
                }
                return stringValue.slice(nonZeroStart, nIndex) || "0";
        }
        // Omit leading "0b", "0o", or "0x", and trailing "n"
        var startIndex = 2, endIndex = stringValue.length - 1;
        var bitsNeeded = (endIndex - startIndex) * log2Base;
        // Stores the value specified by the string as a LE array of 16-bit integers
        // using Uint16 instead of Uint32 so combining steps can use bitwise operators
        var segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
        // Add the digits, one at a time
        for (var i = endIndex - 1, bitOffset = 0; i >= startIndex; i--, bitOffset += log2Base) {
            var segment = bitOffset >>> 4;
            var digitChar = stringValue.charCodeAt(i);
            // Find character range: 0-9 < A-F < a-f
            var digit = digitChar <= 57 /* _9 */
                ? digitChar - 48 /* _0 */
                : 10 + digitChar -
                    (digitChar <= 70 /* F */ ? 65 /* A */ : 97 /* a */);
            var shiftedDigit = digit << (bitOffset & 15);
            segments[segment] |= shiftedDigit;
            var residual = shiftedDigit >>> 16;
            if (residual)
                segments[segment + 1] |= residual; // overflows segment
        }
        // Repeatedly divide segments by 10 and add remainder to base10Value
        var base10Value = "";
        var firstNonzeroSegment = segments.length - 1;
        var segmentsRemaining = true;
        while (segmentsRemaining) {
            var mod10 = 0;
            segmentsRemaining = false;
            for (var segment = firstNonzeroSegment; segment >= 0; segment--) {
                var newSegment = mod10 << 16 | segments[segment];
                var segmentValue = (newSegment / 10) | 0;
                segments[segment] = segmentValue;
                mod10 = newSegment - segmentValue * 10;
                if (segmentValue && !segmentsRemaining) {
                    firstNonzeroSegment = segment;
                    segmentsRemaining = true;
                }
            }
            base10Value = mod10 + base10Value;
        }
        return base10Value;
    }
    ts.parsePseudoBigInt = parsePseudoBigInt;
    function pseudoBigIntToString(_a) {
        var negative = _a.negative, base10Value = _a.base10Value;
        return (negative && base10Value !== "0" ? "-" : "") + base10Value;
    }
    ts.pseudoBigIntToString = pseudoBigIntToString;
    function isValidTypeOnlyAliasUseSite(useSite) {
        return !!(useSite.flags & 8388608 /* Ambient */)
            || isPartOfTypeQuery(useSite)
            || isIdentifierInNonEmittingHeritageClause(useSite)
            || isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite)
            || !isExpressionNode(useSite);
    }
    ts.isValidTypeOnlyAliasUseSite = isValidTypeOnlyAliasUseSite;
    function typeOnlyDeclarationIsExport(typeOnlyDeclaration) {
        return typeOnlyDeclaration.kind === 263 /* ExportSpecifier */;
    }
    ts.typeOnlyDeclarationIsExport = typeOnlyDeclarationIsExport;
    function isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(node) {
        while (node.kind === 75 /* Identifier */ || node.kind === 194 /* PropertyAccessExpression */) {
            node = node.parent;
        }
        if (node.kind !== 154 /* ComputedPropertyName */) {
            return false;
        }
        if (hasModifier(node.parent, 128 /* Abstract */)) {
            return true;
        }
        var containerKind = node.parent.parent.kind;
        return containerKind === 246 /* InterfaceDeclaration */ || containerKind === 173 /* TypeLiteral */;
    }
    /** Returns true for an identifier in 1) an `implements` clause, and 2) an `extends` clause of an interface. */
    function isIdentifierInNonEmittingHeritageClause(node) {
        if (node.kind !== 75 /* Identifier */)
            return false;
        var heritageClause = findAncestor(node.parent, function (parent) {
            switch (parent.kind) {
                case 279 /* HeritageClause */:
                    return true;
                case 194 /* PropertyAccessExpression */:
                case 216 /* ExpressionWithTypeArguments */:
                    return false;
                default:
                    return "quit";
            }
        });
        return (heritageClause === null || heritageClause === void 0 ? void 0 : heritageClause.token) === 113 /* ImplementsKeyword */ || (heritageClause === null || heritageClause === void 0 ? void 0 : heritageClause.parent.kind) === 246 /* InterfaceDeclaration */;
    }
    function isIdentifierTypeReference(node) {
        return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName);
    }
    ts.isIdentifierTypeReference = isIdentifierTypeReference;
    function arrayIsHomogeneous(array, comparer) {
        if (comparer === void 0) { comparer = ts.equateValues; }
        if (array.length < 2)
            return true;
        var first = array[0];
        for (var i = 1, length_1 = array.length; i < length_1; i++) {
            var target = array[i];
            if (!comparer(first, target))
                return false;
        }
        return true;
    }
    ts.arrayIsHomogeneous = arrayIsHomogeneous;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var SignatureFlags;
    (function (SignatureFlags) {
        SignatureFlags[SignatureFlags["None"] = 0] = "None";
        SignatureFlags[SignatureFlags["Yield"] = 1] = "Yield";
        SignatureFlags[SignatureFlags["Await"] = 2] = "Await";
        SignatureFlags[SignatureFlags["Type"] = 4] = "Type";
        SignatureFlags[SignatureFlags["IgnoreMissingOpenBrace"] = 16] = "IgnoreMissingOpenBrace";
        SignatureFlags[SignatureFlags["JSDoc"] = 32] = "JSDoc";
    })(SignatureFlags || (SignatureFlags = {}));
    var NodeConstructor;
    var TokenConstructor;
    var IdentifierConstructor;
    var PrivateIdentifierConstructor;
    var SourceFileConstructor;
    function createNode(kind, pos, end) {
        if (kind === 290 /* SourceFile */) {
            return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end);
        }
        else if (kind === 75 /* Identifier */) {
            return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end);
        }
        else if (kind === 76 /* PrivateIdentifier */) {
            return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = ts.objectAllocator.getPrivateIdentifierConstructor()))(kind, pos, end);
        }
        else if (!ts.isNodeKind(kind)) {
            return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end);
        }
        else {
            return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end);
        }
    }
    ts.createNode = createNode;
    function visitNode(cbNode, node) {
        return node && cbNode(node);
    }
    function visitNodes(cbNode, cbNodes, nodes) {
        if (nodes) {
            if (cbNodes) {
                return cbNodes(nodes);
            }
            for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
                var node = nodes_1[_i];
                var result = cbNode(node);
                if (result) {
                    return result;
                }
            }
        }
    }
    /*@internal*/
    function isJSDocLikeText(text, start) {
        return text.charCodeAt(start + 1) === 42 /* asterisk */ &&
            text.charCodeAt(start + 2) === 42 /* asterisk */ &&
            text.charCodeAt(start + 3) !== 47 /* slash */;
    }
    ts.isJSDocLikeText = isJSDocLikeText;
    /**
     * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
     * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise,
     * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns
     * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
     *
     * @param node a given node to visit its children
     * @param cbNode a callback to be invoked for all child nodes
     * @param cbNodes a callback to be invoked for embedded array
     *
     * @remarks `forEachChild` must visit the children of a node in the order
     * that they appear in the source code. The language service depends on this property to locate nodes by position.
     */
    function forEachChild(node, cbNode, cbNodes) {
        if (!node || node.kind <= 152 /* LastToken */) {
            return;
        }
        switch (node.kind) {
            case 153 /* QualifiedName */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.right);
            case 155 /* TypeParameter */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.constraint) ||
                    visitNode(cbNode, node.default) ||
                    visitNode(cbNode, node.expression);
            case 282 /* ShorthandPropertyAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.equalsToken) ||
                    visitNode(cbNode, node.objectAssignmentInitializer);
            case 283 /* SpreadAssignment */:
                return visitNode(cbNode, node.expression);
            case 156 /* Parameter */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 159 /* PropertyDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 158 /* PropertySignature */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 281 /* PropertyAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.initializer);
            case 242 /* VariableDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.initializer);
            case 191 /* BindingElement */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
            case 165 /* CallSignature */:
            case 166 /* ConstructSignature */:
            case 167 /* IndexSignature */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 161 /* MethodDeclaration */:
            case 160 /* MethodSignature */:
            case 162 /* Constructor */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 201 /* FunctionExpression */:
            case 244 /* FunctionDeclaration */:
            case 202 /* ArrowFunction */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.exclamationToken) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.equalsGreaterThanToken) ||
                    visitNode(cbNode, node.body);
            case 169 /* TypeReference */:
                return visitNode(cbNode, node.typeName) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 168 /* TypePredicate */:
                return visitNode(cbNode, node.assertsModifier) ||
                    visitNode(cbNode, node.parameterName) ||
                    visitNode(cbNode, node.type);
            case 172 /* TypeQuery */:
                return visitNode(cbNode, node.exprName);
            case 173 /* TypeLiteral */:
                return visitNodes(cbNode, cbNodes, node.members);
            case 174 /* ArrayType */:
                return visitNode(cbNode, node.elementType);
            case 175 /* TupleType */:
                return visitNodes(cbNode, cbNodes, node.elementTypes);
            case 178 /* UnionType */:
            case 179 /* IntersectionType */:
                return visitNodes(cbNode, cbNodes, node.types);
            case 180 /* ConditionalType */:
                return visitNode(cbNode, node.checkType) ||
                    visitNode(cbNode, node.extendsType) ||
                    visitNode(cbNode, node.trueType) ||
                    visitNode(cbNode, node.falseType);
            case 181 /* InferType */:
                return visitNode(cbNode, node.typeParameter);
            case 188 /* ImportType */:
                return visitNode(cbNode, node.argument) ||
                    visitNode(cbNode, node.qualifier) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 182 /* ParenthesizedType */:
            case 184 /* TypeOperator */:
                return visitNode(cbNode, node.type);
            case 185 /* IndexedAccessType */:
                return visitNode(cbNode, node.objectType) ||
                    visitNode(cbNode, node.indexType);
            case 186 /* MappedType */:
                return visitNode(cbNode, node.readonlyToken) ||
                    visitNode(cbNode, node.typeParameter) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.type);
            case 187 /* LiteralType */:
                return visitNode(cbNode, node.literal);
            case 189 /* ObjectBindingPattern */:
            case 190 /* ArrayBindingPattern */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 192 /* ArrayLiteralExpression */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 193 /* ObjectLiteralExpression */:
                return visitNodes(cbNode, cbNodes, node.properties);
            case 194 /* PropertyAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.questionDotToken) ||
                    visitNode(cbNode, node.name);
            case 195 /* ElementAccessExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.questionDotToken) ||
                    visitNode(cbNode, node.argumentExpression);
            case 196 /* CallExpression */:
            case 197 /* NewExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.questionDotToken) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNodes(cbNode, cbNodes, node.arguments);
            case 198 /* TaggedTemplateExpression */:
                return visitNode(cbNode, node.tag) ||
                    visitNode(cbNode, node.questionDotToken) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNode(cbNode, node.template);
            case 199 /* TypeAssertionExpression */:
                return visitNode(cbNode, node.type) ||
                    visitNode(cbNode, node.expression);
            case 200 /* ParenthesizedExpression */:
                return visitNode(cbNode, node.expression);
            case 203 /* DeleteExpression */:
                return visitNode(cbNode, node.expression);
            case 204 /* TypeOfExpression */:
                return visitNode(cbNode, node.expression);
            case 205 /* VoidExpression */:
                return visitNode(cbNode, node.expression);
            case 207 /* PrefixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 212 /* YieldExpression */:
                return visitNode(cbNode, node.asteriskToken) ||
                    visitNode(cbNode, node.expression);
            case 206 /* AwaitExpression */:
                return visitNode(cbNode, node.expression);
            case 208 /* PostfixUnaryExpression */:
                return visitNode(cbNode, node.operand);
            case 209 /* BinaryExpression */:
                return visitNode(cbNode, node.left) ||
                    visitNode(cbNode, node.operatorToken) ||
                    visitNode(cbNode, node.right);
            case 217 /* AsExpression */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.type);
            case 218 /* NonNullExpression */:
                return visitNode(cbNode, node.expression);
            case 219 /* MetaProperty */:
                return visitNode(cbNode, node.name);
            case 210 /* ConditionalExpression */:
                return visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.questionToken) ||
                    visitNode(cbNode, node.whenTrue) ||
                    visitNode(cbNode, node.colonToken) ||
                    visitNode(cbNode, node.whenFalse);
            case 213 /* SpreadElement */:
                return visitNode(cbNode, node.expression);
            case 223 /* Block */:
            case 250 /* ModuleBlock */:
                return visitNodes(cbNode, cbNodes, node.statements);
            case 290 /* SourceFile */:
                return visitNodes(cbNode, cbNodes, node.statements) ||
                    visitNode(cbNode, node.endOfFileToken);
            case 225 /* VariableStatement */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.declarationList);
            case 243 /* VariableDeclarationList */:
                return visitNodes(cbNode, cbNodes, node.declarations);
            case 226 /* ExpressionStatement */:
                return visitNode(cbNode, node.expression);
            case 227 /* IfStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.thenStatement) ||
                    visitNode(cbNode, node.elseStatement);
            case 228 /* DoStatement */:
                return visitNode(cbNode, node.statement) ||
                    visitNode(cbNode, node.expression);
            case 229 /* WhileStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 230 /* ForStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.condition) ||
                    visitNode(cbNode, node.incrementor) ||
                    visitNode(cbNode, node.statement);
            case 231 /* ForInStatement */:
                return visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 232 /* ForOfStatement */:
                return visitNode(cbNode, node.awaitModifier) ||
                    visitNode(cbNode, node.initializer) ||
                    visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 233 /* ContinueStatement */:
            case 234 /* BreakStatement */:
                return visitNode(cbNode, node.label);
            case 235 /* ReturnStatement */:
                return visitNode(cbNode, node.expression);
            case 236 /* WithStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.statement);
            case 237 /* SwitchStatement */:
                return visitNode(cbNode, node.expression) ||
                    visitNode(cbNode, node.caseBlock);
            case 251 /* CaseBlock */:
                return visitNodes(cbNode, cbNodes, node.clauses);
            case 277 /* CaseClause */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.statements);
            case 278 /* DefaultClause */:
                return visitNodes(cbNode, cbNodes, node.statements);
            case 238 /* LabeledStatement */:
                return visitNode(cbNode, node.label) ||
                    visitNode(cbNode, node.statement);
            case 239 /* ThrowStatement */:
                return visitNode(cbNode, node.expression);
            case 240 /* TryStatement */:
                return visitNode(cbNode, node.tryBlock) ||
                    visitNode(cbNode, node.catchClause) ||
                    visitNode(cbNode, node.finallyBlock);
            case 280 /* CatchClause */:
                return visitNode(cbNode, node.variableDeclaration) ||
                    visitNode(cbNode, node.block);
            case 157 /* Decorator */:
                return visitNode(cbNode, node.expression);
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 246 /* InterfaceDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNodes(cbNode, cbNodes, node.heritageClauses) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 247 /* TypeAliasDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters) ||
                    visitNode(cbNode, node.type);
            case 248 /* EnumDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNodes(cbNode, cbNodes, node.members);
            case 284 /* EnumMember */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 249 /* ModuleDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.body);
            case 253 /* ImportEqualsDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.moduleReference);
            case 254 /* ImportDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.importClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 255 /* ImportClause */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.namedBindings);
            case 252 /* NamespaceExportDeclaration */:
                return visitNode(cbNode, node.name);
            case 256 /* NamespaceImport */:
                return visitNode(cbNode, node.name);
            case 262 /* NamespaceExport */:
                return visitNode(cbNode, node.name);
            case 257 /* NamedImports */:
            case 261 /* NamedExports */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 260 /* ExportDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.exportClause) ||
                    visitNode(cbNode, node.moduleSpecifier);
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
                return visitNode(cbNode, node.propertyName) ||
                    visitNode(cbNode, node.name);
            case 259 /* ExportAssignment */:
                return visitNodes(cbNode, cbNodes, node.decorators) ||
                    visitNodes(cbNode, cbNodes, node.modifiers) ||
                    visitNode(cbNode, node.expression);
            case 211 /* TemplateExpression */:
                return visitNode(cbNode, node.head) || visitNodes(cbNode, cbNodes, node.templateSpans);
            case 221 /* TemplateSpan */:
                return visitNode(cbNode, node.expression) || visitNode(cbNode, node.literal);
            case 154 /* ComputedPropertyName */:
                return visitNode(cbNode, node.expression);
            case 279 /* HeritageClause */:
                return visitNodes(cbNode, cbNodes, node.types);
            case 216 /* ExpressionWithTypeArguments */:
                return visitNode(cbNode, node.expression) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments);
            case 265 /* ExternalModuleReference */:
                return visitNode(cbNode, node.expression);
            case 264 /* MissingDeclaration */:
                return visitNodes(cbNode, cbNodes, node.decorators);
            case 327 /* CommaListExpression */:
                return visitNodes(cbNode, cbNodes, node.elements);
            case 266 /* JsxElement */:
                return visitNode(cbNode, node.openingElement) ||
                    visitNodes(cbNode, cbNodes, node.children) ||
                    visitNode(cbNode, node.closingElement);
            case 270 /* JsxFragment */:
                return visitNode(cbNode, node.openingFragment) ||
                    visitNodes(cbNode, cbNodes, node.children) ||
                    visitNode(cbNode, node.closingFragment);
            case 267 /* JsxSelfClosingElement */:
            case 268 /* JsxOpeningElement */:
                return visitNode(cbNode, node.tagName) ||
                    visitNodes(cbNode, cbNodes, node.typeArguments) ||
                    visitNode(cbNode, node.attributes);
            case 274 /* JsxAttributes */:
                return visitNodes(cbNode, cbNodes, node.properties);
            case 273 /* JsxAttribute */:
                return visitNode(cbNode, node.name) ||
                    visitNode(cbNode, node.initializer);
            case 275 /* JsxSpreadAttribute */:
                return visitNode(cbNode, node.expression);
            case 276 /* JsxExpression */:
                return visitNode(cbNode, node.dotDotDotToken) ||
                    visitNode(cbNode, node.expression);
            case 269 /* JsxClosingElement */:
                return visitNode(cbNode, node.tagName);
            case 176 /* OptionalType */:
            case 177 /* RestType */:
            case 294 /* JSDocTypeExpression */:
            case 298 /* JSDocNonNullableType */:
            case 297 /* JSDocNullableType */:
            case 299 /* JSDocOptionalType */:
            case 301 /* JSDocVariadicType */:
                return visitNode(cbNode, node.type);
            case 300 /* JSDocFunctionType */:
                return visitNodes(cbNode, cbNodes, node.parameters) ||
                    visitNode(cbNode, node.type);
            case 303 /* JSDocComment */:
                return visitNodes(cbNode, cbNodes, node.tags);
            case 317 /* JSDocParameterTag */:
            case 323 /* JSDocPropertyTag */:
                return visitNode(cbNode, node.tagName) ||
                    (node.isNameFirst
                        ? visitNode(cbNode, node.name) ||
                            visitNode(cbNode, node.typeExpression)
                        : visitNode(cbNode, node.typeExpression) ||
                            visitNode(cbNode, node.name));
            case 309 /* JSDocAuthorTag */:
                return visitNode(cbNode, node.tagName);
            case 308 /* JSDocImplementsTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.class);
            case 307 /* JSDocAugmentsTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.class);
            case 321 /* JSDocTemplateTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.constraint) ||
                    visitNodes(cbNode, cbNodes, node.typeParameters);
            case 322 /* JSDocTypedefTag */:
                return visitNode(cbNode, node.tagName) ||
                    (node.typeExpression &&
                        node.typeExpression.kind === 294 /* JSDocTypeExpression */
                        ? visitNode(cbNode, node.typeExpression) ||
                            visitNode(cbNode, node.fullName)
                        : visitNode(cbNode, node.fullName) ||
                            visitNode(cbNode, node.typeExpression));
            case 315 /* JSDocCallbackTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.fullName) ||
                    visitNode(cbNode, node.typeExpression);
            case 318 /* JSDocReturnTag */:
            case 320 /* JSDocTypeTag */:
            case 319 /* JSDocThisTag */:
            case 316 /* JSDocEnumTag */:
                return visitNode(cbNode, node.tagName) ||
                    visitNode(cbNode, node.typeExpression);
            case 305 /* JSDocSignature */:
                return ts.forEach(node.typeParameters, cbNode) ||
                    ts.forEach(node.parameters, cbNode) ||
                    visitNode(cbNode, node.type);
            case 304 /* JSDocTypeLiteral */:
                return ts.forEach(node.jsDocPropertyTags, cbNode);
            case 306 /* JSDocTag */:
            case 310 /* JSDocClassTag */:
            case 311 /* JSDocPublicTag */:
            case 312 /* JSDocPrivateTag */:
            case 313 /* JSDocProtectedTag */:
            case 314 /* JSDocReadonlyTag */:
                return visitNode(cbNode, node.tagName);
            case 326 /* PartiallyEmittedExpression */:
                return visitNode(cbNode, node.expression);
        }
    }
    ts.forEachChild = forEachChild;
    /** @internal */
    /**
     * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes
     * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; additionally,
     * unlike `forEachChild`, embedded arrays are flattened and the 'cbNode' callback is invoked for each element.
     *  If a callback returns a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned.
     *
     * @param node a given node to visit its children
     * @param cbNode a callback to be invoked for all child nodes
     * @param cbNodes a callback to be invoked for embedded array
     *
     * @remarks Unlike `forEachChild`, `forEachChildRecursively` handles recursively invoking the traversal on each child node found,
     * and while doing so, handles traversing the structure without relying on the callstack to encode the tree structure.
     */
    function forEachChildRecursively(rootNode, cbNode, cbNodes) {
        var stack = [rootNode];
        while (stack.length) {
            var parent = stack.pop();
            var res = visitAllPossibleChildren(parent, gatherPossibleChildren(parent));
            if (res) {
                return res;
            }
        }
        return;
        function gatherPossibleChildren(node) {
            var children = [];
            forEachChild(node, addWorkItem, addWorkItem); // By using a stack above and `unshift` here, we emulate a depth-first preorder traversal
            return children;
            function addWorkItem(n) {
                children.unshift(n);
            }
        }
        function visitAllPossibleChildren(parent, children) {
            for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
                var child = children_1[_i];
                if (ts.isArray(child)) {
                    if (cbNodes) {
                        var res = cbNodes(child, parent);
                        if (res) {
                            if (res === "skip")
                                continue;
                            return res;
                        }
                    }
                    for (var i = child.length - 1; i >= 0; i--) {
                        var realChild = child[i];
                        var res = cbNode(realChild, parent);
                        if (res) {
                            if (res === "skip")
                                continue;
                            return res;
                        }
                        stack.push(realChild);
                    }
                }
                else {
                    stack.push(child);
                    var res = cbNode(child, parent);
                    if (res) {
                        if (res === "skip")
                            continue;
                        return res;
                    }
                }
            }
        }
    }
    ts.forEachChildRecursively = forEachChildRecursively;
    function createSourceFile(fileName, sourceText, languageVersion, setParentNodes, scriptKind) {
        if (setParentNodes === void 0) { setParentNodes = false; }
        ts.performance.mark("beforeParse");
        var result;
        ts.perfLogger.logStartParseSourceFile(fileName);
        if (languageVersion === 100 /* JSON */) {
            result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, 6 /* JSON */);
        }
        else {
            result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
        }
        ts.perfLogger.logStopParseSourceFile();
        ts.performance.mark("afterParse");
        ts.performance.measure("Parse", "beforeParse", "afterParse");
        return result;
    }
    ts.createSourceFile = createSourceFile;
    function parseIsolatedEntityName(text, languageVersion) {
        return Parser.parseIsolatedEntityName(text, languageVersion);
    }
    ts.parseIsolatedEntityName = parseIsolatedEntityName;
    /**
     * Parse json text into SyntaxTree and return node and parse errors if any
     * @param fileName
     * @param sourceText
     */
    function parseJsonText(fileName, sourceText) {
        return Parser.parseJsonText(fileName, sourceText);
    }
    ts.parseJsonText = parseJsonText;
    // See also `isExternalOrCommonJsModule` in utilities.ts
    function isExternalModule(file) {
        return file.externalModuleIndicator !== undefined;
    }
    ts.isExternalModule = isExternalModule;
    // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter
    // indicates what changed between the 'text' that this SourceFile has and the 'newText'.
    // The SourceFile will be created with the compiler attempting to reuse as many nodes from
    // this file as possible.
    //
    // Note: this function mutates nodes from this SourceFile. That means any existing nodes
    // from this SourceFile that are being held onto may change as a result (including
    // becoming detached from any SourceFile).  It is recommended that this SourceFile not
    // be used once 'update' is called on it.
    function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
        if (aggressiveChecks === void 0) { aggressiveChecks = false; }
        var newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
        // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
        // We will manually port the flag to the new source file.
        newSourceFile.flags |= (sourceFile.flags & 3145728 /* PermanentlySetIncrementalFlags */);
        return newSourceFile;
    }
    ts.updateSourceFile = updateSourceFile;
    /* @internal */
    function parseIsolatedJSDocComment(content, start, length) {
        var result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length);
        if (result && result.jsDoc) {
            // because the jsDocComment was parsed out of the source file, it might
            // not be covered by the fixupParentReferences.
            Parser.fixupParentReferences(result.jsDoc);
        }
        return result;
    }
    ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
    /* @internal */
    // Exposed only for testing.
    function parseJSDocTypeExpressionForTests(content, start, length) {
        return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length);
    }
    ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
    // Implement the parser as a singleton module.  We do this for perf reasons because creating
    // parser instances can actually be expensive enough to impact us on projects with many source
    // files.
    var Parser;
    (function (Parser) {
        // Share a single scanner across all calls to parse a source file.  This helps speed things
        // up by avoiding the cost of creating/compiling scanners over and over again.
        var scanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ true);
        var disallowInAndDecoratorContext = 4096 /* DisallowInContext */ | 16384 /* DecoratorContext */;
        // capture constructors in 'initializeState' to avoid null checks
        var NodeConstructor;
        var TokenConstructor;
        var IdentifierConstructor;
        var PrivateIdentifierConstructor;
        var SourceFileConstructor;
        var sourceFile;
        var parseDiagnostics;
        var syntaxCursor;
        var currentToken;
        var sourceText;
        var nodeCount;
        var identifiers;
        var privateIdentifiers;
        var identifierCount;
        var parsingContext;
        var notParenthesizedArrow;
        // Flags that dictate what parsing context we're in.  For example:
        // Whether or not we are in strict parsing mode.  All that changes in strict parsing mode is
        // that some tokens that would be considered identifiers may be considered keywords.
        //
        // When adding more parser context flags, consider which is the more common case that the
        // flag will be in.  This should be the 'false' state for that flag.  The reason for this is
        // that we don't store data in our nodes unless the value is in the *non-default* state.  So,
        // for example, more often than code 'allows-in' (or doesn't 'disallow-in').  We opt for
        // 'disallow-in' set to 'false'.  Otherwise, if we had 'allowsIn' set to 'true', then almost
        // all nodes would need extra state on them to store this info.
        //
        // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6
        // grammar specification.
        //
        // An important thing about these context concepts.  By default they are effectively inherited
        // while parsing through every grammar production.  i.e. if you don't change them, then when
        // you parse a sub-production, it will have the same context values as the parent production.
        // This is great most of the time.  After all, consider all the 'expression' grammar productions
        // and how nearly all of them pass along the 'in' and 'yield' context values:
        //
        // EqualityExpression[In, Yield] :
        //      RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield]
        //      EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield]
        //
        // Where you have to be careful is then understanding what the points are in the grammar
        // where the values are *not* passed along.  For example:
        //
        // SingleNameBinding[Yield,GeneratorParameter]
        //      [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt
        //      [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
        //
        // Here this is saying that if the GeneratorParameter context flag is set, that we should
        // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier
        // and we should explicitly unset the 'yield' context flag before calling into the Initializer.
        // production.  Conversely, if the GeneratorParameter context flag is not set, then we
        // should leave the 'yield' context flag alone.
        //
        // Getting this all correct is tricky and requires careful reading of the grammar to
        // understand when these values should be changed versus when they should be inherited.
        //
        // Note: it should not be necessary to save/restore these flags during speculative/lookahead
        // parsing.  These context flags are naturally stored and restored through normal recursive
        // descent parsing and unwinding.
        var contextFlags;
        // Whether or not we've had a parse error since creating the last AST node.  If we have
        // encountered an error, it will be stored on the next AST node we create.  Parse errors
        // can be broken down into three categories:
        //
        // 1) An error that occurred during scanning.  For example, an unterminated literal, or a
        //    character that was completely not understood.
        //
        // 2) A token was expected, but was not present.  This type of error is commonly produced
        //    by the 'parseExpected' function.
        //
        // 3) A token was present that no parsing function was able to consume.  This type of error
        //    only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser
        //    decides to skip the token.
        //
        // In all of these cases, we want to mark the next node as having had an error before it.
        // With this mark, we can know in incremental settings if this node can be reused, or if
        // we have to reparse it.  If we don't keep this information around, we may just reuse the
        // node.  in that event we would then not produce the same errors as we did before, causing
        // significant confusion problems.
        //
        // Note: it is necessary that this value be saved/restored during speculative/lookahead
        // parsing.  During lookahead parsing, we will often create a node.  That node will have
        // this value attached, and then this value will be set back to 'false'.  If we decide to
        // rewind, we must get back to the same value we had prior to the lookahead.
        //
        // Note: any errors at the end of the file that do not precede a regular node, should get
        // attached to the EOF token.
        var parseErrorBeforeNextFinishedNode = false;
        function parseSourceFile(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes, scriptKind) {
            if (setParentNodes === void 0) { setParentNodes = false; }
            scriptKind = ts.ensureScriptKind(fileName, scriptKind);
            if (scriptKind === 6 /* JSON */) {
                var result_2 = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes);
                ts.convertToObjectWorker(result_2, result_2.parseDiagnostics, /*returnValue*/ false, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
                result_2.referencedFiles = ts.emptyArray;
                result_2.typeReferenceDirectives = ts.emptyArray;
                result_2.libReferenceDirectives = ts.emptyArray;
                result_2.amdDependencies = ts.emptyArray;
                result_2.hasNoDefaultLib = false;
                result_2.pragmas = ts.emptyMap;
                return result_2;
            }
            initializeState(sourceText, languageVersion, syntaxCursor, scriptKind);
            var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
            clearState();
            return result;
        }
        Parser.parseSourceFile = parseSourceFile;
        function parseIsolatedEntityName(content, languageVersion) {
            // Choice of `isDeclarationFile` should be arbitrary
            initializeState(content, languageVersion, /*syntaxCursor*/ undefined, 1 /* JS */);
            // Prime the scanner.
            nextToken();
            var entityName = parseEntityName(/*allowReservedWords*/ true);
            var isInvalid = token() === 1 /* EndOfFileToken */ && !parseDiagnostics.length;
            clearState();
            return isInvalid ? entityName : undefined;
        }
        Parser.parseIsolatedEntityName = parseIsolatedEntityName;
        function parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes) {
            if (languageVersion === void 0) { languageVersion = 2 /* ES2015 */; }
            initializeState(sourceText, languageVersion, syntaxCursor, 6 /* JSON */);
            // Set source file so that errors will be reported with this file name
            sourceFile = createSourceFile(fileName, 2 /* ES2015 */, 6 /* JSON */, /*isDeclaration*/ false);
            sourceFile.flags = contextFlags;
            // Prime the scanner.
            nextToken();
            var pos = getNodePos();
            if (token() === 1 /* EndOfFileToken */) {
                sourceFile.statements = createNodeArray([], pos, pos);
                sourceFile.endOfFileToken = parseTokenNode();
            }
            else {
                var statement = createNode(226 /* ExpressionStatement */);
                switch (token()) {
                    case 22 /* OpenBracketToken */:
                        statement.expression = parseArrayLiteralExpression();
                        break;
                    case 106 /* TrueKeyword */:
                    case 91 /* FalseKeyword */:
                    case 100 /* NullKeyword */:
                        statement.expression = parseTokenNode();
                        break;
                    case 40 /* MinusToken */:
                        if (lookAhead(function () { return nextToken() === 8 /* NumericLiteral */ && nextToken() !== 58 /* ColonToken */; })) {
                            statement.expression = parsePrefixUnaryExpression();
                        }
                        else {
                            statement.expression = parseObjectLiteralExpression();
                        }
                        break;
                    case 8 /* NumericLiteral */:
                    case 10 /* StringLiteral */:
                        if (lookAhead(function () { return nextToken() !== 58 /* ColonToken */; })) {
                            statement.expression = parseLiteralNode();
                            break;
                        }
                    // falls through
                    default:
                        statement.expression = parseObjectLiteralExpression();
                        break;
                }
                finishNode(statement);
                sourceFile.statements = createNodeArray([statement], pos);
                sourceFile.endOfFileToken = parseExpectedToken(1 /* EndOfFileToken */, ts.Diagnostics.Unexpected_token);
            }
            if (setParentNodes) {
                fixupParentReferences(sourceFile);
            }
            sourceFile.nodeCount = nodeCount;
            sourceFile.identifierCount = identifierCount;
            sourceFile.identifiers = identifiers;
            sourceFile.parseDiagnostics = parseDiagnostics;
            var result = sourceFile;
            clearState();
            return result;
        }
        Parser.parseJsonText = parseJsonText;
        function getLanguageVariant(scriptKind) {
            // .tsx and .jsx files are treated as jsx language variant.
            return scriptKind === 4 /* TSX */ || scriptKind === 2 /* JSX */ || scriptKind === 1 /* JS */ || scriptKind === 6 /* JSON */ ? 1 /* JSX */ : 0 /* Standard */;
        }
        function initializeState(_sourceText, languageVersion, _syntaxCursor, scriptKind) {
            NodeConstructor = ts.objectAllocator.getNodeConstructor();
            TokenConstructor = ts.objectAllocator.getTokenConstructor();
            IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor();
            PrivateIdentifierConstructor = ts.objectAllocator.getPrivateIdentifierConstructor();
            SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor();
            sourceText = _sourceText;
            syntaxCursor = _syntaxCursor;
            parseDiagnostics = [];
            parsingContext = 0;
            identifiers = ts.createMap();
            privateIdentifiers = ts.createMap();
            identifierCount = 0;
            nodeCount = 0;
            switch (scriptKind) {
                case 1 /* JS */:
                case 2 /* JSX */:
                    contextFlags = 131072 /* JavaScriptFile */;
                    break;
                case 6 /* JSON */:
                    contextFlags = 131072 /* JavaScriptFile */ | 33554432 /* JsonFile */;
                    break;
                default:
                    contextFlags = 0 /* None */;
                    break;
            }
            parseErrorBeforeNextFinishedNode = false;
            // Initialize and prime the scanner before parsing the source elements.
            scanner.setText(sourceText);
            scanner.setOnError(scanError);
            scanner.setScriptTarget(languageVersion);
            scanner.setLanguageVariant(getLanguageVariant(scriptKind));
        }
        function clearState() {
            // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily.
            scanner.clearCommentDirectives();
            scanner.setText("");
            scanner.setOnError(undefined);
            // Clear any data.  We don't want to accidentally hold onto it for too long.
            parseDiagnostics = undefined;
            sourceFile = undefined;
            identifiers = undefined;
            syntaxCursor = undefined;
            sourceText = undefined;
            notParenthesizedArrow = undefined;
        }
        function parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind) {
            var isDeclarationFile = isDeclarationFileName(fileName);
            if (isDeclarationFile) {
                contextFlags |= 8388608 /* Ambient */;
            }
            sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile);
            sourceFile.flags = contextFlags;
            // Prime the scanner.
            nextToken();
            // A member of ReadonlyArray<T> isn't assignable to a member of T[] (and prevents a direct cast) - but this is where we set up those members so they can be readonly in the future
            processCommentPragmas(sourceFile, sourceText);
            processPragmasIntoFields(sourceFile, reportPragmaDiagnostic);
            sourceFile.statements = parseList(0 /* SourceElements */, parseStatement);
            ts.Debug.assert(token() === 1 /* EndOfFileToken */);
            sourceFile.endOfFileToken = addJSDocComment(parseTokenNode());
            setExternalModuleIndicator(sourceFile);
            sourceFile.commentDirectives = scanner.getCommentDirectives();
            sourceFile.nodeCount = nodeCount;
            sourceFile.identifierCount = identifierCount;
            sourceFile.identifiers = identifiers;
            sourceFile.parseDiagnostics = parseDiagnostics;
            if (setParentNodes) {
                fixupParentReferences(sourceFile);
            }
            return sourceFile;
            function reportPragmaDiagnostic(pos, end, diagnostic) {
                parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, pos, end, diagnostic));
            }
        }
        function addJSDocComment(node) {
            ts.Debug.assert(!node.jsDoc); // Should only be called once per node
            var jsDoc = ts.mapDefined(ts.getJSDocCommentRanges(node, sourceFile.text), function (comment) { return JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); });
            if (jsDoc.length)
                node.jsDoc = jsDoc;
            return node;
        }
        function fixupParentReferences(rootNode) {
            // normally parent references are set during binding. However, for clients that only need
            // a syntax tree, and no semantic features, then the binding process is an unnecessary
            // overhead.  This functions allows us to set all the parents, without all the expense of
            // binding.
            forEachChildRecursively(rootNode, bindParentToChild);
            function bindParentToChild(child, parent) {
                child.parent = parent;
                if (ts.hasJSDocNodes(child)) {
                    for (var _i = 0, _a = child.jsDoc; _i < _a.length; _i++) {
                        var doc = _a[_i];
                        bindParentToChild(doc, child);
                        forEachChildRecursively(doc, bindParentToChild);
                    }
                }
            }
        }
        Parser.fixupParentReferences = fixupParentReferences;
        function createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile) {
            // code from createNode is inlined here so createNode won't have to deal with special case of creating source files
            // this is quite rare comparing to other nodes and createNode should be as fast as possible
            var sourceFile = new SourceFileConstructor(290 /* SourceFile */, /*pos*/ 0, /* end */ sourceText.length);
            nodeCount++;
            sourceFile.text = sourceText;
            sourceFile.bindDiagnostics = [];
            sourceFile.bindSuggestionDiagnostics = undefined;
            sourceFile.languageVersion = languageVersion;
            sourceFile.fileName = ts.normalizePath(fileName);
            sourceFile.languageVariant = getLanguageVariant(scriptKind);
            sourceFile.isDeclarationFile = isDeclarationFile;
            sourceFile.scriptKind = scriptKind;
            return sourceFile;
        }
        function setContextFlag(val, flag) {
            if (val) {
                contextFlags |= flag;
            }
            else {
                contextFlags &= ~flag;
            }
        }
        function setDisallowInContext(val) {
            setContextFlag(val, 4096 /* DisallowInContext */);
        }
        function setYieldContext(val) {
            setContextFlag(val, 8192 /* YieldContext */);
        }
        function setDecoratorContext(val) {
            setContextFlag(val, 16384 /* DecoratorContext */);
        }
        function setAwaitContext(val) {
            setContextFlag(val, 32768 /* AwaitContext */);
        }
        function doOutsideOfContext(context, func) {
            // contextFlagsToClear will contain only the context flags that are
            // currently set that we need to temporarily clear
            // We don't just blindly reset to the previous flags to ensure
            // that we do not mutate cached flags for the incremental
            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
            // HasAggregatedChildData).
            var contextFlagsToClear = context & contextFlags;
            if (contextFlagsToClear) {
                // clear the requested context flags
                setContextFlag(/*val*/ false, contextFlagsToClear);
                var result = func();
                // restore the context flags we just cleared
                setContextFlag(/*val*/ true, contextFlagsToClear);
                return result;
            }
            // no need to do anything special as we are not in any of the requested contexts
            return func();
        }
        function doInsideOfContext(context, func) {
            // contextFlagsToSet will contain only the context flags that
            // are not currently set that we need to temporarily enable.
            // We don't just blindly reset to the previous flags to ensure
            // that we do not mutate cached flags for the incremental
            // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
            // HasAggregatedChildData).
            var contextFlagsToSet = context & ~contextFlags;
            if (contextFlagsToSet) {
                // set the requested context flags
                setContextFlag(/*val*/ true, contextFlagsToSet);
                var result = func();
                // reset the context flags we just set
                setContextFlag(/*val*/ false, contextFlagsToSet);
                return result;
            }
            // no need to do anything special as we are already in all of the requested contexts
            return func();
        }
        function allowInAnd(func) {
            return doOutsideOfContext(4096 /* DisallowInContext */, func);
        }
        function disallowInAnd(func) {
            return doInsideOfContext(4096 /* DisallowInContext */, func);
        }
        function doInYieldContext(func) {
            return doInsideOfContext(8192 /* YieldContext */, func);
        }
        function doInDecoratorContext(func) {
            return doInsideOfContext(16384 /* DecoratorContext */, func);
        }
        function doInAwaitContext(func) {
            return doInsideOfContext(32768 /* AwaitContext */, func);
        }
        function doOutsideOfAwaitContext(func) {
            return doOutsideOfContext(32768 /* AwaitContext */, func);
        }
        function doInYieldAndAwaitContext(func) {
            return doInsideOfContext(8192 /* YieldContext */ | 32768 /* AwaitContext */, func);
        }
        function doOutsideOfYieldAndAwaitContext(func) {
            return doOutsideOfContext(8192 /* YieldContext */ | 32768 /* AwaitContext */, func);
        }
        function inContext(flags) {
            return (contextFlags & flags) !== 0;
        }
        function inYieldContext() {
            return inContext(8192 /* YieldContext */);
        }
        function inDisallowInContext() {
            return inContext(4096 /* DisallowInContext */);
        }
        function inDecoratorContext() {
            return inContext(16384 /* DecoratorContext */);
        }
        function inAwaitContext() {
            return inContext(32768 /* AwaitContext */);
        }
        function parseErrorAtCurrentToken(message, arg0) {
            parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), message, arg0);
        }
        function parseErrorAtPosition(start, length, message, arg0) {
            // Don't report another error if it would just be at the same position as the last error.
            var lastError = ts.lastOrUndefined(parseDiagnostics);
            if (!lastError || start !== lastError.start) {
                parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0));
            }
            // Mark that we've encountered an error.  We'll set an appropriate bit on the next
            // node we finish so that it can't be reused incrementally.
            parseErrorBeforeNextFinishedNode = true;
        }
        function parseErrorAt(start, end, message, arg0) {
            parseErrorAtPosition(start, end - start, message, arg0);
        }
        function parseErrorAtRange(range, message, arg0) {
            parseErrorAt(range.pos, range.end, message, arg0);
        }
        function scanError(message, length) {
            parseErrorAtPosition(scanner.getTextPos(), length, message);
        }
        function getNodePos() {
            return scanner.getStartPos();
        }
        // Use this function to access the current token instead of reading the currentToken
        // variable. Since function results aren't narrowed in control flow analysis, this ensures
        // that the type checker doesn't make wrong assumptions about the type of the current
        // token (e.g. a call to nextToken() changes the current token but the checker doesn't
        // reason about this side effect).  Mainstream VMs inline simple functions like this, so
        // there is no performance penalty.
        function token() {
            return currentToken;
        }
        function nextTokenWithoutCheck() {
            return currentToken = scanner.scan();
        }
        function nextToken() {
            // if the keyword had an escape
            if (ts.isKeyword(currentToken) && (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape())) {
                // issue a parse error for the escape
                parseErrorAt(scanner.getTokenPos(), scanner.getTextPos(), ts.Diagnostics.Keywords_cannot_contain_escape_characters);
            }
            return nextTokenWithoutCheck();
        }
        function nextTokenJSDoc() {
            return currentToken = scanner.scanJsDocToken();
        }
        function reScanGreaterToken() {
            return currentToken = scanner.reScanGreaterToken();
        }
        function reScanSlashToken() {
            return currentToken = scanner.reScanSlashToken();
        }
        function reScanTemplateToken(isTaggedTemplate) {
            return currentToken = scanner.reScanTemplateToken(isTaggedTemplate);
        }
        function reScanTemplateHeadOrNoSubstitutionTemplate() {
            return currentToken = scanner.reScanTemplateHeadOrNoSubstitutionTemplate();
        }
        function reScanLessThanToken() {
            return currentToken = scanner.reScanLessThanToken();
        }
        function scanJsxIdentifier() {
            return currentToken = scanner.scanJsxIdentifier();
        }
        function scanJsxText() {
            return currentToken = scanner.scanJsxToken();
        }
        function scanJsxAttributeValue() {
            return currentToken = scanner.scanJsxAttributeValue();
        }
        function speculationHelper(callback, isLookAhead) {
            // Keep track of the state we'll need to rollback to if lookahead fails (or if the
            // caller asked us to always reset our state).
            var saveToken = currentToken;
            var saveParseDiagnosticsLength = parseDiagnostics.length;
            var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
            // Note: it is not actually necessary to save/restore the context flags here.  That's
            // because the saving/restoring of these flags happens naturally through the recursive
            // descent nature of our parser.  However, we still store this here just so we can
            // assert that invariant holds.
            var saveContextFlags = contextFlags;
            // If we're only looking ahead, then tell the scanner to only lookahead as well.
            // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the
            // same.
            var result = isLookAhead
                ? scanner.lookAhead(callback)
                : scanner.tryScan(callback);
            ts.Debug.assert(saveContextFlags === contextFlags);
            // If our callback returned something 'falsy' or we're just looking ahead,
            // then unconditionally restore us to where we were.
            if (!result || isLookAhead) {
                currentToken = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
            }
            return result;
        }
        /** Invokes the provided callback then unconditionally restores the parser to the state it
         * was in immediately prior to invoking the callback.  The result of invoking the callback
         * is returned from this function.
         */
        function lookAhead(callback) {
            return speculationHelper(callback, /*isLookAhead*/ true);
        }
        /** Invokes the provided callback.  If the callback returns something falsy, then it restores
         * the parser to the state it was in immediately prior to invoking the callback.  If the
         * callback returns something truthy, then the parser state is not rolled back.  The result
         * of invoking the callback is returned from this function.
         */
        function tryParse(callback) {
            return speculationHelper(callback, /*isLookAhead*/ false);
        }
        // Ignore strict mode flag because we will report an error in type checker instead.
        function isIdentifier() {
            if (token() === 75 /* Identifier */) {
                return true;
            }
            // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is
            // considered a keyword and is not an identifier.
            if (token() === 121 /* YieldKeyword */ && inYieldContext()) {
                return false;
            }
            // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is
            // considered a keyword and is not an identifier.
            if (token() === 127 /* AwaitKeyword */ && inAwaitContext()) {
                return false;
            }
            return token() > 112 /* LastReservedWord */;
        }
        function parseExpected(kind, diagnosticMessage, shouldAdvance) {
            if (shouldAdvance === void 0) { shouldAdvance = true; }
            if (token() === kind) {
                if (shouldAdvance) {
                    nextToken();
                }
                return true;
            }
            // Report specific message if provided with one.  Otherwise, report generic fallback message.
            if (diagnosticMessage) {
                parseErrorAtCurrentToken(diagnosticMessage);
            }
            else {
                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind));
            }
            return false;
        }
        function parseExpectedJSDoc(kind) {
            if (token() === kind) {
                nextTokenJSDoc();
                return true;
            }
            parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind));
            return false;
        }
        function parseOptional(t) {
            if (token() === t) {
                nextToken();
                return true;
            }
            return false;
        }
        function parseOptionalToken(t) {
            if (token() === t) {
                return parseTokenNode();
            }
            return undefined;
        }
        function parseOptionalTokenJSDoc(t) {
            if (token() === t) {
                return parseTokenNodeJSDoc();
            }
            return undefined;
        }
        function parseExpectedToken(t, diagnosticMessage, arg0) {
            return parseOptionalToken(t) ||
                createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || ts.Diagnostics._0_expected, arg0 || ts.tokenToString(t));
        }
        function parseExpectedTokenJSDoc(t) {
            return parseOptionalTokenJSDoc(t) ||
                createMissingNode(t, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(t));
        }
        function parseTokenNode() {
            var node = createNode(token());
            nextToken();
            return finishNode(node);
        }
        function parseTokenNodeJSDoc() {
            var node = createNode(token());
            nextTokenJSDoc();
            return finishNode(node);
        }
        function canParseSemicolon() {
            // If there's a real semicolon, then we can always parse it out.
            if (token() === 26 /* SemicolonToken */) {
                return true;
            }
            // We can parse out an optional semicolon in ASI cases in the following cases.
            return token() === 19 /* CloseBraceToken */ || token() === 1 /* EndOfFileToken */ || scanner.hasPrecedingLineBreak();
        }
        function parseSemicolon() {
            if (canParseSemicolon()) {
                if (token() === 26 /* SemicolonToken */) {
                    // consume the semicolon if it was explicitly provided.
                    nextToken();
                }
                return true;
            }
            else {
                return parseExpected(26 /* SemicolonToken */);
            }
        }
        function createNode(kind, pos) {
            nodeCount++;
            var p = pos >= 0 ? pos : scanner.getStartPos();
            return ts.isNodeKind(kind) || kind === 0 /* Unknown */ ? new NodeConstructor(kind, p, p) :
                kind === 75 /* Identifier */ ? new IdentifierConstructor(kind, p, p) :
                    kind === 76 /* PrivateIdentifier */ ? new PrivateIdentifierConstructor(kind, p, p) :
                        new TokenConstructor(kind, p, p);
        }
        function createNodeWithJSDoc(kind, pos) {
            var node = createNode(kind, pos);
            if (scanner.getTokenFlags() & 2 /* PrecedingJSDocComment */ && (kind !== 226 /* ExpressionStatement */ || token() !== 20 /* OpenParenToken */)) {
                addJSDocComment(node);
            }
            return node;
        }
        function createNodeArray(elements, pos, end) {
            // Since the element list of a node array is typically created by starting with an empty array and
            // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for
            // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation.
            var length = elements.length;
            var array = (length >= 1 && length <= 4 ? elements.slice() : elements);
            array.pos = pos;
            array.end = end === undefined ? scanner.getStartPos() : end;
            return array;
        }
        function finishNode(node, end) {
            node.end = end === undefined ? scanner.getStartPos() : end;
            if (contextFlags) {
                node.flags |= contextFlags;
            }
            // Keep track on the node if we encountered an error while parsing it.  If we did, then
            // we cannot reuse the node incrementally.  Once we've marked this node, clear out the
            // flag so that we don't mark any subsequent nodes.
            if (parseErrorBeforeNextFinishedNode) {
                parseErrorBeforeNextFinishedNode = false;
                node.flags |= 65536 /* ThisNodeHasError */;
            }
            return node;
        }
        function createMissingNode(kind, reportAtCurrentPosition, diagnosticMessage, arg0) {
            if (reportAtCurrentPosition) {
                parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
            }
            else if (diagnosticMessage) {
                parseErrorAtCurrentToken(diagnosticMessage, arg0);
            }
            var result = createNode(kind);
            if (kind === 75 /* Identifier */) {
                result.escapedText = "";
            }
            else if (ts.isLiteralKind(kind) || ts.isTemplateLiteralKind(kind)) {
                result.text = "";
            }
            return finishNode(result);
        }
        function internIdentifier(text) {
            var identifier = identifiers.get(text);
            if (identifier === undefined) {
                identifiers.set(text, identifier = text);
            }
            return identifier;
        }
        // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues
        // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for
        // each identifier in order to reduce memory consumption.
        function createIdentifier(isIdentifier, diagnosticMessage, privateIdentifierDiagnosticMessage) {
            identifierCount++;
            if (isIdentifier) {
                var node = createNode(75 /* Identifier */);
                // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
                if (token() !== 75 /* Identifier */) {
                    node.originalKeywordKind = token();
                }
                node.escapedText = ts.escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
                nextTokenWithoutCheck();
                return finishNode(node);
            }
            if (token() === 76 /* PrivateIdentifier */) {
                parseErrorAtCurrentToken(privateIdentifierDiagnosticMessage || ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
                return createIdentifier(/*isIdentifier*/ true);
            }
            // Only for end of file because the error gets reported incorrectly on embedded script tags.
            var reportAtCurrentPosition = token() === 1 /* EndOfFileToken */;
            var isReservedWord = scanner.isReservedWord();
            var msgArg = scanner.getTokenText();
            var defaultMessage = isReservedWord ?
                ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here :
                ts.Diagnostics.Identifier_expected;
            return createMissingNode(75 /* Identifier */, reportAtCurrentPosition, diagnosticMessage || defaultMessage, msgArg);
        }
        function parseIdentifier(diagnosticMessage, privateIdentifierDiagnosticMessage) {
            return createIdentifier(isIdentifier(), diagnosticMessage, privateIdentifierDiagnosticMessage);
        }
        function parseIdentifierName(diagnosticMessage) {
            return createIdentifier(ts.tokenIsIdentifierOrKeyword(token()), diagnosticMessage);
        }
        function isLiteralPropertyName() {
            return ts.tokenIsIdentifierOrKeyword(token()) ||
                token() === 10 /* StringLiteral */ ||
                token() === 8 /* NumericLiteral */;
        }
        function parsePropertyNameWorker(allowComputedPropertyNames) {
            if (token() === 10 /* StringLiteral */ || token() === 8 /* NumericLiteral */) {
                var node = parseLiteralNode();
                node.text = internIdentifier(node.text);
                return node;
            }
            if (allowComputedPropertyNames && token() === 22 /* OpenBracketToken */) {
                return parseComputedPropertyName();
            }
            if (token() === 76 /* PrivateIdentifier */) {
                return parsePrivateIdentifier();
            }
            return parseIdentifierName();
        }
        function parsePropertyName() {
            return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true);
        }
        function parseComputedPropertyName() {
            // PropertyName [Yield]:
            //      LiteralPropertyName
            //      ComputedPropertyName[?Yield]
            var node = createNode(154 /* ComputedPropertyName */);
            parseExpected(22 /* OpenBracketToken */);
            // We parse any expression (including a comma expression). But the grammar
            // says that only an assignment expression is allowed, so the grammar checker
            // will error if it sees a comma expression.
            node.expression = allowInAnd(parseExpression);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function internPrivateIdentifier(text) {
            var privateIdentifier = privateIdentifiers.get(text);
            if (privateIdentifier === undefined) {
                privateIdentifiers.set(text, privateIdentifier = text);
            }
            return privateIdentifier;
        }
        function parsePrivateIdentifier() {
            var node = createNode(76 /* PrivateIdentifier */);
            node.escapedText = ts.escapeLeadingUnderscores(internPrivateIdentifier(scanner.getTokenText()));
            nextToken();
            return finishNode(node);
        }
        function parseContextualModifier(t) {
            return token() === t && tryParse(nextTokenCanFollowModifier);
        }
        function nextTokenIsOnSameLineAndCanFollowModifier() {
            nextToken();
            if (scanner.hasPrecedingLineBreak()) {
                return false;
            }
            return canFollowModifier();
        }
        function nextTokenCanFollowModifier() {
            switch (token()) {
                case 81 /* ConstKeyword */:
                    // 'const' is only a modifier if followed by 'enum'.
                    return nextToken() === 88 /* EnumKeyword */;
                case 89 /* ExportKeyword */:
                    nextToken();
                    if (token() === 84 /* DefaultKeyword */) {
                        return lookAhead(nextTokenCanFollowDefaultKeyword);
                    }
                    if (token() === 145 /* TypeKeyword */) {
                        return lookAhead(nextTokenCanFollowExportModifier);
                    }
                    return canFollowExportModifier();
                case 84 /* DefaultKeyword */:
                    return nextTokenCanFollowDefaultKeyword();
                case 120 /* StaticKeyword */:
                case 131 /* GetKeyword */:
                case 142 /* SetKeyword */:
                    nextToken();
                    return canFollowModifier();
                default:
                    return nextTokenIsOnSameLineAndCanFollowModifier();
            }
        }
        function canFollowExportModifier() {
            return token() !== 41 /* AsteriskToken */
                && token() !== 123 /* AsKeyword */
                && token() !== 18 /* OpenBraceToken */
                && canFollowModifier();
        }
        function nextTokenCanFollowExportModifier() {
            nextToken();
            return canFollowExportModifier();
        }
        function parseAnyContextualModifier() {
            return ts.isModifierKind(token()) && tryParse(nextTokenCanFollowModifier);
        }
        function canFollowModifier() {
            return token() === 22 /* OpenBracketToken */
                || token() === 18 /* OpenBraceToken */
                || token() === 41 /* AsteriskToken */
                || token() === 25 /* DotDotDotToken */
                || isLiteralPropertyName();
        }
        function nextTokenCanFollowDefaultKeyword() {
            nextToken();
            return token() === 80 /* ClassKeyword */ || token() === 94 /* FunctionKeyword */ ||
                token() === 114 /* InterfaceKeyword */ ||
                (token() === 122 /* AbstractKeyword */ && lookAhead(nextTokenIsClassKeywordOnSameLine)) ||
                (token() === 126 /* AsyncKeyword */ && lookAhead(nextTokenIsFunctionKeywordOnSameLine));
        }
        // True if positioned at the start of a list element
        function isListElement(parsingContext, inErrorRecovery) {
            var node = currentNode(parsingContext);
            if (node) {
                return true;
            }
            switch (parsingContext) {
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                    // If we're in error recovery, then we don't want to treat ';' as an empty statement.
                    // The problem is that ';' can show up in far too many contexts, and if we see one
                    // and assume it's a statement, then we may bail out inappropriately from whatever
                    // we're parsing.  For example, if we have a semicolon in the middle of a class, then
                    // we really don't want to assume the class is over and we're on a statement in the
                    // outer module.  We just want to consume and move on.
                    return !(token() === 26 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement();
                case 2 /* SwitchClauses */:
                    return token() === 78 /* CaseKeyword */ || token() === 84 /* DefaultKeyword */;
                case 4 /* TypeMembers */:
                    return lookAhead(isTypeMemberStart);
                case 5 /* ClassMembers */:
                    // We allow semicolons as class elements (as specified by ES6) as long as we're
                    // not in error recovery.  If we're in error recovery, we don't want an errant
                    // semicolon to be treated as a class member (since they're almost always used
                    // for statements.
                    return lookAhead(isClassMemberStart) || (token() === 26 /* SemicolonToken */ && !inErrorRecovery);
                case 6 /* EnumMembers */:
                    // Include open bracket computed properties. This technically also lets in indexers,
                    // which would be a candidate for improved error reporting.
                    return token() === 22 /* OpenBracketToken */ || isLiteralPropertyName();
                case 12 /* ObjectLiteralMembers */:
                    switch (token()) {
                        case 22 /* OpenBracketToken */:
                        case 41 /* AsteriskToken */:
                        case 25 /* DotDotDotToken */:
                        case 24 /* DotToken */: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`)
                            return true;
                        default:
                            return isLiteralPropertyName();
                    }
                case 18 /* RestProperties */:
                    return isLiteralPropertyName();
                case 9 /* ObjectBindingElements */:
                    return token() === 22 /* OpenBracketToken */ || token() === 25 /* DotDotDotToken */ || isLiteralPropertyName();
                case 7 /* HeritageClauseElement */:
                    // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{`
                    // That way we won't consume the body of a class in its heritage clause.
                    if (token() === 18 /* OpenBraceToken */) {
                        return lookAhead(isValidHeritageClauseObjectLiteral);
                    }
                    if (!inErrorRecovery) {
                        return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword();
                    }
                    else {
                        // If we're in error recovery we tighten up what we're willing to match.
                        // That way we don't treat something like "this" as a valid heritage clause
                        // element during recovery.
                        return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword();
                    }
                case 8 /* VariableDeclarations */:
                    return isIdentifierOrPrivateIdentifierOrPattern();
                case 10 /* ArrayBindingElements */:
                    return token() === 27 /* CommaToken */ || token() === 25 /* DotDotDotToken */ || isIdentifierOrPrivateIdentifierOrPattern();
                case 19 /* TypeParameters */:
                    return isIdentifier();
                case 15 /* ArrayLiteralMembers */:
                    switch (token()) {
                        case 27 /* CommaToken */:
                        case 24 /* DotToken */: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`)
                            return true;
                    }
                // falls through
                case 11 /* ArgumentExpressions */:
                    return token() === 25 /* DotDotDotToken */ || isStartOfExpression();
                case 16 /* Parameters */:
                    return isStartOfParameter(/*isJSDocParameter*/ false);
                case 17 /* JSDocParameters */:
                    return isStartOfParameter(/*isJSDocParameter*/ true);
                case 20 /* TypeArguments */:
                case 21 /* TupleElementTypes */:
                    return token() === 27 /* CommaToken */ || isStartOfType();
                case 22 /* HeritageClauses */:
                    return isHeritageClause();
                case 23 /* ImportOrExportSpecifiers */:
                    return ts.tokenIsIdentifierOrKeyword(token());
                case 13 /* JsxAttributes */:
                    return ts.tokenIsIdentifierOrKeyword(token()) || token() === 18 /* OpenBraceToken */;
                case 14 /* JsxChildren */:
                    return true;
            }
            return ts.Debug.fail("Non-exhaustive case in 'isListElement'.");
        }
        function isValidHeritageClauseObjectLiteral() {
            ts.Debug.assert(token() === 18 /* OpenBraceToken */);
            if (nextToken() === 19 /* CloseBraceToken */) {
                // if we see "extends {}" then only treat the {} as what we're extending (and not
                // the class body) if we have:
                //
                //      extends {} {
                //      extends {},
                //      extends {} extends
                //      extends {} implements
                var next = nextToken();
                return next === 27 /* CommaToken */ || next === 18 /* OpenBraceToken */ || next === 90 /* ExtendsKeyword */ || next === 113 /* ImplementsKeyword */;
            }
            return true;
        }
        function nextTokenIsIdentifier() {
            nextToken();
            return isIdentifier();
        }
        function nextTokenIsIdentifierOrKeyword() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token());
        }
        function nextTokenIsIdentifierOrKeywordOrGreaterThan() {
            nextToken();
            return ts.tokenIsIdentifierOrKeywordOrGreaterThan(token());
        }
        function isHeritageClauseExtendsOrImplementsKeyword() {
            if (token() === 113 /* ImplementsKeyword */ ||
                token() === 90 /* ExtendsKeyword */) {
                return lookAhead(nextTokenIsStartOfExpression);
            }
            return false;
        }
        function nextTokenIsStartOfExpression() {
            nextToken();
            return isStartOfExpression();
        }
        function nextTokenIsStartOfType() {
            nextToken();
            return isStartOfType();
        }
        // True if positioned at a list terminator
        function isListTerminator(kind) {
            if (token() === 1 /* EndOfFileToken */) {
                // Being at the end of the file ends all lists.
                return true;
            }
            switch (kind) {
                case 1 /* BlockStatements */:
                case 2 /* SwitchClauses */:
                case 4 /* TypeMembers */:
                case 5 /* ClassMembers */:
                case 6 /* EnumMembers */:
                case 12 /* ObjectLiteralMembers */:
                case 9 /* ObjectBindingElements */:
                case 23 /* ImportOrExportSpecifiers */:
                    return token() === 19 /* CloseBraceToken */;
                case 3 /* SwitchClauseStatements */:
                    return token() === 19 /* CloseBraceToken */ || token() === 78 /* CaseKeyword */ || token() === 84 /* DefaultKeyword */;
                case 7 /* HeritageClauseElement */:
                    return token() === 18 /* OpenBraceToken */ || token() === 90 /* ExtendsKeyword */ || token() === 113 /* ImplementsKeyword */;
                case 8 /* VariableDeclarations */:
                    return isVariableDeclaratorListTerminator();
                case 19 /* TypeParameters */:
                    // Tokens other than '>' are here for better error recovery
                    return token() === 31 /* GreaterThanToken */ || token() === 20 /* OpenParenToken */ || token() === 18 /* OpenBraceToken */ || token() === 90 /* ExtendsKeyword */ || token() === 113 /* ImplementsKeyword */;
                case 11 /* ArgumentExpressions */:
                    // Tokens other than ')' are here for better error recovery
                    return token() === 21 /* CloseParenToken */ || token() === 26 /* SemicolonToken */;
                case 15 /* ArrayLiteralMembers */:
                case 21 /* TupleElementTypes */:
                case 10 /* ArrayBindingElements */:
                    return token() === 23 /* CloseBracketToken */;
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                case 18 /* RestProperties */:
                    // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery
                    return token() === 21 /* CloseParenToken */ || token() === 23 /* CloseBracketToken */ /*|| token === SyntaxKind.OpenBraceToken*/;
                case 20 /* TypeArguments */:
                    // All other tokens should cause the type-argument to terminate except comma token
                    return token() !== 27 /* CommaToken */;
                case 22 /* HeritageClauses */:
                    return token() === 18 /* OpenBraceToken */ || token() === 19 /* CloseBraceToken */;
                case 13 /* JsxAttributes */:
                    return token() === 31 /* GreaterThanToken */ || token() === 43 /* SlashToken */;
                case 14 /* JsxChildren */:
                    return token() === 29 /* LessThanToken */ && lookAhead(nextTokenIsSlash);
                default:
                    return false;
            }
        }
        function isVariableDeclaratorListTerminator() {
            // If we can consume a semicolon (either explicitly, or with ASI), then consider us done
            // with parsing the list of variable declarators.
            if (canParseSemicolon()) {
                return true;
            }
            // in the case where we're parsing the variable declarator of a 'for-in' statement, we
            // are done if we see an 'in' keyword in front of us. Same with for-of
            if (isInOrOfKeyword(token())) {
                return true;
            }
            // ERROR RECOVERY TWEAK:
            // For better error recovery, if we see an '=>' then we just stop immediately.  We've got an
            // arrow function here and it's going to be very unlikely that we'll resynchronize and get
            // another variable declaration.
            if (token() === 38 /* EqualsGreaterThanToken */) {
                return true;
            }
            // Keep trying to parse out variable declarators.
            return false;
        }
        // True if positioned at element or terminator of the current list or any enclosing list
        function isInSomeParsingContext() {
            for (var kind = 0; kind < 24 /* Count */; kind++) {
                if (parsingContext & (1 << kind)) {
                    if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        // Parses a list of elements
        function parseList(kind, parseElement) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var list = [];
            var listPos = getNodePos();
            while (!isListTerminator(kind)) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var element = parseListElement(kind, parseElement);
                    list.push(element);
                    continue;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            parsingContext = saveParsingContext;
            return createNodeArray(list, listPos);
        }
        function parseListElement(parsingContext, parseElement) {
            var node = currentNode(parsingContext);
            if (node) {
                return consumeNode(node);
            }
            return parseElement();
        }
        function currentNode(parsingContext) {
            // If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse.
            //
            // If there is an outstanding parse error that we've encountered, but not attached to
            // some node, then we cannot get a node from the old source tree.  This is because we
            // want to mark the next node we encounter as being unusable.
            //
            // Note: This may be too conservative.  Perhaps we could reuse the node and set the bit
            // on it (or its leftmost child) as having the error.  For now though, being conservative
            // is nice and likely won't ever affect perf.
            if (!syntaxCursor || !isReusableParsingContext(parsingContext) || parseErrorBeforeNextFinishedNode) {
                return undefined;
            }
            var node = syntaxCursor.currentNode(scanner.getStartPos());
            // Can't reuse a missing node.
            // Can't reuse a node that intersected the change range.
            // Can't reuse a node that contains a parse error.  This is necessary so that we
            // produce the same set of errors again.
            if (ts.nodeIsMissing(node) || node.intersectsChange || ts.containsParseError(node)) {
                return undefined;
            }
            // We can only reuse a node if it was parsed under the same strict mode that we're
            // currently in.  i.e. if we originally parsed a node in non-strict mode, but then
            // the user added 'using strict' at the top of the file, then we can't use that node
            // again as the presence of strict mode may cause us to parse the tokens in the file
            // differently.
            //
            // Note: we *can* reuse tokens when the strict mode changes.  That's because tokens
            // are unaffected by strict mode.  It's just the parser will decide what to do with it
            // differently depending on what mode it is in.
            //
            // This also applies to all our other context flags as well.
            var nodeContextFlags = node.flags & 25358336 /* ContextFlags */;
            if (nodeContextFlags !== contextFlags) {
                return undefined;
            }
            // Ok, we have a node that looks like it could be reused.  Now verify that it is valid
            // in the current list parsing context that we're currently at.
            if (!canReuseNode(node, parsingContext)) {
                return undefined;
            }
            if (node.jsDocCache) {
                // jsDocCache may include tags from parent nodes, which might have been modified.
                node.jsDocCache = undefined;
            }
            return node;
        }
        function consumeNode(node) {
            // Move the scanner so it is after the node we just consumed.
            scanner.setTextPos(node.end);
            nextToken();
            return node;
        }
        function isReusableParsingContext(parsingContext) {
            switch (parsingContext) {
                case 5 /* ClassMembers */:
                case 2 /* SwitchClauses */:
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                case 6 /* EnumMembers */:
                case 4 /* TypeMembers */:
                case 8 /* VariableDeclarations */:
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                    return true;
            }
            return false;
        }
        function canReuseNode(node, parsingContext) {
            switch (parsingContext) {
                case 5 /* ClassMembers */:
                    return isReusableClassMember(node);
                case 2 /* SwitchClauses */:
                    return isReusableSwitchClause(node);
                case 0 /* SourceElements */:
                case 1 /* BlockStatements */:
                case 3 /* SwitchClauseStatements */:
                    return isReusableStatement(node);
                case 6 /* EnumMembers */:
                    return isReusableEnumMember(node);
                case 4 /* TypeMembers */:
                    return isReusableTypeMember(node);
                case 8 /* VariableDeclarations */:
                    return isReusableVariableDeclaration(node);
                case 17 /* JSDocParameters */:
                case 16 /* Parameters */:
                    return isReusableParameter(node);
                // Any other lists we do not care about reusing nodes in.  But feel free to add if
                // you can do so safely.  Danger areas involve nodes that may involve speculative
                // parsing.  If speculative parsing is involved with the node, then the range the
                // parser reached while looking ahead might be in the edited range (see the example
                // in canReuseVariableDeclaratorNode for a good case of this).
                // case ParsingContext.HeritageClauses:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // heritage clauses.
                // case ParsingContext.TypeParameters:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // type parameters.  Note that that's because type *parameters* only occur in
                // unambiguous *type* contexts.  While type *arguments* occur in very ambiguous
                // *expression* contexts.
                // case ParsingContext.TupleElementTypes:
                // This would probably be safe to reuse.  There is no speculative parsing with
                // tuple types.
                // Technically, type argument list types are probably safe to reuse.  While
                // speculative parsing is involved with them (since type argument lists are only
                // produced from speculative parsing a < as a type argument list), we only have
                // the types because speculative parsing succeeded.  Thus, the lookahead never
                // went past the end of the list and rewound.
                // case ParsingContext.TypeArguments:
                // Note: these are almost certainly not safe to ever reuse.  Expressions commonly
                // need a large amount of lookahead, and we should not reuse them as they may
                // have actually intersected the edit.
                // case ParsingContext.ArgumentExpressions:
                // This is not safe to reuse for the same reason as the 'AssignmentExpression'
                // cases.  i.e. a property assignment may end with an expression, and thus might
                // have lookahead far beyond it's old node.
                // case ParsingContext.ObjectLiteralMembers:
                // This is probably not safe to reuse.  There can be speculative parsing with
                // type names in a heritage clause.  There can be generic names in the type
                // name list, and there can be left hand side expressions (which can have type
                // arguments.)
                // case ParsingContext.HeritageClauseElement:
                // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes
                // on any given element. Same for children.
                // case ParsingContext.JsxAttributes:
                // case ParsingContext.JsxChildren:
            }
            return false;
        }
        function isReusableClassMember(node) {
            if (node) {
                switch (node.kind) {
                    case 162 /* Constructor */:
                    case 167 /* IndexSignature */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 159 /* PropertyDeclaration */:
                    case 222 /* SemicolonClassElement */:
                        return true;
                    case 161 /* MethodDeclaration */:
                        // Method declarations are not necessarily reusable.  An object-literal
                        // may have a method calls "constructor(...)" and we must reparse that
                        // into an actual .ConstructorDeclaration.
                        var methodDeclaration = node;
                        var nameIsConstructor = methodDeclaration.name.kind === 75 /* Identifier */ &&
                            methodDeclaration.name.originalKeywordKind === 129 /* ConstructorKeyword */;
                        return !nameIsConstructor;
                }
            }
            return false;
        }
        function isReusableSwitchClause(node) {
            if (node) {
                switch (node.kind) {
                    case 277 /* CaseClause */:
                    case 278 /* DefaultClause */:
                        return true;
                }
            }
            return false;
        }
        function isReusableStatement(node) {
            if (node) {
                switch (node.kind) {
                    case 244 /* FunctionDeclaration */:
                    case 225 /* VariableStatement */:
                    case 223 /* Block */:
                    case 227 /* IfStatement */:
                    case 226 /* ExpressionStatement */:
                    case 239 /* ThrowStatement */:
                    case 235 /* ReturnStatement */:
                    case 237 /* SwitchStatement */:
                    case 234 /* BreakStatement */:
                    case 233 /* ContinueStatement */:
                    case 231 /* ForInStatement */:
                    case 232 /* ForOfStatement */:
                    case 230 /* ForStatement */:
                    case 229 /* WhileStatement */:
                    case 236 /* WithStatement */:
                    case 224 /* EmptyStatement */:
                    case 240 /* TryStatement */:
                    case 238 /* LabeledStatement */:
                    case 228 /* DoStatement */:
                    case 241 /* DebuggerStatement */:
                    case 254 /* ImportDeclaration */:
                    case 253 /* ImportEqualsDeclaration */:
                    case 260 /* ExportDeclaration */:
                    case 259 /* ExportAssignment */:
                    case 249 /* ModuleDeclaration */:
                    case 245 /* ClassDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                    case 248 /* EnumDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                        return true;
                }
            }
            return false;
        }
        function isReusableEnumMember(node) {
            return node.kind === 284 /* EnumMember */;
        }
        function isReusableTypeMember(node) {
            if (node) {
                switch (node.kind) {
                    case 166 /* ConstructSignature */:
                    case 160 /* MethodSignature */:
                    case 167 /* IndexSignature */:
                    case 158 /* PropertySignature */:
                    case 165 /* CallSignature */:
                        return true;
                }
            }
            return false;
        }
        function isReusableVariableDeclaration(node) {
            if (node.kind !== 242 /* VariableDeclaration */) {
                return false;
            }
            // Very subtle incremental parsing bug.  Consider the following code:
            //
            //      let v = new List < A, B
            //
            // This is actually legal code.  It's a list of variable declarators "v = new List<A"
            // on one side and "B" on the other. If you then change that to:
            //
            //      let v = new List < A, B >()
            //
            // then we have a problem.  "v = new List<A" doesn't intersect the change range, so we
            // start reparsing at "B" and we completely fail to handle this properly.
            //
            // In order to prevent this, we do not allow a variable declarator to be reused if it
            // has an initializer.
            var variableDeclarator = node;
            return variableDeclarator.initializer === undefined;
        }
        function isReusableParameter(node) {
            if (node.kind !== 156 /* Parameter */) {
                return false;
            }
            // See the comment in isReusableVariableDeclaration for why we do this.
            var parameter = node;
            return parameter.initializer === undefined;
        }
        // Returns true if we should abort parsing.
        function abortParsingListOrMoveToNextToken(kind) {
            parseErrorAtCurrentToken(parsingContextErrors(kind));
            if (isInSomeParsingContext()) {
                return true;
            }
            nextToken();
            return false;
        }
        function parsingContextErrors(context) {
            switch (context) {
                case 0 /* SourceElements */: return ts.Diagnostics.Declaration_or_statement_expected;
                case 1 /* BlockStatements */: return ts.Diagnostics.Declaration_or_statement_expected;
                case 2 /* SwitchClauses */: return ts.Diagnostics.case_or_default_expected;
                case 3 /* SwitchClauseStatements */: return ts.Diagnostics.Statement_expected;
                case 18 /* RestProperties */: // fallthrough
                case 4 /* TypeMembers */: return ts.Diagnostics.Property_or_signature_expected;
                case 5 /* ClassMembers */: return ts.Diagnostics.Unexpected_token_A_constructor_method_accessor_or_property_was_expected;
                case 6 /* EnumMembers */: return ts.Diagnostics.Enum_member_expected;
                case 7 /* HeritageClauseElement */: return ts.Diagnostics.Expression_expected;
                case 8 /* VariableDeclarations */: return ts.Diagnostics.Variable_declaration_expected;
                case 9 /* ObjectBindingElements */: return ts.Diagnostics.Property_destructuring_pattern_expected;
                case 10 /* ArrayBindingElements */: return ts.Diagnostics.Array_element_destructuring_pattern_expected;
                case 11 /* ArgumentExpressions */: return ts.Diagnostics.Argument_expression_expected;
                case 12 /* ObjectLiteralMembers */: return ts.Diagnostics.Property_assignment_expected;
                case 15 /* ArrayLiteralMembers */: return ts.Diagnostics.Expression_or_comma_expected;
                case 17 /* JSDocParameters */: return ts.Diagnostics.Parameter_declaration_expected;
                case 16 /* Parameters */: return ts.Diagnostics.Parameter_declaration_expected;
                case 19 /* TypeParameters */: return ts.Diagnostics.Type_parameter_declaration_expected;
                case 20 /* TypeArguments */: return ts.Diagnostics.Type_argument_expected;
                case 21 /* TupleElementTypes */: return ts.Diagnostics.Type_expected;
                case 22 /* HeritageClauses */: return ts.Diagnostics.Unexpected_token_expected;
                case 23 /* ImportOrExportSpecifiers */: return ts.Diagnostics.Identifier_expected;
                case 13 /* JsxAttributes */: return ts.Diagnostics.Identifier_expected;
                case 14 /* JsxChildren */: return ts.Diagnostics.Identifier_expected;
                default: return undefined; // TODO: GH#18217 `default: Debug.assertNever(context);`
            }
        }
        // Parses a comma-delimited list of elements
        function parseDelimitedList(kind, parseElement, considerSemicolonAsDelimiter) {
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << kind;
            var list = [];
            var listPos = getNodePos();
            var commaStart = -1; // Meaning the previous token was not a comma
            while (true) {
                if (isListElement(kind, /*inErrorRecovery*/ false)) {
                    var startPos = scanner.getStartPos();
                    list.push(parseListElement(kind, parseElement));
                    commaStart = scanner.getTokenPos();
                    if (parseOptional(27 /* CommaToken */)) {
                        // No need to check for a zero length node since we know we parsed a comma
                        continue;
                    }
                    commaStart = -1; // Back to the state where the last token was not a comma
                    if (isListTerminator(kind)) {
                        break;
                    }
                    // We didn't get a comma, and the list wasn't terminated, explicitly parse
                    // out a comma so we give a good error message.
                    parseExpected(27 /* CommaToken */, getExpectedCommaDiagnostic(kind));
                    // If the token was a semicolon, and the caller allows that, then skip it and
                    // continue.  This ensures we get back on track and don't result in tons of
                    // parse errors.  For example, this can happen when people do things like use
                    // a semicolon to delimit object literal members.   Note: we'll have already
                    // reported an error when we called parseExpected above.
                    if (considerSemicolonAsDelimiter && token() === 26 /* SemicolonToken */ && !scanner.hasPrecedingLineBreak()) {
                        nextToken();
                    }
                    if (startPos === scanner.getStartPos()) {
                        // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever
                        // Consume a token to advance the parser in some way and avoid an infinite loop
                        // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions,
                        // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied
                        nextToken();
                    }
                    continue;
                }
                if (isListTerminator(kind)) {
                    break;
                }
                if (abortParsingListOrMoveToNextToken(kind)) {
                    break;
                }
            }
            parsingContext = saveParsingContext;
            var result = createNodeArray(list, listPos);
            // Recording the trailing comma is deliberately done after the previous
            // loop, and not just if we see a list terminator. This is because the list
            // may have ended incorrectly, but it is still important to know if there
            // was a trailing comma.
            // Check if the last token was a comma.
            if (commaStart >= 0) {
                // Always preserve a trailing comma by marking it on the NodeArray
                result.hasTrailingComma = true;
            }
            return result;
        }
        function getExpectedCommaDiagnostic(kind) {
            return kind === 6 /* EnumMembers */ ? ts.Diagnostics.An_enum_member_name_must_be_followed_by_a_or : undefined;
        }
        function createMissingList() {
            var list = createNodeArray([], getNodePos());
            list.isMissingList = true;
            return list;
        }
        function isMissingList(arr) {
            return !!arr.isMissingList;
        }
        function parseBracketedList(kind, parseElement, open, close) {
            if (parseExpected(open)) {
                var result = parseDelimitedList(kind, parseElement);
                parseExpected(close);
                return result;
            }
            return createMissingList();
        }
        function parseEntityName(allowReservedWords, diagnosticMessage) {
            var entity = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage);
            var dotPos = scanner.getStartPos();
            while (parseOptional(24 /* DotToken */)) {
                if (token() === 29 /* LessThanToken */) {
                    // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting
                    entity.jsdocDotPos = dotPos;
                    break;
                }
                dotPos = scanner.getStartPos();
                entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false));
            }
            return entity;
        }
        function createQualifiedName(entity, name) {
            var node = createNode(153 /* QualifiedName */, entity.pos);
            node.left = entity;
            node.right = name;
            return finishNode(node);
        }
        function parseRightSideOfDot(allowIdentifierNames, allowPrivateIdentifiers) {
            // Technically a keyword is valid here as all identifiers and keywords are identifier names.
            // However, often we'll encounter this in error situations when the identifier or keyword
            // is actually starting another valid construct.
            //
            // So, we check for the following specific case:
            //
            //      name.
            //      identifierOrKeyword identifierNameOrKeyword
            //
            // Note: the newlines are important here.  For example, if that above code
            // were rewritten into:
            //
            //      name.identifierOrKeyword
            //      identifierNameOrKeyword
            //
            // Then we would consider it valid.  That's because ASI would take effect and
            // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword".
            // In the first case though, ASI will not take effect because there is not a
            // line terminator after the identifier or keyword.
            if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token())) {
                var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
                if (matchesPattern) {
                    // Report that we need an identifier.  However, report it right after the dot,
                    // and not on the next token.  This is because the next token might actually
                    // be an identifier and the error would be quite confusing.
                    return createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
                }
            }
            if (token() === 76 /* PrivateIdentifier */) {
                var node = parsePrivateIdentifier();
                return allowPrivateIdentifiers ? node : createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected);
            }
            return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
        }
        function parseTemplateExpression(isTaggedTemplate) {
            var template = createNode(211 /* TemplateExpression */);
            template.head = parseTemplateHead(isTaggedTemplate);
            ts.Debug.assert(template.head.kind === 15 /* TemplateHead */, "Template head has wrong token kind");
            var list = [];
            var listPos = getNodePos();
            do {
                list.push(parseTemplateSpan(isTaggedTemplate));
            } while (ts.last(list).literal.kind === 16 /* TemplateMiddle */);
            template.templateSpans = createNodeArray(list, listPos);
            return finishNode(template);
        }
        function parseTemplateSpan(isTaggedTemplate) {
            var span = createNode(221 /* TemplateSpan */);
            span.expression = allowInAnd(parseExpression);
            var literal;
            if (token() === 19 /* CloseBraceToken */) {
                reScanTemplateToken(isTaggedTemplate);
                literal = parseTemplateMiddleOrTemplateTail();
            }
            else {
                literal = parseExpectedToken(17 /* TemplateTail */, ts.Diagnostics._0_expected, ts.tokenToString(19 /* CloseBraceToken */));
            }
            span.literal = literal;
            return finishNode(span);
        }
        function parseLiteralNode() {
            return parseLiteralLikeNode(token());
        }
        function parseTemplateHead(isTaggedTemplate) {
            if (isTaggedTemplate) {
                reScanTemplateHeadOrNoSubstitutionTemplate();
            }
            var fragment = parseLiteralLikeNode(token());
            ts.Debug.assert(fragment.kind === 15 /* TemplateHead */, "Template head has wrong token kind");
            return fragment;
        }
        function parseTemplateMiddleOrTemplateTail() {
            var fragment = parseLiteralLikeNode(token());
            ts.Debug.assert(fragment.kind === 16 /* TemplateMiddle */ || fragment.kind === 17 /* TemplateTail */, "Template fragment has wrong token kind");
            return fragment;
        }
        function parseLiteralLikeNode(kind) {
            var node = createNode(kind);
            node.text = scanner.getTokenValue();
            switch (kind) {
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 15 /* TemplateHead */:
                case 16 /* TemplateMiddle */:
                case 17 /* TemplateTail */:
                    var isLast = kind === 14 /* NoSubstitutionTemplateLiteral */ || kind === 17 /* TemplateTail */;
                    var tokenText = scanner.getTokenText();
                    node.rawText = tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2));
                    break;
            }
            if (scanner.hasExtendedUnicodeEscape()) {
                node.hasExtendedUnicodeEscape = true;
            }
            if (scanner.isUnterminated()) {
                node.isUnterminated = true;
            }
            // Octal literals are not allowed in strict mode or ES5
            // Note that theoretically the following condition would hold true literals like 009,
            // which is not octal.But because of how the scanner separates the tokens, we would
            // never get a token like this. Instead, we would get 00 and 9 as two separate tokens.
            // We also do not need to check for negatives because any prefix operator would be part of a
            // parent unary expression.
            if (node.kind === 8 /* NumericLiteral */) {
                node.numericLiteralFlags = scanner.getTokenFlags() & 1008 /* NumericLiteralFlags */;
            }
            if (ts.isTemplateLiteralKind(node.kind)) {
                node.templateFlags = scanner.getTokenFlags() & 2048 /* ContainsInvalidEscape */;
            }
            nextToken();
            finishNode(node);
            return node;
        }
        // TYPES
        function parseTypeReference() {
            var node = createNode(169 /* TypeReference */);
            node.typeName = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected);
            if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === 29 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(20 /* TypeArguments */, parseType, 29 /* LessThanToken */, 31 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        // If true, we should abort parsing an error function.
        function typeHasArrowFunctionBlockingParseError(node) {
            switch (node.kind) {
                case 169 /* TypeReference */:
                    return ts.nodeIsMissing(node.typeName);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */: {
                    var _a = node, parameters = _a.parameters, type = _a.type;
                    return isMissingList(parameters) || typeHasArrowFunctionBlockingParseError(type);
                }
                case 182 /* ParenthesizedType */:
                    return typeHasArrowFunctionBlockingParseError(node.type);
                default:
                    return false;
            }
        }
        function parseThisTypePredicate(lhs) {
            nextToken();
            var node = createNode(168 /* TypePredicate */, lhs.pos);
            node.parameterName = lhs;
            node.type = parseType();
            return finishNode(node);
        }
        function parseThisTypeNode() {
            var node = createNode(183 /* ThisType */);
            nextToken();
            return finishNode(node);
        }
        function parseJSDocAllType(postFixEquals) {
            var result = createNode(295 /* JSDocAllType */);
            if (postFixEquals) {
                return createPostfixType(299 /* JSDocOptionalType */, result);
            }
            else {
                nextToken();
            }
            return finishNode(result);
        }
        function parseJSDocNonNullableType() {
            var result = createNode(298 /* JSDocNonNullableType */);
            nextToken();
            result.type = parseNonArrayType();
            return finishNode(result);
        }
        function parseJSDocUnknownOrNullableType() {
            var pos = scanner.getStartPos();
            // skip the ?
            nextToken();
            // Need to lookahead to decide if this is a nullable or unknown type.
            // Here are cases where we'll pick the unknown type:
            //
            //      Foo(?,
            //      { a: ? }
            //      Foo(?)
            //      Foo<?>
            //      Foo(?=
            //      (?|
            if (token() === 27 /* CommaToken */ ||
                token() === 19 /* CloseBraceToken */ ||
                token() === 21 /* CloseParenToken */ ||
                token() === 31 /* GreaterThanToken */ ||
                token() === 62 /* EqualsToken */ ||
                token() === 51 /* BarToken */) {
                var result = createNode(296 /* JSDocUnknownType */, pos);
                return finishNode(result);
            }
            else {
                var result = createNode(297 /* JSDocNullableType */, pos);
                result.type = parseType();
                return finishNode(result);
            }
        }
        function parseJSDocFunctionType() {
            if (lookAhead(nextTokenIsOpenParen)) {
                var result = createNodeWithJSDoc(300 /* JSDocFunctionType */);
                nextToken();
                fillSignature(58 /* ColonToken */, 4 /* Type */ | 32 /* JSDoc */, result);
                return finishNode(result);
            }
            var node = createNode(169 /* TypeReference */);
            node.typeName = parseIdentifierName();
            return finishNode(node);
        }
        function parseJSDocParameter() {
            var parameter = createNode(156 /* Parameter */);
            if (token() === 104 /* ThisKeyword */ || token() === 99 /* NewKeyword */) {
                parameter.name = parseIdentifierName();
                parseExpected(58 /* ColonToken */);
            }
            parameter.type = parseJSDocType();
            return finishNode(parameter);
        }
        function parseJSDocType() {
            scanner.setInJSDocType(true);
            var moduleSpecifier = parseOptionalToken(135 /* ModuleKeyword */);
            if (moduleSpecifier) {
                var moduleTag = createNode(302 /* JSDocNamepathType */, moduleSpecifier.pos);
                terminate: while (true) {
                    switch (token()) {
                        case 19 /* CloseBraceToken */:
                        case 1 /* EndOfFileToken */:
                        case 27 /* CommaToken */:
                        case 5 /* WhitespaceTrivia */:
                            break terminate;
                        default:
                            nextTokenJSDoc();
                    }
                }
                scanner.setInJSDocType(false);
                return finishNode(moduleTag);
            }
            var dotdotdot = parseOptionalToken(25 /* DotDotDotToken */);
            var type = parseTypeOrTypePredicate();
            scanner.setInJSDocType(false);
            if (dotdotdot) {
                var variadic = createNode(301 /* JSDocVariadicType */, dotdotdot.pos);
                variadic.type = type;
                type = finishNode(variadic);
            }
            if (token() === 62 /* EqualsToken */) {
                return createPostfixType(299 /* JSDocOptionalType */, type);
            }
            return type;
        }
        function parseTypeQuery() {
            var node = createNode(172 /* TypeQuery */);
            parseExpected(108 /* TypeOfKeyword */);
            node.exprName = parseEntityName(/*allowReservedWords*/ true);
            return finishNode(node);
        }
        function parseTypeParameter() {
            var node = createNode(155 /* TypeParameter */);
            node.name = parseIdentifier();
            if (parseOptional(90 /* ExtendsKeyword */)) {
                // It's not uncommon for people to write improper constraints to a generic.  If the
                // user writes a constraint that is an expression and not an actual type, then parse
                // it out as an expression (so we can recover well), but report that a type is needed
                // instead.
                if (isStartOfType() || !isStartOfExpression()) {
                    node.constraint = parseType();
                }
                else {
                    // It was not a type, and it looked like an expression.  Parse out an expression
                    // here so we recover well.  Note: it is important that we call parseUnaryExpression
                    // and not parseExpression here.  If the user has:
                    //
                    //      <T extends "">
                    //
                    // We do *not* want to consume the `>` as we're consuming the expression for "".
                    node.expression = parseUnaryExpressionOrHigher();
                }
            }
            if (parseOptional(62 /* EqualsToken */)) {
                node.default = parseType();
            }
            return finishNode(node);
        }
        function parseTypeParameters() {
            if (token() === 29 /* LessThanToken */) {
                return parseBracketedList(19 /* TypeParameters */, parseTypeParameter, 29 /* LessThanToken */, 31 /* GreaterThanToken */);
            }
        }
        function parseParameterType() {
            if (parseOptional(58 /* ColonToken */)) {
                return parseType();
            }
            return undefined;
        }
        function isStartOfParameter(isJSDocParameter) {
            return token() === 25 /* DotDotDotToken */ ||
                isIdentifierOrPrivateIdentifierOrPattern() ||
                ts.isModifierKind(token()) ||
                token() === 59 /* AtToken */ ||
                isStartOfType(/*inStartOfParameter*/ !isJSDocParameter);
        }
        function parseParameter() {
            var node = createNodeWithJSDoc(156 /* Parameter */);
            if (token() === 104 /* ThisKeyword */) {
                node.name = createIdentifier(/*isIdentifier*/ true);
                node.type = parseParameterType();
                return finishNode(node);
            }
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            // FormalParameter [Yield,Await]:
            //      BindingElement[?Yield,?Await]
            node.name = parseIdentifierOrPattern(ts.Diagnostics.Private_identifiers_cannot_be_used_as_parameters);
            if (ts.getFullWidth(node.name) === 0 && !node.modifiers && ts.isModifierKind(token())) {
                // in cases like
                // 'use strict'
                // function foo(static)
                // isParameter('static') === true, because of isModifier('static')
                // however 'static' is not a legal identifier in a strict mode.
                // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined)
                // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM)
                // to avoid this we'll advance cursor to the next token.
                nextToken();
            }
            node.questionToken = parseOptionalToken(57 /* QuestionToken */);
            node.type = parseParameterType();
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        /**
         * Note: If returnToken is EqualsGreaterThanToken, `signature.type` will always be defined.
         * @returns If return type parsing succeeds
         */
        function fillSignature(returnToken, flags, signature) {
            if (!(flags & 32 /* JSDoc */)) {
                signature.typeParameters = parseTypeParameters();
            }
            var parametersParsedSuccessfully = parseParameterList(signature, flags);
            if (shouldParseReturnType(returnToken, !!(flags & 4 /* Type */))) {
                signature.type = parseTypeOrTypePredicate();
                if (typeHasArrowFunctionBlockingParseError(signature.type))
                    return false;
            }
            return parametersParsedSuccessfully;
        }
        function shouldParseReturnType(returnToken, isType) {
            if (returnToken === 38 /* EqualsGreaterThanToken */) {
                parseExpected(returnToken);
                return true;
            }
            else if (parseOptional(58 /* ColonToken */)) {
                return true;
            }
            else if (isType && token() === 38 /* EqualsGreaterThanToken */) {
                // This is easy to get backward, especially in type contexts, so parse the type anyway
                parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(58 /* ColonToken */));
                nextToken();
                return true;
            }
            return false;
        }
        // Returns true on success.
        function parseParameterList(signature, flags) {
            // FormalParameters [Yield,Await]: (modified)
            //      [empty]
            //      FormalParameterList[?Yield,Await]
            //
            // FormalParameter[Yield,Await]: (modified)
            //      BindingElement[?Yield,Await]
            //
            // BindingElement [Yield,Await]: (modified)
            //      SingleNameBinding[?Yield,?Await]
            //      BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
            //
            // SingleNameBinding [Yield,Await]:
            //      BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
            if (!parseExpected(20 /* OpenParenToken */)) {
                signature.parameters = createMissingList();
                return false;
            }
            var savedYieldContext = inYieldContext();
            var savedAwaitContext = inAwaitContext();
            setYieldContext(!!(flags & 1 /* Yield */));
            setAwaitContext(!!(flags & 2 /* Await */));
            signature.parameters = flags & 32 /* JSDoc */ ?
                parseDelimitedList(17 /* JSDocParameters */, parseJSDocParameter) :
                parseDelimitedList(16 /* Parameters */, parseParameter);
            setYieldContext(savedYieldContext);
            setAwaitContext(savedAwaitContext);
            return parseExpected(21 /* CloseParenToken */);
        }
        function parseTypeMemberSemicolon() {
            // We allow type members to be separated by commas or (possibly ASI) semicolons.
            // First check if it was a comma.  If so, we're done with the member.
            if (parseOptional(27 /* CommaToken */)) {
                return;
            }
            // Didn't have a comma.  We must have a (possible ASI) semicolon.
            parseSemicolon();
        }
        function parseSignatureMember(kind) {
            var node = createNodeWithJSDoc(kind);
            if (kind === 166 /* ConstructSignature */) {
                parseExpected(99 /* NewKeyword */);
            }
            fillSignature(58 /* ColonToken */, 4 /* Type */, node);
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function isIndexSignature() {
            return token() === 22 /* OpenBracketToken */ && lookAhead(isUnambiguouslyIndexSignature);
        }
        function isUnambiguouslyIndexSignature() {
            // The only allowed sequence is:
            //
            //   [id:
            //
            // However, for error recovery, we also check the following cases:
            //
            //   [...
            //   [id,
            //   [id?,
            //   [id?:
            //   [id?]
            //   [public id
            //   [private id
            //   [protected id
            //   []
            //
            nextToken();
            if (token() === 25 /* DotDotDotToken */ || token() === 23 /* CloseBracketToken */) {
                return true;
            }
            if (ts.isModifierKind(token())) {
                nextToken();
                if (isIdentifier()) {
                    return true;
                }
            }
            else if (!isIdentifier()) {
                return false;
            }
            else {
                // Skip the identifier
                nextToken();
            }
            // A colon signifies a well formed indexer
            // A comma should be a badly formed indexer because comma expressions are not allowed
            // in computed properties.
            if (token() === 58 /* ColonToken */ || token() === 27 /* CommaToken */) {
                return true;
            }
            // Question mark could be an indexer with an optional property,
            // or it could be a conditional expression in a computed property.
            if (token() !== 57 /* QuestionToken */) {
                return false;
            }
            // If any of the following tokens are after the question mark, it cannot
            // be a conditional expression, so treat it as an indexer.
            nextToken();
            return token() === 58 /* ColonToken */ || token() === 27 /* CommaToken */ || token() === 23 /* CloseBracketToken */;
        }
        function parseIndexSignatureDeclaration(node) {
            node.kind = 167 /* IndexSignature */;
            node.parameters = parseBracketedList(16 /* Parameters */, parseParameter, 22 /* OpenBracketToken */, 23 /* CloseBracketToken */);
            node.type = parseTypeAnnotation();
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function parsePropertyOrMethodSignature(node) {
            node.name = parsePropertyName();
            node.questionToken = parseOptionalToken(57 /* QuestionToken */);
            if (token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                node.kind = 160 /* MethodSignature */;
                // Method signatures don't exist in expression contexts.  So they have neither
                // [Yield] nor [Await]
                fillSignature(58 /* ColonToken */, 4 /* Type */, node);
            }
            else {
                node.kind = 158 /* PropertySignature */;
                node.type = parseTypeAnnotation();
                if (token() === 62 /* EqualsToken */) {
                    // Although type literal properties cannot not have initializers, we attempt
                    // to parse an initializer so we can report in the checker that an interface
                    // property or type literal property cannot have an initializer.
                    node.initializer = parseInitializer();
                }
            }
            parseTypeMemberSemicolon();
            return finishNode(node);
        }
        function isTypeMemberStart() {
            // Return true if we have the start of a signature member
            if (token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                return true;
            }
            var idToken = false;
            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier
            while (ts.isModifierKind(token())) {
                idToken = true;
                nextToken();
            }
            // Index signatures and computed property names are type members
            if (token() === 22 /* OpenBracketToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers
            if (isLiteralPropertyName()) {
                idToken = true;
                nextToken();
            }
            // If we were able to get any potential identifier, check that it is
            // the start of a member declaration
            if (idToken) {
                return token() === 20 /* OpenParenToken */ ||
                    token() === 29 /* LessThanToken */ ||
                    token() === 57 /* QuestionToken */ ||
                    token() === 58 /* ColonToken */ ||
                    token() === 27 /* CommaToken */ ||
                    canParseSemicolon();
            }
            return false;
        }
        function parseTypeMember() {
            if (token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                return parseSignatureMember(165 /* CallSignature */);
            }
            if (token() === 99 /* NewKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) {
                return parseSignatureMember(166 /* ConstructSignature */);
            }
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.modifiers = parseModifiers();
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(node);
            }
            return parsePropertyOrMethodSignature(node);
        }
        function nextTokenIsOpenParenOrLessThan() {
            nextToken();
            return token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */;
        }
        function nextTokenIsDot() {
            return nextToken() === 24 /* DotToken */;
        }
        function nextTokenIsOpenParenOrLessThanOrDot() {
            switch (nextToken()) {
                case 20 /* OpenParenToken */:
                case 29 /* LessThanToken */:
                case 24 /* DotToken */:
                    return true;
            }
            return false;
        }
        function parseTypeLiteral() {
            var node = createNode(173 /* TypeLiteral */);
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseObjectTypeMembers() {
            var members;
            if (parseExpected(18 /* OpenBraceToken */)) {
                members = parseList(4 /* TypeMembers */, parseTypeMember);
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                members = createMissingList();
            }
            return members;
        }
        function isStartOfMappedType() {
            nextToken();
            if (token() === 39 /* PlusToken */ || token() === 40 /* MinusToken */) {
                return nextToken() === 138 /* ReadonlyKeyword */;
            }
            if (token() === 138 /* ReadonlyKeyword */) {
                nextToken();
            }
            return token() === 22 /* OpenBracketToken */ && nextTokenIsIdentifier() && nextToken() === 97 /* InKeyword */;
        }
        function parseMappedTypeParameter() {
            var node = createNode(155 /* TypeParameter */);
            node.name = parseIdentifier();
            parseExpected(97 /* InKeyword */);
            node.constraint = parseType();
            return finishNode(node);
        }
        function parseMappedType() {
            var node = createNode(186 /* MappedType */);
            parseExpected(18 /* OpenBraceToken */);
            if (token() === 138 /* ReadonlyKeyword */ || token() === 39 /* PlusToken */ || token() === 40 /* MinusToken */) {
                node.readonlyToken = parseTokenNode();
                if (node.readonlyToken.kind !== 138 /* ReadonlyKeyword */) {
                    parseExpectedToken(138 /* ReadonlyKeyword */);
                }
            }
            parseExpected(22 /* OpenBracketToken */);
            node.typeParameter = parseMappedTypeParameter();
            parseExpected(23 /* CloseBracketToken */);
            if (token() === 57 /* QuestionToken */ || token() === 39 /* PlusToken */ || token() === 40 /* MinusToken */) {
                node.questionToken = parseTokenNode();
                if (node.questionToken.kind !== 57 /* QuestionToken */) {
                    parseExpectedToken(57 /* QuestionToken */);
                }
            }
            node.type = parseTypeAnnotation();
            parseSemicolon();
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseTupleElementType() {
            var pos = getNodePos();
            if (parseOptional(25 /* DotDotDotToken */)) {
                var node = createNode(177 /* RestType */, pos);
                node.type = parseType();
                return finishNode(node);
            }
            var type = parseType();
            if (!(contextFlags & 4194304 /* JSDoc */) && type.kind === 297 /* JSDocNullableType */ && type.pos === type.type.pos) {
                type.kind = 176 /* OptionalType */;
            }
            return type;
        }
        function parseTupleType() {
            var node = createNode(175 /* TupleType */);
            node.elementTypes = parseBracketedList(21 /* TupleElementTypes */, parseTupleElementType, 22 /* OpenBracketToken */, 23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseParenthesizedType() {
            var node = createNode(182 /* ParenthesizedType */);
            parseExpected(20 /* OpenParenToken */);
            node.type = parseType();
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseFunctionOrConstructorType() {
            var pos = getNodePos();
            var kind = parseOptional(99 /* NewKeyword */) ? 171 /* ConstructorType */ : 170 /* FunctionType */;
            var node = createNodeWithJSDoc(kind, pos);
            fillSignature(38 /* EqualsGreaterThanToken */, 4 /* Type */, node);
            return finishNode(node);
        }
        function parseKeywordAndNoDot() {
            var node = parseTokenNode();
            return token() === 24 /* DotToken */ ? undefined : node;
        }
        function parseLiteralTypeNode(negative) {
            var node = createNode(187 /* LiteralType */);
            var unaryMinusExpression;
            if (negative) {
                unaryMinusExpression = createNode(207 /* PrefixUnaryExpression */);
                unaryMinusExpression.operator = 40 /* MinusToken */;
                nextToken();
            }
            var expression = token() === 106 /* TrueKeyword */ || token() === 91 /* FalseKeyword */
                ? parseTokenNode()
                : parseLiteralLikeNode(token());
            if (negative) {
                unaryMinusExpression.operand = expression;
                finishNode(unaryMinusExpression);
                expression = unaryMinusExpression;
            }
            node.literal = expression;
            return finishNode(node);
        }
        function isStartOfTypeOfImportType() {
            nextToken();
            return token() === 96 /* ImportKeyword */;
        }
        function parseImportType() {
            sourceFile.flags |= 1048576 /* PossiblyContainsDynamicImport */;
            var node = createNode(188 /* ImportType */);
            if (parseOptional(108 /* TypeOfKeyword */)) {
                node.isTypeOf = true;
            }
            parseExpected(96 /* ImportKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.argument = parseType();
            parseExpected(21 /* CloseParenToken */);
            if (parseOptional(24 /* DotToken */)) {
                node.qualifier = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected);
            }
            if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === 29 /* LessThanToken */) {
                node.typeArguments = parseBracketedList(20 /* TypeArguments */, parseType, 29 /* LessThanToken */, 31 /* GreaterThanToken */);
            }
            return finishNode(node);
        }
        function nextTokenIsNumericOrBigIntLiteral() {
            nextToken();
            return token() === 8 /* NumericLiteral */ || token() === 9 /* BigIntLiteral */;
        }
        function parseNonArrayType() {
            switch (token()) {
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 143 /* StringKeyword */:
                case 140 /* NumberKeyword */:
                case 151 /* BigIntKeyword */:
                case 144 /* SymbolKeyword */:
                case 128 /* BooleanKeyword */:
                case 146 /* UndefinedKeyword */:
                case 137 /* NeverKeyword */:
                case 141 /* ObjectKeyword */:
                    // If these are followed by a dot, then parse these out as a dotted type reference instead.
                    return tryParse(parseKeywordAndNoDot) || parseTypeReference();
                case 41 /* AsteriskToken */:
                    return parseJSDocAllType(/*postfixEquals*/ false);
                case 65 /* AsteriskEqualsToken */:
                    return parseJSDocAllType(/*postfixEquals*/ true);
                case 60 /* QuestionQuestionToken */:
                    // If there is '??', consider that is prefix '?' in JSDoc type.
                    scanner.reScanQuestionToken();
                // falls through
                case 57 /* QuestionToken */:
                    return parseJSDocUnknownOrNullableType();
                case 94 /* FunctionKeyword */:
                    return parseJSDocFunctionType();
                case 53 /* ExclamationToken */:
                    return parseJSDocNonNullableType();
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                    return parseLiteralTypeNode();
                case 40 /* MinusToken */:
                    return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
                case 110 /* VoidKeyword */:
                case 100 /* NullKeyword */:
                    return parseTokenNode();
                case 104 /* ThisKeyword */: {
                    var thisKeyword = parseThisTypeNode();
                    if (token() === 133 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                        return parseThisTypePredicate(thisKeyword);
                    }
                    else {
                        return thisKeyword;
                    }
                }
                case 108 /* TypeOfKeyword */:
                    return lookAhead(isStartOfTypeOfImportType) ? parseImportType() : parseTypeQuery();
                case 18 /* OpenBraceToken */:
                    return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral();
                case 22 /* OpenBracketToken */:
                    return parseTupleType();
                case 20 /* OpenParenToken */:
                    return parseParenthesizedType();
                case 96 /* ImportKeyword */:
                    return parseImportType();
                case 124 /* AssertsKeyword */:
                    return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? parseAssertsTypePredicate() : parseTypeReference();
                default:
                    return parseTypeReference();
            }
        }
        function isStartOfType(inStartOfParameter) {
            switch (token()) {
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 143 /* StringKeyword */:
                case 140 /* NumberKeyword */:
                case 151 /* BigIntKeyword */:
                case 128 /* BooleanKeyword */:
                case 138 /* ReadonlyKeyword */:
                case 144 /* SymbolKeyword */:
                case 147 /* UniqueKeyword */:
                case 110 /* VoidKeyword */:
                case 146 /* UndefinedKeyword */:
                case 100 /* NullKeyword */:
                case 104 /* ThisKeyword */:
                case 108 /* TypeOfKeyword */:
                case 137 /* NeverKeyword */:
                case 18 /* OpenBraceToken */:
                case 22 /* OpenBracketToken */:
                case 29 /* LessThanToken */:
                case 51 /* BarToken */:
                case 50 /* AmpersandToken */:
                case 99 /* NewKeyword */:
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 141 /* ObjectKeyword */:
                case 41 /* AsteriskToken */:
                case 57 /* QuestionToken */:
                case 53 /* ExclamationToken */:
                case 25 /* DotDotDotToken */:
                case 132 /* InferKeyword */:
                case 96 /* ImportKeyword */:
                case 124 /* AssertsKeyword */:
                    return true;
                case 94 /* FunctionKeyword */:
                    return !inStartOfParameter;
                case 40 /* MinusToken */:
                    return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral);
                case 20 /* OpenParenToken */:
                    // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
                    // or something that starts a type. We don't want to consider things like '(1)' a type.
                    return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfParenthesizedOrFunctionType() {
            nextToken();
            return token() === 21 /* CloseParenToken */ || isStartOfParameter(/*isJSDocParameter*/ false) || isStartOfType();
        }
        function parsePostfixTypeOrHigher() {
            var type = parseNonArrayType();
            while (!scanner.hasPrecedingLineBreak()) {
                switch (token()) {
                    case 53 /* ExclamationToken */:
                        type = createPostfixType(298 /* JSDocNonNullableType */, type);
                        break;
                    case 57 /* QuestionToken */:
                        // If not in JSDoc and next token is start of a type we have a conditional type
                        if (!(contextFlags & 4194304 /* JSDoc */) && lookAhead(nextTokenIsStartOfType)) {
                            return type;
                        }
                        type = createPostfixType(297 /* JSDocNullableType */, type);
                        break;
                    case 22 /* OpenBracketToken */:
                        parseExpected(22 /* OpenBracketToken */);
                        if (isStartOfType()) {
                            var node = createNode(185 /* IndexedAccessType */, type.pos);
                            node.objectType = type;
                            node.indexType = parseType();
                            parseExpected(23 /* CloseBracketToken */);
                            type = finishNode(node);
                        }
                        else {
                            var node = createNode(174 /* ArrayType */, type.pos);
                            node.elementType = type;
                            parseExpected(23 /* CloseBracketToken */);
                            type = finishNode(node);
                        }
                        break;
                    default:
                        return type;
                }
            }
            return type;
        }
        function createPostfixType(kind, type) {
            nextToken();
            var postfix = createNode(kind, type.pos);
            postfix.type = type;
            return finishNode(postfix);
        }
        function parseTypeOperator(operator) {
            var node = createNode(184 /* TypeOperator */);
            parseExpected(operator);
            node.operator = operator;
            node.type = parseTypeOperatorOrHigher();
            return finishNode(node);
        }
        function parseInferType() {
            var node = createNode(181 /* InferType */);
            parseExpected(132 /* InferKeyword */);
            var typeParameter = createNode(155 /* TypeParameter */);
            typeParameter.name = parseIdentifier();
            node.typeParameter = finishNode(typeParameter);
            return finishNode(node);
        }
        function parseTypeOperatorOrHigher() {
            var operator = token();
            switch (operator) {
                case 134 /* KeyOfKeyword */:
                case 147 /* UniqueKeyword */:
                case 138 /* ReadonlyKeyword */:
                    return parseTypeOperator(operator);
                case 132 /* InferKeyword */:
                    return parseInferType();
            }
            return parsePostfixTypeOrHigher();
        }
        function parseUnionOrIntersectionType(kind, parseConstituentType, operator) {
            var start = scanner.getStartPos();
            var hasLeadingOperator = parseOptional(operator);
            var type = parseConstituentType();
            if (token() === operator || hasLeadingOperator) {
                var types = [type];
                while (parseOptional(operator)) {
                    types.push(parseConstituentType());
                }
                var node = createNode(kind, start);
                node.types = createNodeArray(types, start);
                type = finishNode(node);
            }
            return type;
        }
        function parseIntersectionTypeOrHigher() {
            return parseUnionOrIntersectionType(179 /* IntersectionType */, parseTypeOperatorOrHigher, 50 /* AmpersandToken */);
        }
        function parseUnionTypeOrHigher() {
            return parseUnionOrIntersectionType(178 /* UnionType */, parseIntersectionTypeOrHigher, 51 /* BarToken */);
        }
        function isStartOfFunctionType() {
            if (token() === 29 /* LessThanToken */) {
                return true;
            }
            return token() === 20 /* OpenParenToken */ && lookAhead(isUnambiguouslyStartOfFunctionType);
        }
        function skipParameterStart() {
            if (ts.isModifierKind(token())) {
                // Skip modifiers
                parseModifiers();
            }
            if (isIdentifier() || token() === 104 /* ThisKeyword */) {
                nextToken();
                return true;
            }
            if (token() === 22 /* OpenBracketToken */ || token() === 18 /* OpenBraceToken */) {
                // Return true if we can parse an array or object binding pattern with no errors
                var previousErrorCount = parseDiagnostics.length;
                parseIdentifierOrPattern();
                return previousErrorCount === parseDiagnostics.length;
            }
            return false;
        }
        function isUnambiguouslyStartOfFunctionType() {
            nextToken();
            if (token() === 21 /* CloseParenToken */ || token() === 25 /* DotDotDotToken */) {
                // ( )
                // ( ...
                return true;
            }
            if (skipParameterStart()) {
                // We successfully skipped modifiers (if any) and an identifier or binding pattern,
                // now see if we have something that indicates a parameter declaration
                if (token() === 58 /* ColonToken */ || token() === 27 /* CommaToken */ ||
                    token() === 57 /* QuestionToken */ || token() === 62 /* EqualsToken */) {
                    // ( xxx :
                    // ( xxx ,
                    // ( xxx ?
                    // ( xxx =
                    return true;
                }
                if (token() === 21 /* CloseParenToken */) {
                    nextToken();
                    if (token() === 38 /* EqualsGreaterThanToken */) {
                        // ( xxx ) =>
                        return true;
                    }
                }
            }
            return false;
        }
        function parseTypeOrTypePredicate() {
            var typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix);
            var type = parseType();
            if (typePredicateVariable) {
                var node = createNode(168 /* TypePredicate */, typePredicateVariable.pos);
                node.assertsModifier = undefined;
                node.parameterName = typePredicateVariable;
                node.type = type;
                return finishNode(node);
            }
            else {
                return type;
            }
        }
        function parseTypePredicatePrefix() {
            var id = parseIdentifier();
            if (token() === 133 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) {
                nextToken();
                return id;
            }
        }
        function parseAssertsTypePredicate() {
            var node = createNode(168 /* TypePredicate */);
            node.assertsModifier = parseExpectedToken(124 /* AssertsKeyword */);
            node.parameterName = token() === 104 /* ThisKeyword */ ? parseThisTypeNode() : parseIdentifier();
            node.type = parseOptional(133 /* IsKeyword */) ? parseType() : undefined;
            return finishNode(node);
        }
        function parseType() {
            // The rules about 'yield' only apply to actual code/expression contexts.  They don't
            // apply to 'type' contexts.  So we disable these parameters here before moving on.
            return doOutsideOfContext(40960 /* TypeExcludesFlags */, parseTypeWorker);
        }
        function parseTypeWorker(noConditionalTypes) {
            if (isStartOfFunctionType() || token() === 99 /* NewKeyword */) {
                return parseFunctionOrConstructorType();
            }
            var type = parseUnionTypeOrHigher();
            if (!noConditionalTypes && !scanner.hasPrecedingLineBreak() && parseOptional(90 /* ExtendsKeyword */)) {
                var node = createNode(180 /* ConditionalType */, type.pos);
                node.checkType = type;
                // The type following 'extends' is not permitted to be another conditional type
                node.extendsType = parseTypeWorker(/*noConditionalTypes*/ true);
                parseExpected(57 /* QuestionToken */);
                node.trueType = parseTypeWorker();
                parseExpected(58 /* ColonToken */);
                node.falseType = parseTypeWorker();
                return finishNode(node);
            }
            return type;
        }
        function parseTypeAnnotation() {
            return parseOptional(58 /* ColonToken */) ? parseType() : undefined;
        }
        // EXPRESSIONS
        function isStartOfLeftHandSideExpression() {
            switch (token()) {
                case 104 /* ThisKeyword */:
                case 102 /* SuperKeyword */:
                case 100 /* NullKeyword */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 15 /* TemplateHead */:
                case 20 /* OpenParenToken */:
                case 22 /* OpenBracketToken */:
                case 18 /* OpenBraceToken */:
                case 94 /* FunctionKeyword */:
                case 80 /* ClassKeyword */:
                case 99 /* NewKeyword */:
                case 43 /* SlashToken */:
                case 67 /* SlashEqualsToken */:
                case 75 /* Identifier */:
                    return true;
                case 96 /* ImportKeyword */:
                    return lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
                default:
                    return isIdentifier();
            }
        }
        function isStartOfExpression() {
            if (isStartOfLeftHandSideExpression()) {
                return true;
            }
            switch (token()) {
                case 39 /* PlusToken */:
                case 40 /* MinusToken */:
                case 54 /* TildeToken */:
                case 53 /* ExclamationToken */:
                case 85 /* DeleteKeyword */:
                case 108 /* TypeOfKeyword */:
                case 110 /* VoidKeyword */:
                case 45 /* PlusPlusToken */:
                case 46 /* MinusMinusToken */:
                case 29 /* LessThanToken */:
                case 127 /* AwaitKeyword */:
                case 121 /* YieldKeyword */:
                case 76 /* PrivateIdentifier */:
                    // Yield/await always starts an expression.  Either it is an identifier (in which case
                    // it is definitely an expression).  Or it's a keyword (either because we're in
                    // a generator or async function, or in strict mode (or both)) and it started a yield or await expression.
                    return true;
                default:
                    // Error tolerance.  If we see the start of some binary operator, we consider
                    // that the start of an expression.  That way we'll parse out a missing identifier,
                    // give a good message about an identifier being missing, and then consume the
                    // rest of the binary expression.
                    if (isBinaryOperator()) {
                        return true;
                    }
                    return isIdentifier();
            }
        }
        function isStartOfExpressionStatement() {
            // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement.
            return token() !== 18 /* OpenBraceToken */ &&
                token() !== 94 /* FunctionKeyword */ &&
                token() !== 80 /* ClassKeyword */ &&
                token() !== 59 /* AtToken */ &&
                isStartOfExpression();
        }
        function parseExpression() {
            // Expression[in]:
            //      AssignmentExpression[in]
            //      Expression[in] , AssignmentExpression[in]
            // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var expr = parseAssignmentExpressionOrHigher();
            var operatorToken;
            while ((operatorToken = parseOptionalToken(27 /* CommaToken */))) {
                expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher());
            }
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return expr;
        }
        function parseInitializer() {
            return parseOptional(62 /* EqualsToken */) ? parseAssignmentExpressionOrHigher() : undefined;
        }
        function parseAssignmentExpressionOrHigher() {
            //  AssignmentExpression[in,yield]:
            //      1) ConditionalExpression[?in,?yield]
            //      2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
            //      3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield]
            //      4) ArrowFunctionExpression[?in,?yield]
            //      5) AsyncArrowFunctionExpression[in,yield,await]
            //      6) [+Yield] YieldExpression[?In]
            //
            // Note: for ease of implementation we treat productions '2' and '3' as the same thing.
            // (i.e. they're both BinaryExpressions with an assignment operator in it).
            // First, do the simple check if we have a YieldExpression (production '6').
            if (isYieldExpression()) {
                return parseYieldExpression();
            }
            // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized
            // parameter list or is an async arrow function.
            // AsyncArrowFunctionExpression:
            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
            // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression".
            // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression".
            //
            // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
            // not a LeftHandSideExpression, nor does it start a ConditionalExpression.  So we are done
            // with AssignmentExpression if we see one.
            var arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression();
            if (arrowExpression) {
                return arrowExpression;
            }
            // Now try to see if we're in production '1', '2' or '3'.  A conditional expression can
            // start with a LogicalOrExpression, while the assignment productions can only start with
            // LeftHandSideExpressions.
            //
            // So, first, we try to just parse out a BinaryExpression.  If we get something that is a
            // LeftHandSide or higher, then we can try to parse out the assignment expression part.
            // Otherwise, we try to parse out the conditional expression bit.  We want to allow any
            // binary expression here, so we pass in the 'lowest' precedence here so that it matches
            // and consumes anything.
            var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
            // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized
            // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
            // identifier and the current token is an arrow.
            if (expr.kind === 75 /* Identifier */ && token() === 38 /* EqualsGreaterThanToken */) {
                return parseSimpleArrowFunctionExpression(expr);
            }
            // Now see if we might be in cases '2' or '3'.
            // If the expression was a LHS expression, and we have an assignment operator, then
            // we're in '2' or '3'. Consume the assignment and return.
            //
            // Note: we call reScanGreaterToken so that we get an appropriately merged token
            // for cases like `> > =` becoming `>>=`
            if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) {
                return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher());
            }
            // It wasn't an assignment or a lambda.  This is a conditional expression:
            return parseConditionalExpressionRest(expr);
        }
        function isYieldExpression() {
            if (token() === 121 /* YieldKeyword */) {
                // If we have a 'yield' keyword, and this is a context where yield expressions are
                // allowed, then definitely parse out a yield expression.
                if (inYieldContext()) {
                    return true;
                }
                // We're in a context where 'yield expr' is not allowed.  However, if we can
                // definitely tell that the user was trying to parse a 'yield expr' and not
                // just a normal expr that start with a 'yield' identifier, then parse out
                // a 'yield expr'.  We can then report an error later that they are only
                // allowed in generator expressions.
                //
                // for example, if we see 'yield(foo)', then we'll have to treat that as an
                // invocation expression of something called 'yield'.  However, if we have
                // 'yield foo' then that is not legal as a normal expression, so we can
                // definitely recognize this as a yield expression.
                //
                // for now we just check if the next token is an identifier.  More heuristics
                // can be added here later as necessary.  We just need to make sure that we
                // don't accidentally consume something legal.
                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
            }
            return false;
        }
        function nextTokenIsIdentifierOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && isIdentifier();
        }
        function parseYieldExpression() {
            var node = createNode(212 /* YieldExpression */);
            // YieldExpression[In] :
            //      yield
            //      yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
            //      yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield]
            nextToken();
            if (!scanner.hasPrecedingLineBreak() &&
                (token() === 41 /* AsteriskToken */ || isStartOfExpression())) {
                node.asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
                node.expression = parseAssignmentExpressionOrHigher();
                return finishNode(node);
            }
            else {
                // if the next token is not on the same line as yield.  or we don't have an '*' or
                // the start of an expression, then this is just a simple "yield" expression.
                return finishNode(node);
            }
        }
        function parseSimpleArrowFunctionExpression(identifier, asyncModifier) {
            ts.Debug.assert(token() === 38 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
            var node;
            if (asyncModifier) {
                node = createNode(202 /* ArrowFunction */, asyncModifier.pos);
                node.modifiers = asyncModifier;
            }
            else {
                node = createNode(202 /* ArrowFunction */, identifier.pos);
            }
            var parameter = createNode(156 /* Parameter */, identifier.pos);
            parameter.name = identifier;
            finishNode(parameter);
            node.parameters = createNodeArray([parameter], parameter.pos, parameter.end);
            node.equalsGreaterThanToken = parseExpectedToken(38 /* EqualsGreaterThanToken */);
            node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
            return addJSDocComment(finishNode(node));
        }
        function tryParseParenthesizedArrowFunctionExpression() {
            var triState = isParenthesizedArrowFunctionExpression();
            if (triState === 0 /* False */) {
                // It's definitely not a parenthesized arrow function expression.
                return undefined;
            }
            // If we definitely have an arrow function, then we can just parse one, not requiring a
            // following => or { token. Otherwise, we *might* have an arrow function.  Try to parse
            // it out, but don't allow any ambiguity, and return 'undefined' if this could be an
            // expression instead.
            var arrowFunction = triState === 1 /* True */
                ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true)
                : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead);
            if (!arrowFunction) {
                // Didn't appear to actually be a parenthesized arrow function.  Just bail out.
                return undefined;
            }
            var isAsync = hasModifierOfKind(arrowFunction, 126 /* AsyncKeyword */);
            // If we have an arrow, then try to parse the body. Even if not, try to parse if we
            // have an opening brace, just in case we're in an error state.
            var lastToken = token();
            arrowFunction.equalsGreaterThanToken = parseExpectedToken(38 /* EqualsGreaterThanToken */);
            arrowFunction.body = (lastToken === 38 /* EqualsGreaterThanToken */ || lastToken === 18 /* OpenBraceToken */)
                ? parseArrowFunctionExpressionBody(isAsync)
                : parseIdentifier();
            return finishNode(arrowFunction);
        }
        //  True        -> We definitely expect a parenthesized arrow function here.
        //  False       -> There *cannot* be a parenthesized arrow function here.
        //  Unknown     -> There *might* be a parenthesized arrow function here.
        //                 Speculatively look ahead to be sure, and rollback if not.
        function isParenthesizedArrowFunctionExpression() {
            if (token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */ || token() === 126 /* AsyncKeyword */) {
                return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
            }
            if (token() === 38 /* EqualsGreaterThanToken */) {
                // ERROR RECOVERY TWEAK:
                // If we see a standalone => try to parse it as an arrow function expression as that's
                // likely what the user intended to write.
                return 1 /* True */;
            }
            // Definitely not a parenthesized arrow function.
            return 0 /* False */;
        }
        function isParenthesizedArrowFunctionExpressionWorker() {
            if (token() === 126 /* AsyncKeyword */) {
                nextToken();
                if (scanner.hasPrecedingLineBreak()) {
                    return 0 /* False */;
                }
                if (token() !== 20 /* OpenParenToken */ && token() !== 29 /* LessThanToken */) {
                    return 0 /* False */;
                }
            }
            var first = token();
            var second = nextToken();
            if (first === 20 /* OpenParenToken */) {
                if (second === 21 /* CloseParenToken */) {
                    // Simple cases: "() =>", "(): ", and "() {".
                    // This is an arrow function with no parameters.
                    // The last one is not actually an arrow function,
                    // but this is probably what the user intended.
                    var third = nextToken();
                    switch (third) {
                        case 38 /* EqualsGreaterThanToken */:
                        case 58 /* ColonToken */:
                        case 18 /* OpenBraceToken */:
                            return 1 /* True */;
                        default:
                            return 0 /* False */;
                    }
                }
                // If encounter "([" or "({", this could be the start of a binding pattern.
                // Examples:
                //      ([ x ]) => { }
                //      ({ x }) => { }
                //      ([ x ])
                //      ({ x })
                if (second === 22 /* OpenBracketToken */ || second === 18 /* OpenBraceToken */) {
                    return 2 /* Unknown */;
                }
                // Simple case: "(..."
                // This is an arrow function with a rest parameter.
                if (second === 25 /* DotDotDotToken */) {
                    return 1 /* True */;
                }
                // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This
                // isn't actually allowed, but we want to treat it as a lambda so we can provide
                // a good error message.
                if (ts.isModifierKind(second) && second !== 126 /* AsyncKeyword */ && lookAhead(nextTokenIsIdentifier)) {
                    return 1 /* True */;
                }
                // If we had "(" followed by something that's not an identifier,
                // then this definitely doesn't look like a lambda.  "this" is not
                // valid, but we want to parse it and then give a semantic error.
                if (!isIdentifier() && second !== 104 /* ThisKeyword */) {
                    return 0 /* False */;
                }
                switch (nextToken()) {
                    case 58 /* ColonToken */:
                        // If we have something like "(a:", then we must have a
                        // type-annotated parameter in an arrow function expression.
                        return 1 /* True */;
                    case 57 /* QuestionToken */:
                        nextToken();
                        // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda.
                        if (token() === 58 /* ColonToken */ || token() === 27 /* CommaToken */ || token() === 62 /* EqualsToken */ || token() === 21 /* CloseParenToken */) {
                            return 1 /* True */;
                        }
                        // Otherwise it is definitely not a lambda.
                        return 0 /* False */;
                    case 27 /* CommaToken */:
                    case 62 /* EqualsToken */:
                    case 21 /* CloseParenToken */:
                        // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function
                        return 2 /* Unknown */;
                }
                // It is definitely not an arrow function
                return 0 /* False */;
            }
            else {
                ts.Debug.assert(first === 29 /* LessThanToken */);
                // If we have "<" not followed by an identifier,
                // then this definitely is not an arrow function.
                if (!isIdentifier()) {
                    return 0 /* False */;
                }
                // JSX overrides
                if (sourceFile.languageVariant === 1 /* JSX */) {
                    var isArrowFunctionInJsx = lookAhead(function () {
                        var third = nextToken();
                        if (third === 90 /* ExtendsKeyword */) {
                            var fourth = nextToken();
                            switch (fourth) {
                                case 62 /* EqualsToken */:
                                case 31 /* GreaterThanToken */:
                                    return false;
                                default:
                                    return true;
                            }
                        }
                        else if (third === 27 /* CommaToken */) {
                            return true;
                        }
                        return false;
                    });
                    if (isArrowFunctionInJsx) {
                        return 1 /* True */;
                    }
                    return 0 /* False */;
                }
                // This *could* be a parenthesized arrow function.
                return 2 /* Unknown */;
            }
        }
        function parsePossibleParenthesizedArrowFunctionExpressionHead() {
            var tokenPos = scanner.getTokenPos();
            if (notParenthesizedArrow && notParenthesizedArrow.has(tokenPos.toString())) {
                return undefined;
            }
            var result = parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false);
            if (!result) {
                (notParenthesizedArrow || (notParenthesizedArrow = ts.createMap())).set(tokenPos.toString(), true);
            }
            return result;
        }
        function tryParseAsyncSimpleArrowFunctionExpression() {
            // We do a check here so that we won't be doing unnecessarily call to "lookAhead"
            if (token() === 126 /* AsyncKeyword */) {
                if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === 1 /* True */) {
                    var asyncModifier = parseModifiersForArrowFunction();
                    var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                    return parseSimpleArrowFunctionExpression(expr, asyncModifier);
                }
            }
            return undefined;
        }
        function isUnParenthesizedAsyncArrowFunctionWorker() {
            // AsyncArrowFunctionExpression:
            //      1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In]
            //      2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
            if (token() === 126 /* AsyncKeyword */) {
                nextToken();
                // If the "async" is followed by "=>" token then it is not a beginning of an async arrow-function
                // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher"
                if (scanner.hasPrecedingLineBreak() || token() === 38 /* EqualsGreaterThanToken */) {
                    return 0 /* False */;
                }
                // Check for un-parenthesized AsyncArrowFunction
                var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0);
                if (!scanner.hasPrecedingLineBreak() && expr.kind === 75 /* Identifier */ && token() === 38 /* EqualsGreaterThanToken */) {
                    return 1 /* True */;
                }
            }
            return 0 /* False */;
        }
        function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) {
            var node = createNodeWithJSDoc(202 /* ArrowFunction */);
            node.modifiers = parseModifiersForArrowFunction();
            var isAsync = hasModifierOfKind(node, 126 /* AsyncKeyword */) ? 2 /* Await */ : 0 /* None */;
            // Arrow functions are never generators.
            //
            // If we're speculatively parsing a signature for a parenthesized arrow function, then
            // we have to have a complete parameter list.  Otherwise we might see something like
            // a => (b => c)
            // And think that "(b =>" was actually a parenthesized arrow function with a missing
            // close paren.
            if (!fillSignature(58 /* ColonToken */, isAsync, node) && !allowAmbiguity) {
                return undefined;
            }
            // Parsing a signature isn't enough.
            // Parenthesized arrow signatures often look like other valid expressions.
            // For instance:
            //  - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value.
            //  - "(x,y)" is a comma expression parsed as a signature with two parameters.
            //  - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation.
            //  - "a ? (b): function() {}" will too, since function() is a valid JSDoc function type.
            //
            // So we need just a bit of lookahead to ensure that it can only be a signature.
            var hasJSDocFunctionType = node.type && ts.isJSDocFunctionType(node.type);
            if (!allowAmbiguity && token() !== 38 /* EqualsGreaterThanToken */ && (hasJSDocFunctionType || token() !== 18 /* OpenBraceToken */)) {
                // Returning undefined here will cause our caller to rewind to where we started from.
                return undefined;
            }
            return node;
        }
        function parseArrowFunctionExpressionBody(isAsync) {
            if (token() === 18 /* OpenBraceToken */) {
                return parseFunctionBlock(isAsync ? 2 /* Await */ : 0 /* None */);
            }
            if (token() !== 26 /* SemicolonToken */ &&
                token() !== 94 /* FunctionKeyword */ &&
                token() !== 80 /* ClassKeyword */ &&
                isStartOfStatement() &&
                !isStartOfExpressionStatement()) {
                // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations)
                //
                // Here we try to recover from a potential error situation in the case where the
                // user meant to supply a block. For example, if the user wrote:
                //
                //  a =>
                //      let v = 0;
                //  }
                //
                // they may be missing an open brace.  Check to see if that's the case so we can
                // try to recover better.  If we don't do this, then the next close curly we see may end
                // up preemptively closing the containing construct.
                //
                // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error.
                return parseFunctionBlock(16 /* IgnoreMissingOpenBrace */ | (isAsync ? 2 /* Await */ : 0 /* None */));
            }
            return isAsync
                ? doInAwaitContext(parseAssignmentExpressionOrHigher)
                : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
        }
        function parseConditionalExpressionRest(leftOperand) {
            // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher.
            var questionToken = parseOptionalToken(57 /* QuestionToken */);
            if (!questionToken) {
                return leftOperand;
            }
            // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
            // we do not that for the 'whenFalse' part.
            var node = createNode(210 /* ConditionalExpression */, leftOperand.pos);
            node.condition = leftOperand;
            node.questionToken = questionToken;
            node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
            node.colonToken = parseExpectedToken(58 /* ColonToken */);
            node.whenFalse = ts.nodeIsPresent(node.colonToken)
                ? parseAssignmentExpressionOrHigher()
                : createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(58 /* ColonToken */));
            return finishNode(node);
        }
        function parseBinaryExpressionOrHigher(precedence) {
            var leftOperand = parseUnaryExpressionOrHigher();
            return parseBinaryExpressionRest(precedence, leftOperand);
        }
        function isInOrOfKeyword(t) {
            return t === 97 /* InKeyword */ || t === 152 /* OfKeyword */;
        }
        function parseBinaryExpressionRest(precedence, leftOperand) {
            while (true) {
                // We either have a binary operator here, or we're finished.  We call
                // reScanGreaterToken so that we merge token sequences like > and = into >=
                reScanGreaterToken();
                var newPrecedence = ts.getBinaryOperatorPrecedence(token());
                // Check the precedence to see if we should "take" this operator
                // - For left associative operator (all operator but **), consume the operator,
                //   recursively call the function below, and parse binaryExpression as a rightOperand
                //   of the caller if the new precedence of the operator is greater then or equal to the current precedence.
                //   For example:
                //      a - b - c;
                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
                //      a * b - c
                //            ^token; leftOperand = b. Return b to the caller as a rightOperand
                //      a - b * c;
                //            ^token; leftOperand = b. Return b * c to the caller as a rightOperand
                // - For right associative operator (**), consume the operator, recursively call the function
                //   and parse binaryExpression as a rightOperand of the caller if the new precedence of
                //   the operator is strictly grater than the current precedence
                //   For example:
                //      a ** b ** c;
                //             ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
                //      a - b ** c;
                //            ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand
                //      a ** b - c
                //             ^token; leftOperand = b. Return b to the caller as a rightOperand
                var consumeCurrentOperator = token() === 42 /* AsteriskAsteriskToken */ ?
                    newPrecedence >= precedence :
                    newPrecedence > precedence;
                if (!consumeCurrentOperator) {
                    break;
                }
                if (token() === 97 /* InKeyword */ && inDisallowInContext()) {
                    break;
                }
                if (token() === 123 /* AsKeyword */) {
                    // Make sure we *do* perform ASI for constructs like this:
                    //    var x = foo
                    //    as (Bar)
                    // This should be parsed as an initialized variable, followed
                    // by a function call to 'as' with the argument 'Bar'
                    if (scanner.hasPrecedingLineBreak()) {
                        break;
                    }
                    else {
                        nextToken();
                        leftOperand = makeAsExpression(leftOperand, parseType());
                    }
                }
                else {
                    leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence));
                }
            }
            return leftOperand;
        }
        function isBinaryOperator() {
            if (inDisallowInContext() && token() === 97 /* InKeyword */) {
                return false;
            }
            return ts.getBinaryOperatorPrecedence(token()) > 0;
        }
        function makeBinaryExpression(left, operatorToken, right) {
            var node = createNode(209 /* BinaryExpression */, left.pos);
            node.left = left;
            node.operatorToken = operatorToken;
            node.right = right;
            return finishNode(node);
        }
        function makeAsExpression(left, right) {
            var node = createNode(217 /* AsExpression */, left.pos);
            node.expression = left;
            node.type = right;
            return finishNode(node);
        }
        function parsePrefixUnaryExpression() {
            var node = createNode(207 /* PrefixUnaryExpression */);
            node.operator = token();
            nextToken();
            node.operand = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseDeleteExpression() {
            var node = createNode(203 /* DeleteExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseTypeOfExpression() {
            var node = createNode(204 /* TypeOfExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function parseVoidExpression() {
            var node = createNode(205 /* VoidExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function isAwaitExpression() {
            if (token() === 127 /* AwaitKeyword */) {
                if (inAwaitContext()) {
                    return true;
                }
                // here we are using similar heuristics as 'isYieldExpression'
                return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine);
            }
            return false;
        }
        function parseAwaitExpression() {
            var node = createNode(206 /* AwaitExpression */);
            nextToken();
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        /**
         * Parse ES7 exponential expression and await expression
         *
         * ES7 ExponentiationExpression:
         *      1) UnaryExpression[?Yield]
         *      2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield]
         *
         */
        function parseUnaryExpressionOrHigher() {
            /**
             * ES7 UpdateExpression:
             *      1) LeftHandSideExpression[?Yield]
             *      2) LeftHandSideExpression[?Yield][no LineTerminator here]++
             *      3) LeftHandSideExpression[?Yield][no LineTerminator here]--
             *      4) ++UnaryExpression[?Yield]
             *      5) --UnaryExpression[?Yield]
             */
            if (isUpdateExpression()) {
                var updateExpression = parseUpdateExpression();
                return token() === 42 /* AsteriskAsteriskToken */ ?
                    parseBinaryExpressionRest(ts.getBinaryOperatorPrecedence(token()), updateExpression) :
                    updateExpression;
            }
            /**
             * ES7 UnaryExpression:
             *      1) UpdateExpression[?yield]
             *      2) delete UpdateExpression[?yield]
             *      3) void UpdateExpression[?yield]
             *      4) typeof UpdateExpression[?yield]
             *      5) + UpdateExpression[?yield]
             *      6) - UpdateExpression[?yield]
             *      7) ~ UpdateExpression[?yield]
             *      8) ! UpdateExpression[?yield]
             */
            var unaryOperator = token();
            var simpleUnaryExpression = parseSimpleUnaryExpression();
            if (token() === 42 /* AsteriskAsteriskToken */) {
                var pos = ts.skipTrivia(sourceText, simpleUnaryExpression.pos);
                var end = simpleUnaryExpression.end;
                if (simpleUnaryExpression.kind === 199 /* TypeAssertionExpression */) {
                    parseErrorAt(pos, end, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses);
                }
                else {
                    parseErrorAt(pos, end, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator));
                }
            }
            return simpleUnaryExpression;
        }
        /**
         * Parse ES7 simple-unary expression or higher:
         *
         * ES7 UnaryExpression:
         *      1) UpdateExpression[?yield]
         *      2) delete UnaryExpression[?yield]
         *      3) void UnaryExpression[?yield]
         *      4) typeof UnaryExpression[?yield]
         *      5) + UnaryExpression[?yield]
         *      6) - UnaryExpression[?yield]
         *      7) ~ UnaryExpression[?yield]
         *      8) ! UnaryExpression[?yield]
         *      9) [+Await] await UnaryExpression[?yield]
         */
        function parseSimpleUnaryExpression() {
            switch (token()) {
                case 39 /* PlusToken */:
                case 40 /* MinusToken */:
                case 54 /* TildeToken */:
                case 53 /* ExclamationToken */:
                    return parsePrefixUnaryExpression();
                case 85 /* DeleteKeyword */:
                    return parseDeleteExpression();
                case 108 /* TypeOfKeyword */:
                    return parseTypeOfExpression();
                case 110 /* VoidKeyword */:
                    return parseVoidExpression();
                case 29 /* LessThanToken */:
                    // This is modified UnaryExpression grammar in TypeScript
                    //  UnaryExpression (modified):
                    //      < type > UnaryExpression
                    return parseTypeAssertion();
                case 127 /* AwaitKeyword */:
                    if (isAwaitExpression()) {
                        return parseAwaitExpression();
                    }
                // falls through
                default:
                    return parseUpdateExpression();
            }
        }
        /**
         * Check if the current token can possibly be an ES7 increment expression.
         *
         * ES7 UpdateExpression:
         *      LeftHandSideExpression[?Yield]
         *      LeftHandSideExpression[?Yield][no LineTerminator here]++
         *      LeftHandSideExpression[?Yield][no LineTerminator here]--
         *      ++LeftHandSideExpression[?Yield]
         *      --LeftHandSideExpression[?Yield]
         */
        function isUpdateExpression() {
            // This function is called inside parseUnaryExpression to decide
            // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly
            switch (token()) {
                case 39 /* PlusToken */:
                case 40 /* MinusToken */:
                case 54 /* TildeToken */:
                case 53 /* ExclamationToken */:
                case 85 /* DeleteKeyword */:
                case 108 /* TypeOfKeyword */:
                case 110 /* VoidKeyword */:
                case 127 /* AwaitKeyword */:
                    return false;
                case 29 /* LessThanToken */:
                    // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
                    if (sourceFile.languageVariant !== 1 /* JSX */) {
                        return false;
                    }
                // We are in JSX context and the token is part of JSXElement.
                // falls through
                default:
                    return true;
            }
        }
        /**
         * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression.
         *
         * ES7 UpdateExpression[yield]:
         *      1) LeftHandSideExpression[?yield]
         *      2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++
         *      3) LeftHandSideExpression[?yield] [[no LineTerminator here]]--
         *      4) ++LeftHandSideExpression[?yield]
         *      5) --LeftHandSideExpression[?yield]
         * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression
         */
        function parseUpdateExpression() {
            if (token() === 45 /* PlusPlusToken */ || token() === 46 /* MinusMinusToken */) {
                var node = createNode(207 /* PrefixUnaryExpression */);
                node.operator = token();
                nextToken();
                node.operand = parseLeftHandSideExpressionOrHigher();
                return finishNode(node);
            }
            else if (sourceFile.languageVariant === 1 /* JSX */ && token() === 29 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) {
                // JSXElement is part of primaryExpression
                return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
            }
            var expression = parseLeftHandSideExpressionOrHigher();
            ts.Debug.assert(ts.isLeftHandSideExpression(expression));
            if ((token() === 45 /* PlusPlusToken */ || token() === 46 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) {
                var node = createNode(208 /* PostfixUnaryExpression */, expression.pos);
                node.operand = expression;
                node.operator = token();
                nextToken();
                return finishNode(node);
            }
            return expression;
        }
        function parseLeftHandSideExpressionOrHigher() {
            // Original Ecma:
            // LeftHandSideExpression: See 11.2
            //      NewExpression
            //      CallExpression
            //
            // Our simplification:
            //
            // LeftHandSideExpression: See 11.2
            //      MemberExpression
            //      CallExpression
            //
            // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with
            // MemberExpression to make our lives easier.
            //
            // to best understand the below code, it's important to see how CallExpression expands
            // out into its own productions:
            //
            // CallExpression:
            //      MemberExpression Arguments
            //      CallExpression Arguments
            //      CallExpression[Expression]
            //      CallExpression.IdentifierName
            //      import (AssignmentExpression)
            //      super Arguments
            //      super.IdentifierName
            //
            // Because of the recursion in these calls, we need to bottom out first. There are three
            // bottom out states we can run into: 1) We see 'super' which must start either of
            // the last two CallExpression productions. 2) We see 'import' which must start import call.
            // 3)we have a MemberExpression which either completes the LeftHandSideExpression,
            // or starts the beginning of the first four CallExpression productions.
            var expression;
            if (token() === 96 /* ImportKeyword */) {
                if (lookAhead(nextTokenIsOpenParenOrLessThan)) {
                    // We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "("
                    // For example:
                    //      var foo3 = require("subfolder
                    //      import * as foo1 from "module-from-node
                    // We want this import to be a statement rather than import call expression
                    sourceFile.flags |= 1048576 /* PossiblyContainsDynamicImport */;
                    expression = parseTokenNode();
                }
                else if (lookAhead(nextTokenIsDot)) {
                    // This is an 'import.*' metaproperty (i.e. 'import.meta')
                    var fullStart = scanner.getStartPos();
                    nextToken(); // advance past the 'import'
                    nextToken(); // advance past the dot
                    var node = createNode(219 /* MetaProperty */, fullStart);
                    node.keywordToken = 96 /* ImportKeyword */;
                    node.name = parseIdentifierName();
                    expression = finishNode(node);
                    sourceFile.flags |= 2097152 /* PossiblyContainsImportMeta */;
                }
                else {
                    expression = parseMemberExpressionOrHigher();
                }
            }
            else {
                expression = token() === 102 /* SuperKeyword */ ? parseSuperExpression() : parseMemberExpressionOrHigher();
            }
            // Now, we *may* be complete.  However, we might have consumed the start of a
            // CallExpression or OptionalExpression.  As such, we need to consume the rest
            // of it here to be complete.
            return parseCallExpressionRest(expression);
        }
        function parseMemberExpressionOrHigher() {
            // Note: to make our lives simpler, we decompose the NewExpression productions and
            // place ObjectCreationExpression and FunctionExpression into PrimaryExpression.
            // like so:
            //
            //   PrimaryExpression : See 11.1
            //      this
            //      Identifier
            //      Literal
            //      ArrayLiteral
            //      ObjectLiteral
            //      (Expression)
            //      FunctionExpression
            //      new MemberExpression Arguments?
            //
            //   MemberExpression : See 11.2
            //      PrimaryExpression
            //      MemberExpression[Expression]
            //      MemberExpression.IdentifierName
            //
            //   CallExpression : See 11.2
            //      MemberExpression
            //      CallExpression Arguments
            //      CallExpression[Expression]
            //      CallExpression.IdentifierName
            //
            // Technically this is ambiguous.  i.e. CallExpression defines:
            //
            //   CallExpression:
            //      CallExpression Arguments
            //
            // If you see: "new Foo()"
            //
            // Then that could be treated as a single ObjectCreationExpression, or it could be
            // treated as the invocation of "new Foo".  We disambiguate that in code (to match
            // the original grammar) by making sure that if we see an ObjectCreationExpression
            // we always consume arguments if they are there. So we treat "new Foo()" as an
            // object creation only, and not at all as an invocation.  Another way to think
            // about this is that for every "new" that we see, we will consume an argument list if
            // it is there as part of the *associated* object creation node.  Any additional
            // argument lists we see, will become invocation expressions.
            //
            // Because there are no other places in the grammar now that refer to FunctionExpression
            // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression
            // production.
            //
            // Because CallExpression and MemberExpression are left recursive, we need to bottom out
            // of the recursion immediately.  So we parse out a primary expression to start with.
            var expression = parsePrimaryExpression();
            return parseMemberExpressionRest(expression, /*allowOptionalChain*/ true);
        }
        function parseSuperExpression() {
            var expression = parseTokenNode();
            if (token() === 29 /* LessThanToken */) {
                var startPos = getNodePos();
                var typeArguments = tryParse(parseTypeArgumentsInExpression);
                if (typeArguments !== undefined) {
                    parseErrorAt(startPos, getNodePos(), ts.Diagnostics.super_may_not_use_type_arguments);
                }
            }
            if (token() === 20 /* OpenParenToken */ || token() === 24 /* DotToken */ || token() === 22 /* OpenBracketToken */) {
                return expression;
            }
            // If we have seen "super" it must be followed by '(' or '.'.
            // If it wasn't then just try to parse out a '.' and report an error.
            var node = createNode(194 /* PropertyAccessExpression */, expression.pos);
            node.expression = expression;
            parseExpectedToken(24 /* DotToken */, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access);
            // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic
            node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true);
            return finishNode(node);
        }
        function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext) {
            var opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext);
            var result;
            if (opening.kind === 268 /* JsxOpeningElement */) {
                var node = createNode(266 /* JsxElement */, opening.pos);
                node.openingElement = opening;
                node.children = parseJsxChildren(node.openingElement);
                node.closingElement = parseJsxClosingElement(inExpressionContext);
                if (!tagNamesAreEquivalent(node.openingElement.tagName, node.closingElement.tagName)) {
                    parseErrorAtRange(node.closingElement, ts.Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, ts.getTextOfNodeFromSourceText(sourceText, node.openingElement.tagName));
                }
                result = finishNode(node);
            }
            else if (opening.kind === 271 /* JsxOpeningFragment */) {
                var node = createNode(270 /* JsxFragment */, opening.pos);
                node.openingFragment = opening;
                node.children = parseJsxChildren(node.openingFragment);
                node.closingFragment = parseJsxClosingFragment(inExpressionContext);
                result = finishNode(node);
            }
            else {
                ts.Debug.assert(opening.kind === 267 /* JsxSelfClosingElement */);
                // Nothing else to do for self-closing elements
                result = opening;
            }
            // If the user writes the invalid code '<div></div><div></div>' in an expression context (i.e. not wrapped in
            // an enclosing tag), we'll naively try to parse   ^ this as a 'less than' operator and the remainder of the tag
            // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX
            // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter
            // does less damage and we can report a better error.
            // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios
            // of one sort or another.
            if (inExpressionContext && token() === 29 /* LessThanToken */) {
                var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); });
                if (invalidElement) {
                    parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element);
                    var badNode = createNode(209 /* BinaryExpression */, result.pos);
                    badNode.end = invalidElement.end;
                    badNode.left = result;
                    badNode.right = invalidElement;
                    badNode.operatorToken = createMissingNode(27 /* CommaToken */, /*reportAtCurrentPosition*/ false);
                    badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos;
                    return badNode;
                }
            }
            return result;
        }
        function parseJsxText() {
            var node = createNode(11 /* JsxText */);
            node.text = scanner.getTokenValue();
            node.containsOnlyTriviaWhiteSpaces = currentToken === 12 /* JsxTextAllWhiteSpaces */;
            currentToken = scanner.scanJsxToken();
            return finishNode(node);
        }
        function parseJsxChild(openingTag, token) {
            switch (token) {
                case 1 /* EndOfFileToken */:
                    // If we hit EOF, issue the error at the tag that lacks the closing element
                    // rather than at the end of the file (which is useless)
                    if (ts.isJsxOpeningFragment(openingTag)) {
                        parseErrorAtRange(openingTag, ts.Diagnostics.JSX_fragment_has_no_corresponding_closing_tag);
                    }
                    else {
                        // We want the error span to cover only 'Foo.Bar' in < Foo.Bar >
                        // or to cover only 'Foo' in < Foo >
                        var tag = openingTag.tagName;
                        var start = ts.skipTrivia(sourceText, tag.pos);
                        parseErrorAt(start, tag.end, ts.Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, ts.getTextOfNodeFromSourceText(sourceText, openingTag.tagName));
                    }
                    return undefined;
                case 30 /* LessThanSlashToken */:
                case 7 /* ConflictMarkerTrivia */:
                    return undefined;
                case 11 /* JsxText */:
                case 12 /* JsxTextAllWhiteSpaces */:
                    return parseJsxText();
                case 18 /* OpenBraceToken */:
                    return parseJsxExpression(/*inExpressionContext*/ false);
                case 29 /* LessThanToken */:
                    return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false);
                default:
                    return ts.Debug.assertNever(token);
            }
        }
        function parseJsxChildren(openingTag) {
            var list = [];
            var listPos = getNodePos();
            var saveParsingContext = parsingContext;
            parsingContext |= 1 << 14 /* JsxChildren */;
            while (true) {
                var child = parseJsxChild(openingTag, currentToken = scanner.reScanJsxToken());
                if (!child)
                    break;
                list.push(child);
            }
            parsingContext = saveParsingContext;
            return createNodeArray(list, listPos);
        }
        function parseJsxAttributes() {
            var jsxAttributes = createNode(274 /* JsxAttributes */);
            jsxAttributes.properties = parseList(13 /* JsxAttributes */, parseJsxAttribute);
            return finishNode(jsxAttributes);
        }
        function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext) {
            var fullStart = scanner.getStartPos();
            parseExpected(29 /* LessThanToken */);
            if (token() === 31 /* GreaterThanToken */) {
                // See below for explanation of scanJsxText
                var node_1 = createNode(271 /* JsxOpeningFragment */, fullStart);
                scanJsxText();
                return finishNode(node_1);
            }
            var tagName = parseJsxElementName();
            var typeArguments = tryParseTypeArguments();
            var attributes = parseJsxAttributes();
            var node;
            if (token() === 31 /* GreaterThanToken */) {
                // Closing tag, so scan the immediately-following text with the JSX scanning instead
                // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
                // scanning errors
                node = createNode(268 /* JsxOpeningElement */, fullStart);
                scanJsxText();
            }
            else {
                parseExpected(43 /* SlashToken */);
                if (inExpressionContext) {
                    parseExpected(31 /* GreaterThanToken */);
                }
                else {
                    parseExpected(31 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                    scanJsxText();
                }
                node = createNode(267 /* JsxSelfClosingElement */, fullStart);
            }
            node.tagName = tagName;
            node.typeArguments = typeArguments;
            node.attributes = attributes;
            return finishNode(node);
        }
        function parseJsxElementName() {
            scanJsxIdentifier();
            // JsxElement can have name in the form of
            //      propertyAccessExpression
            //      primaryExpression in the form of an identifier and "this" keyword
            // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword
            // We only want to consider "this" as a primaryExpression
            var expression = token() === 104 /* ThisKeyword */ ?
                parseTokenNode() : parseIdentifierName();
            while (parseOptional(24 /* DotToken */)) {
                var propertyAccess = createNode(194 /* PropertyAccessExpression */, expression.pos);
                propertyAccess.expression = expression;
                propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false);
                expression = finishNode(propertyAccess);
            }
            return expression;
        }
        function parseJsxExpression(inExpressionContext) {
            var node = createNode(276 /* JsxExpression */);
            if (!parseExpected(18 /* OpenBraceToken */)) {
                return undefined;
            }
            if (token() !== 19 /* CloseBraceToken */) {
                node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
                // Only an AssignmentExpression is valid here per the JSX spec,
                // but we can unambiguously parse a comma sequence and provide
                // a better error message in grammar checking.
                node.expression = parseExpression();
            }
            if (inExpressionContext) {
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                if (parseExpected(19 /* CloseBraceToken */, /*message*/ undefined, /*shouldAdvance*/ false)) {
                    scanJsxText();
                }
            }
            return finishNode(node);
        }
        function parseJsxAttribute() {
            if (token() === 18 /* OpenBraceToken */) {
                return parseJsxSpreadAttribute();
            }
            scanJsxIdentifier();
            var node = createNode(273 /* JsxAttribute */);
            node.name = parseIdentifierName();
            if (token() === 62 /* EqualsToken */) {
                switch (scanJsxAttributeValue()) {
                    case 10 /* StringLiteral */:
                        node.initializer = parseLiteralNode();
                        break;
                    default:
                        node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
                        break;
                }
            }
            return finishNode(node);
        }
        function parseJsxSpreadAttribute() {
            var node = createNode(275 /* JsxSpreadAttribute */);
            parseExpected(18 /* OpenBraceToken */);
            parseExpected(25 /* DotDotDotToken */);
            node.expression = parseExpression();
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseJsxClosingElement(inExpressionContext) {
            var node = createNode(269 /* JsxClosingElement */);
            parseExpected(30 /* LessThanSlashToken */);
            node.tagName = parseJsxElementName();
            if (inExpressionContext) {
                parseExpected(31 /* GreaterThanToken */);
            }
            else {
                parseExpected(31 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseJsxClosingFragment(inExpressionContext) {
            var node = createNode(272 /* JsxClosingFragment */);
            parseExpected(30 /* LessThanSlashToken */);
            if (ts.tokenIsIdentifierOrKeyword(token())) {
                parseErrorAtRange(parseJsxElementName(), ts.Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment);
            }
            if (inExpressionContext) {
                parseExpected(31 /* GreaterThanToken */);
            }
            else {
                parseExpected(31 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false);
                scanJsxText();
            }
            return finishNode(node);
        }
        function parseTypeAssertion() {
            var node = createNode(199 /* TypeAssertionExpression */);
            parseExpected(29 /* LessThanToken */);
            node.type = parseType();
            parseExpected(31 /* GreaterThanToken */);
            node.expression = parseSimpleUnaryExpression();
            return finishNode(node);
        }
        function nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token())
                || token() === 22 /* OpenBracketToken */
                || isTemplateStartOfTaggedTemplate();
        }
        function isStartOfOptionalPropertyOrElementAccessChain() {
            return token() === 28 /* QuestionDotToken */
                && lookAhead(nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate);
        }
        function tryReparseOptionalChain(node) {
            if (node.flags & 32 /* OptionalChain */) {
                return true;
            }
            // check for an optional chain in a non-null expression
            if (ts.isNonNullExpression(node)) {
                var expr = node.expression;
                while (ts.isNonNullExpression(expr) && !(expr.flags & 32 /* OptionalChain */)) {
                    expr = expr.expression;
                }
                if (expr.flags & 32 /* OptionalChain */) {
                    // this is part of an optional chain. Walk down from `node` to `expression` and set the flag.
                    while (ts.isNonNullExpression(node)) {
                        node.flags |= 32 /* OptionalChain */;
                        node = node.expression;
                    }
                    return true;
                }
            }
            return false;
        }
        function parsePropertyAccessExpressionRest(expression, questionDotToken) {
            var propertyAccess = createNode(194 /* PropertyAccessExpression */, expression.pos);
            propertyAccess.expression = expression;
            propertyAccess.questionDotToken = questionDotToken;
            propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true);
            if (questionDotToken || tryReparseOptionalChain(expression)) {
                propertyAccess.flags |= 32 /* OptionalChain */;
                if (ts.isPrivateIdentifier(propertyAccess.name)) {
                    parseErrorAtRange(propertyAccess.name, ts.Diagnostics.An_optional_chain_cannot_contain_private_identifiers);
                }
            }
            return finishNode(propertyAccess);
        }
        function parseElementAccessExpressionRest(expression, questionDotToken) {
            var indexedAccess = createNode(195 /* ElementAccessExpression */, expression.pos);
            indexedAccess.expression = expression;
            indexedAccess.questionDotToken = questionDotToken;
            if (token() === 23 /* CloseBracketToken */) {
                indexedAccess.argumentExpression = createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.An_element_access_expression_should_take_an_argument);
            }
            else {
                var argument = allowInAnd(parseExpression);
                if (ts.isStringOrNumericLiteralLike(argument)) {
                    argument.text = internIdentifier(argument.text);
                }
                indexedAccess.argumentExpression = argument;
            }
            parseExpected(23 /* CloseBracketToken */);
            if (questionDotToken || tryReparseOptionalChain(expression)) {
                indexedAccess.flags |= 32 /* OptionalChain */;
            }
            return finishNode(indexedAccess);
        }
        function parseMemberExpressionRest(expression, allowOptionalChain) {
            while (true) {
                var questionDotToken = void 0;
                var isPropertyAccess = false;
                if (allowOptionalChain && isStartOfOptionalPropertyOrElementAccessChain()) {
                    questionDotToken = parseExpectedToken(28 /* QuestionDotToken */);
                    isPropertyAccess = ts.tokenIsIdentifierOrKeyword(token());
                }
                else {
                    isPropertyAccess = parseOptional(24 /* DotToken */);
                }
                if (isPropertyAccess) {
                    expression = parsePropertyAccessExpressionRest(expression, questionDotToken);
                    continue;
                }
                if (!questionDotToken && token() === 53 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                    nextToken();
                    var nonNullExpression = createNode(218 /* NonNullExpression */, expression.pos);
                    nonNullExpression.expression = expression;
                    expression = finishNode(nonNullExpression);
                    continue;
                }
                // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName
                if ((questionDotToken || !inDecoratorContext()) && parseOptional(22 /* OpenBracketToken */)) {
                    expression = parseElementAccessExpressionRest(expression, questionDotToken);
                    continue;
                }
                if (isTemplateStartOfTaggedTemplate()) {
                    expression = parseTaggedTemplateRest(expression, questionDotToken, /*typeArguments*/ undefined);
                    continue;
                }
                return expression;
            }
        }
        function isTemplateStartOfTaggedTemplate() {
            return token() === 14 /* NoSubstitutionTemplateLiteral */ || token() === 15 /* TemplateHead */;
        }
        function parseTaggedTemplateRest(tag, questionDotToken, typeArguments) {
            var tagExpression = createNode(198 /* TaggedTemplateExpression */, tag.pos);
            tagExpression.tag = tag;
            tagExpression.questionDotToken = questionDotToken;
            tagExpression.typeArguments = typeArguments;
            tagExpression.template = token() === 14 /* NoSubstitutionTemplateLiteral */
                ? (reScanTemplateHeadOrNoSubstitutionTemplate(), parseLiteralNode())
                : parseTemplateExpression(/*isTaggedTemplate*/ true);
            if (questionDotToken || tag.flags & 32 /* OptionalChain */) {
                tagExpression.flags |= 32 /* OptionalChain */;
            }
            return finishNode(tagExpression);
        }
        function parseCallExpressionRest(expression) {
            while (true) {
                expression = parseMemberExpressionRest(expression, /*allowOptionalChain*/ true);
                var questionDotToken = parseOptionalToken(28 /* QuestionDotToken */);
                // handle 'foo<<T>()'
                if (token() === 29 /* LessThanToken */ || token() === 47 /* LessThanLessThanToken */) {
                    // See if this is the start of a generic invocation.  If so, consume it and
                    // keep checking for postfix expressions.  Otherwise, it's just a '<' that's
                    // part of an arithmetic expression.  Break out so we consume it higher in the
                    // stack.
                    var typeArguments = tryParse(parseTypeArgumentsInExpression);
                    if (typeArguments) {
                        if (isTemplateStartOfTaggedTemplate()) {
                            expression = parseTaggedTemplateRest(expression, questionDotToken, typeArguments);
                            continue;
                        }
                        var callExpr = createNode(196 /* CallExpression */, expression.pos);
                        callExpr.expression = expression;
                        callExpr.questionDotToken = questionDotToken;
                        callExpr.typeArguments = typeArguments;
                        callExpr.arguments = parseArgumentList();
                        if (questionDotToken || tryReparseOptionalChain(expression)) {
                            callExpr.flags |= 32 /* OptionalChain */;
                        }
                        expression = finishNode(callExpr);
                        continue;
                    }
                }
                else if (token() === 20 /* OpenParenToken */) {
                    var callExpr = createNode(196 /* CallExpression */, expression.pos);
                    callExpr.expression = expression;
                    callExpr.questionDotToken = questionDotToken;
                    callExpr.arguments = parseArgumentList();
                    if (questionDotToken || tryReparseOptionalChain(expression)) {
                        callExpr.flags |= 32 /* OptionalChain */;
                    }
                    expression = finishNode(callExpr);
                    continue;
                }
                if (questionDotToken) {
                    // We failed to parse anything, so report a missing identifier here.
                    var propertyAccess = createNode(194 /* PropertyAccessExpression */, expression.pos);
                    propertyAccess.expression = expression;
                    propertyAccess.questionDotToken = questionDotToken;
                    propertyAccess.name = createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.Identifier_expected);
                    propertyAccess.flags |= 32 /* OptionalChain */;
                    expression = finishNode(propertyAccess);
                }
                break;
            }
            return expression;
        }
        function parseArgumentList() {
            parseExpected(20 /* OpenParenToken */);
            var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression);
            parseExpected(21 /* CloseParenToken */);
            return result;
        }
        function parseTypeArgumentsInExpression() {
            if (reScanLessThanToken() !== 29 /* LessThanToken */) {
                return undefined;
            }
            nextToken();
            var typeArguments = parseDelimitedList(20 /* TypeArguments */, parseType);
            if (!parseExpected(31 /* GreaterThanToken */)) {
                // If it doesn't have the closing `>` then it's definitely not an type argument list.
                return undefined;
            }
            // If we have a '<', then only parse this as a argument list if the type arguments
            // are complete and we have an open paren.  if we don't, rewind and return nothing.
            return typeArguments && canFollowTypeArgumentsInExpression()
                ? typeArguments
                : undefined;
        }
        function canFollowTypeArgumentsInExpression() {
            switch (token()) {
                case 20 /* OpenParenToken */: // foo<x>(
                case 14 /* NoSubstitutionTemplateLiteral */: // foo<T> `...`
                case 15 /* TemplateHead */: // foo<T> `...${100}...`
                // these are the only tokens can legally follow a type argument
                // list. So we definitely want to treat them as type arg lists.
                // falls through
                case 24 /* DotToken */: // foo<x>.
                case 21 /* CloseParenToken */: // foo<x>)
                case 23 /* CloseBracketToken */: // foo<x>]
                case 58 /* ColonToken */: // foo<x>:
                case 26 /* SemicolonToken */: // foo<x>;
                case 57 /* QuestionToken */: // foo<x>?
                case 34 /* EqualsEqualsToken */: // foo<x> ==
                case 36 /* EqualsEqualsEqualsToken */: // foo<x> ===
                case 35 /* ExclamationEqualsToken */: // foo<x> !=
                case 37 /* ExclamationEqualsEqualsToken */: // foo<x> !==
                case 55 /* AmpersandAmpersandToken */: // foo<x> &&
                case 56 /* BarBarToken */: // foo<x> ||
                case 60 /* QuestionQuestionToken */: // foo<x> ??
                case 52 /* CaretToken */: // foo<x> ^
                case 50 /* AmpersandToken */: // foo<x> &
                case 51 /* BarToken */: // foo<x> |
                case 19 /* CloseBraceToken */: // foo<x> }
                case 1 /* EndOfFileToken */: // foo<x>
                    // these cases can't legally follow a type arg list.  However, they're not legal
                    // expressions either.  The user is probably in the middle of a generic type. So
                    // treat it as such.
                    return true;
                case 27 /* CommaToken */: // foo<x>,
                case 18 /* OpenBraceToken */: // foo<x> {
                // We don't want to treat these as type arguments.  Otherwise we'll parse this
                // as an invocation expression.  Instead, we want to parse out the expression
                // in isolation from the type arguments.
                // falls through
                default:
                    // Anything else treat as an expression.
                    return false;
            }
        }
        function parsePrimaryExpression() {
            switch (token()) {
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    return parseLiteralNode();
                case 104 /* ThisKeyword */:
                case 102 /* SuperKeyword */:
                case 100 /* NullKeyword */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                    return parseTokenNode();
                case 20 /* OpenParenToken */:
                    return parseParenthesizedExpression();
                case 22 /* OpenBracketToken */:
                    return parseArrayLiteralExpression();
                case 18 /* OpenBraceToken */:
                    return parseObjectLiteralExpression();
                case 126 /* AsyncKeyword */:
                    // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
                    // If we encounter `async [no LineTerminator here] function` then this is an async
                    // function; otherwise, its an identifier.
                    if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
                        break;
                    }
                    return parseFunctionExpression();
                case 80 /* ClassKeyword */:
                    return parseClassExpression();
                case 94 /* FunctionKeyword */:
                    return parseFunctionExpression();
                case 99 /* NewKeyword */:
                    return parseNewExpressionOrNewDotTarget();
                case 43 /* SlashToken */:
                case 67 /* SlashEqualsToken */:
                    if (reScanSlashToken() === 13 /* RegularExpressionLiteral */) {
                        return parseLiteralNode();
                    }
                    break;
                case 15 /* TemplateHead */:
                    return parseTemplateExpression(/* isTaggedTemplate */ false);
            }
            return parseIdentifier(ts.Diagnostics.Expression_expected);
        }
        function parseParenthesizedExpression() {
            var node = createNodeWithJSDoc(200 /* ParenthesizedExpression */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseSpreadElement() {
            var node = createNode(213 /* SpreadElement */);
            parseExpected(25 /* DotDotDotToken */);
            node.expression = parseAssignmentExpressionOrHigher();
            return finishNode(node);
        }
        function parseArgumentOrArrayLiteralElement() {
            return token() === 25 /* DotDotDotToken */ ? parseSpreadElement() :
                token() === 27 /* CommaToken */ ? createNode(215 /* OmittedExpression */) :
                    parseAssignmentExpressionOrHigher();
        }
        function parseArgumentExpression() {
            return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement);
        }
        function parseArrayLiteralExpression() {
            var node = createNode(192 /* ArrayLiteralExpression */);
            parseExpected(22 /* OpenBracketToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function parseObjectLiteralElement() {
            var node = createNodeWithJSDoc(0 /* Unknown */);
            if (parseOptionalToken(25 /* DotDotDotToken */)) {
                node.kind = 283 /* SpreadAssignment */;
                node.expression = parseAssignmentExpressionOrHigher();
                return finishNode(node);
            }
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            if (parseContextualModifier(131 /* GetKeyword */)) {
                return parseAccessorDeclaration(node, 163 /* GetAccessor */);
            }
            if (parseContextualModifier(142 /* SetKeyword */)) {
                return parseAccessorDeclaration(node, 164 /* SetAccessor */);
            }
            var asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
            var tokenIsIdentifier = isIdentifier();
            node.name = parsePropertyName();
            // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker.
            node.questionToken = parseOptionalToken(57 /* QuestionToken */);
            node.exclamationToken = parseOptionalToken(53 /* ExclamationToken */);
            if (asteriskToken || token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                return parseMethodDeclaration(node, asteriskToken);
            }
            // check if it is short-hand property assignment or normal property assignment
            // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production
            // CoverInitializedName[Yield] :
            //     IdentifierReference[?Yield] Initializer[In, ?Yield]
            // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
            var isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== 58 /* ColonToken */);
            if (isShorthandPropertyAssignment) {
                node.kind = 282 /* ShorthandPropertyAssignment */;
                var equalsToken = parseOptionalToken(62 /* EqualsToken */);
                if (equalsToken) {
                    node.equalsToken = equalsToken;
                    node.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher);
                }
            }
            else {
                node.kind = 281 /* PropertyAssignment */;
                parseExpected(58 /* ColonToken */);
                node.initializer = allowInAnd(parseAssignmentExpressionOrHigher);
            }
            return finishNode(node);
        }
        function parseObjectLiteralExpression() {
            var node = createNode(193 /* ObjectLiteralExpression */);
            var openBracePosition = scanner.getTokenPos();
            parseExpected(18 /* OpenBraceToken */);
            if (scanner.hasPrecedingLineBreak()) {
                node.multiLine = true;
            }
            node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true);
            if (!parseExpected(19 /* CloseBraceToken */)) {
                var lastError = ts.lastOrUndefined(parseDiagnostics);
                if (lastError && lastError.code === ts.Diagnostics._0_expected.code) {
                    ts.addRelatedInfo(lastError, ts.createFileDiagnostic(sourceFile, openBracePosition, 1, ts.Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here));
                }
            }
            return finishNode(node);
        }
        function parseFunctionExpression() {
            // GeneratorExpression:
            //      function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
            //
            // FunctionExpression:
            //      function BindingIdentifier[opt](FormalParameters){ FunctionBody }
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var node = createNodeWithJSDoc(201 /* FunctionExpression */);
            node.modifiers = parseModifiers();
            parseExpected(94 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = hasModifierOfKind(node, 126 /* AsyncKeyword */) ? 2 /* Await */ : 0 /* None */;
            node.name =
                isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
                    isGenerator ? doInYieldContext(parseOptionalIdentifier) :
                        isAsync ? doInAwaitContext(parseOptionalIdentifier) :
                            parseOptionalIdentifier();
            fillSignature(58 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlock(isGenerator | isAsync);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            return finishNode(node);
        }
        function parseOptionalIdentifier() {
            return isIdentifier() ? parseIdentifier() : undefined;
        }
        function parseNewExpressionOrNewDotTarget() {
            var fullStart = scanner.getStartPos();
            parseExpected(99 /* NewKeyword */);
            if (parseOptional(24 /* DotToken */)) {
                var node_2 = createNode(219 /* MetaProperty */, fullStart);
                node_2.keywordToken = 99 /* NewKeyword */;
                node_2.name = parseIdentifierName();
                return finishNode(node_2);
            }
            var expression = parsePrimaryExpression();
            var typeArguments;
            while (true) {
                expression = parseMemberExpressionRest(expression, /*allowOptionalChain*/ false);
                typeArguments = tryParse(parseTypeArgumentsInExpression);
                if (isTemplateStartOfTaggedTemplate()) {
                    ts.Debug.assert(!!typeArguments, "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'");
                    expression = parseTaggedTemplateRest(expression, /*optionalChain*/ undefined, typeArguments);
                    typeArguments = undefined;
                }
                break;
            }
            var node = createNode(197 /* NewExpression */, fullStart);
            node.expression = expression;
            node.typeArguments = typeArguments;
            if (token() === 20 /* OpenParenToken */) {
                node.arguments = parseArgumentList();
            }
            else if (node.typeArguments) {
                parseErrorAt(fullStart, scanner.getStartPos(), ts.Diagnostics.A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list);
            }
            return finishNode(node);
        }
        // STATEMENTS
        function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) {
            var node = createNode(223 /* Block */);
            var openBracePosition = scanner.getTokenPos();
            if (parseExpected(18 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) {
                if (scanner.hasPrecedingLineBreak()) {
                    node.multiLine = true;
                }
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                if (!parseExpected(19 /* CloseBraceToken */)) {
                    var lastError = ts.lastOrUndefined(parseDiagnostics);
                    if (lastError && lastError.code === ts.Diagnostics._0_expected.code) {
                        ts.addRelatedInfo(lastError, ts.createFileDiagnostic(sourceFile, openBracePosition, 1, ts.Diagnostics.The_parser_expected_to_find_a_to_match_the_token_here));
                    }
                }
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseFunctionBlock(flags, diagnosticMessage) {
            var savedYieldContext = inYieldContext();
            setYieldContext(!!(flags & 1 /* Yield */));
            var savedAwaitContext = inAwaitContext();
            setAwaitContext(!!(flags & 2 /* Await */));
            // We may be in a [Decorator] context when parsing a function expression or
            // arrow function. The body of the function is not in [Decorator] context.
            var saveDecoratorContext = inDecoratorContext();
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ false);
            }
            var block = parseBlock(!!(flags & 16 /* IgnoreMissingOpenBrace */), diagnosticMessage);
            if (saveDecoratorContext) {
                setDecoratorContext(/*val*/ true);
            }
            setYieldContext(savedYieldContext);
            setAwaitContext(savedAwaitContext);
            return block;
        }
        function parseEmptyStatement() {
            var node = createNode(224 /* EmptyStatement */);
            parseExpected(26 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseIfStatement() {
            var node = createNode(227 /* IfStatement */);
            parseExpected(95 /* IfKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.thenStatement = parseStatement();
            node.elseStatement = parseOptional(87 /* ElseKeyword */) ? parseStatement() : undefined;
            return finishNode(node);
        }
        function parseDoStatement() {
            var node = createNode(228 /* DoStatement */);
            parseExpected(86 /* DoKeyword */);
            node.statement = parseStatement();
            parseExpected(111 /* WhileKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html
            // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in
            // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby
            //  do;while(0)x will have a semicolon inserted before x.
            parseOptional(26 /* SemicolonToken */);
            return finishNode(node);
        }
        function parseWhileStatement() {
            var node = createNode(229 /* WhileStatement */);
            parseExpected(111 /* WhileKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.statement = parseStatement();
            return finishNode(node);
        }
        function parseForOrForInOrForOfStatement() {
            var pos = getNodePos();
            parseExpected(93 /* ForKeyword */);
            var awaitToken = parseOptionalToken(127 /* AwaitKeyword */);
            parseExpected(20 /* OpenParenToken */);
            var initializer;
            if (token() !== 26 /* SemicolonToken */) {
                if (token() === 109 /* VarKeyword */ || token() === 115 /* LetKeyword */ || token() === 81 /* ConstKeyword */) {
                    initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true);
                }
                else {
                    initializer = disallowInAnd(parseExpression);
                }
            }
            var forOrForInOrForOfStatement;
            if (awaitToken ? parseExpected(152 /* OfKeyword */) : parseOptional(152 /* OfKeyword */)) {
                var forOfStatement = createNode(232 /* ForOfStatement */, pos);
                forOfStatement.awaitModifier = awaitToken;
                forOfStatement.initializer = initializer;
                forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forOfStatement;
            }
            else if (parseOptional(97 /* InKeyword */)) {
                var forInStatement = createNode(231 /* ForInStatement */, pos);
                forInStatement.initializer = initializer;
                forInStatement.expression = allowInAnd(parseExpression);
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forInStatement;
            }
            else {
                var forStatement = createNode(230 /* ForStatement */, pos);
                forStatement.initializer = initializer;
                parseExpected(26 /* SemicolonToken */);
                if (token() !== 26 /* SemicolonToken */ && token() !== 21 /* CloseParenToken */) {
                    forStatement.condition = allowInAnd(parseExpression);
                }
                parseExpected(26 /* SemicolonToken */);
                if (token() !== 21 /* CloseParenToken */) {
                    forStatement.incrementor = allowInAnd(parseExpression);
                }
                parseExpected(21 /* CloseParenToken */);
                forOrForInOrForOfStatement = forStatement;
            }
            forOrForInOrForOfStatement.statement = parseStatement();
            return finishNode(forOrForInOrForOfStatement);
        }
        function parseBreakOrContinueStatement(kind) {
            var node = createNode(kind);
            parseExpected(kind === 234 /* BreakStatement */ ? 77 /* BreakKeyword */ : 82 /* ContinueKeyword */);
            if (!canParseSemicolon()) {
                node.label = parseIdentifier();
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseReturnStatement() {
            var node = createNode(235 /* ReturnStatement */);
            parseExpected(101 /* ReturnKeyword */);
            if (!canParseSemicolon()) {
                node.expression = allowInAnd(parseExpression);
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseWithStatement() {
            var node = createNode(236 /* WithStatement */);
            parseExpected(112 /* WithKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            node.statement = doInsideOfContext(16777216 /* InWithStatement */, parseStatement);
            return finishNode(node);
        }
        function parseCaseClause() {
            var node = createNode(277 /* CaseClause */);
            parseExpected(78 /* CaseKeyword */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(58 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseDefaultClause() {
            var node = createNode(278 /* DefaultClause */);
            parseExpected(84 /* DefaultKeyword */);
            parseExpected(58 /* ColonToken */);
            node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement);
            return finishNode(node);
        }
        function parseCaseOrDefaultClause() {
            return token() === 78 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause();
        }
        function parseSwitchStatement() {
            var node = createNode(237 /* SwitchStatement */);
            parseExpected(103 /* SwitchKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = allowInAnd(parseExpression);
            parseExpected(21 /* CloseParenToken */);
            var caseBlock = createNode(251 /* CaseBlock */);
            parseExpected(18 /* OpenBraceToken */);
            caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause);
            parseExpected(19 /* CloseBraceToken */);
            node.caseBlock = finishNode(caseBlock);
            return finishNode(node);
        }
        function parseThrowStatement() {
            // ThrowStatement[Yield] :
            //      throw [no LineTerminator here]Expression[In, ?Yield];
            // Because of automatic semicolon insertion, we need to report error if this
            // throw could be terminated with a semicolon.  Note: we can't call 'parseExpression'
            // directly as that might consume an expression on the following line.
            // We just return 'undefined' in that case.  The actual error will be reported in the
            // grammar walker.
            var node = createNode(239 /* ThrowStatement */);
            parseExpected(105 /* ThrowKeyword */);
            node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression);
            parseSemicolon();
            return finishNode(node);
        }
        // TODO: Review for error recovery
        function parseTryStatement() {
            var node = createNode(240 /* TryStatement */);
            parseExpected(107 /* TryKeyword */);
            node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            node.catchClause = token() === 79 /* CatchKeyword */ ? parseCatchClause() : undefined;
            // If we don't have a catch clause, then we must have a finally clause.  Try to parse
            // one out no matter what.
            if (!node.catchClause || token() === 92 /* FinallyKeyword */) {
                parseExpected(92 /* FinallyKeyword */);
                node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false);
            }
            return finishNode(node);
        }
        function parseCatchClause() {
            var result = createNode(280 /* CatchClause */);
            parseExpected(79 /* CatchKeyword */);
            if (parseOptional(20 /* OpenParenToken */)) {
                result.variableDeclaration = parseVariableDeclaration();
                parseExpected(21 /* CloseParenToken */);
            }
            else {
                // Keep shape of node to avoid degrading performance.
                result.variableDeclaration = undefined;
            }
            result.block = parseBlock(/*ignoreMissingOpenBrace*/ false);
            return finishNode(result);
        }
        function parseDebuggerStatement() {
            var node = createNode(241 /* DebuggerStatement */);
            parseExpected(83 /* DebuggerKeyword */);
            parseSemicolon();
            return finishNode(node);
        }
        function parseExpressionOrLabeledStatement() {
            // Avoiding having to do the lookahead for a labeled statement by just trying to parse
            // out an expression, seeing if it is identifier and then seeing if it is followed by
            // a colon.
            var node = createNodeWithJSDoc(token() === 75 /* Identifier */ ? 0 /* Unknown */ : 226 /* ExpressionStatement */);
            var expression = allowInAnd(parseExpression);
            if (expression.kind === 75 /* Identifier */ && parseOptional(58 /* ColonToken */)) {
                node.kind = 238 /* LabeledStatement */;
                node.label = expression;
                node.statement = parseStatement();
            }
            else {
                node.kind = 226 /* ExpressionStatement */;
                node.expression = expression;
                parseSemicolon();
            }
            return finishNode(node);
        }
        function nextTokenIsIdentifierOrKeywordOnSameLine() {
            nextToken();
            return ts.tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsClassKeywordOnSameLine() {
            nextToken();
            return token() === 80 /* ClassKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsFunctionKeywordOnSameLine() {
            nextToken();
            return token() === 94 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak();
        }
        function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() {
            nextToken();
            return (ts.tokenIsIdentifierOrKeyword(token()) || token() === 8 /* NumericLiteral */ || token() === 9 /* BigIntLiteral */ || token() === 10 /* StringLiteral */) && !scanner.hasPrecedingLineBreak();
        }
        function isDeclaration() {
            while (true) {
                switch (token()) {
                    case 109 /* VarKeyword */:
                    case 115 /* LetKeyword */:
                    case 81 /* ConstKeyword */:
                    case 94 /* FunctionKeyword */:
                    case 80 /* ClassKeyword */:
                    case 88 /* EnumKeyword */:
                        return true;
                    // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers;
                    // however, an identifier cannot be followed by another identifier on the same line. This is what we
                    // count on to parse out the respective declarations. For instance, we exploit this to say that
                    //
                    //    namespace n
                    //
                    // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees
                    //
                    //    namespace
                    //    n
                    //
                    // as the identifier 'namespace' on one line followed by the identifier 'n' on another.
                    // We need to look one token ahead to see if it permissible to try parsing a declaration.
                    //
                    // *Note*: 'interface' is actually a strict mode reserved word. So while
                    //
                    //   "use strict"
                    //   interface
                    //   I {}
                    //
                    // could be legal, it would add complexity for very little gain.
                    case 114 /* InterfaceKeyword */:
                    case 145 /* TypeKeyword */:
                        return nextTokenIsIdentifierOnSameLine();
                    case 135 /* ModuleKeyword */:
                    case 136 /* NamespaceKeyword */:
                        return nextTokenIsIdentifierOrStringLiteralOnSameLine();
                    case 122 /* AbstractKeyword */:
                    case 126 /* AsyncKeyword */:
                    case 130 /* DeclareKeyword */:
                    case 117 /* PrivateKeyword */:
                    case 118 /* ProtectedKeyword */:
                    case 119 /* PublicKeyword */:
                    case 138 /* ReadonlyKeyword */:
                        nextToken();
                        // ASI takes effect for this modifier.
                        if (scanner.hasPrecedingLineBreak()) {
                            return false;
                        }
                        continue;
                    case 150 /* GlobalKeyword */:
                        nextToken();
                        return token() === 18 /* OpenBraceToken */ || token() === 75 /* Identifier */ || token() === 89 /* ExportKeyword */;
                    case 96 /* ImportKeyword */:
                        nextToken();
                        return token() === 10 /* StringLiteral */ || token() === 41 /* AsteriskToken */ ||
                            token() === 18 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token());
                    case 89 /* ExportKeyword */:
                        var currentToken_1 = nextToken();
                        if (currentToken_1 === 145 /* TypeKeyword */) {
                            currentToken_1 = lookAhead(nextToken);
                        }
                        if (currentToken_1 === 62 /* EqualsToken */ || currentToken_1 === 41 /* AsteriskToken */ ||
                            currentToken_1 === 18 /* OpenBraceToken */ || currentToken_1 === 84 /* DefaultKeyword */ ||
                            currentToken_1 === 123 /* AsKeyword */) {
                            return true;
                        }
                        continue;
                    case 120 /* StaticKeyword */:
                        nextToken();
                        continue;
                    default:
                        return false;
                }
            }
        }
        function isStartOfDeclaration() {
            return lookAhead(isDeclaration);
        }
        function isStartOfStatement() {
            switch (token()) {
                case 59 /* AtToken */:
                case 26 /* SemicolonToken */:
                case 18 /* OpenBraceToken */:
                case 109 /* VarKeyword */:
                case 115 /* LetKeyword */:
                case 94 /* FunctionKeyword */:
                case 80 /* ClassKeyword */:
                case 88 /* EnumKeyword */:
                case 95 /* IfKeyword */:
                case 86 /* DoKeyword */:
                case 111 /* WhileKeyword */:
                case 93 /* ForKeyword */:
                case 82 /* ContinueKeyword */:
                case 77 /* BreakKeyword */:
                case 101 /* ReturnKeyword */:
                case 112 /* WithKeyword */:
                case 103 /* SwitchKeyword */:
                case 105 /* ThrowKeyword */:
                case 107 /* TryKeyword */:
                case 83 /* DebuggerKeyword */:
                // 'catch' and 'finally' do not actually indicate that the code is part of a statement,
                // however, we say they are here so that we may gracefully parse them and error later.
                // falls through
                case 79 /* CatchKeyword */:
                case 92 /* FinallyKeyword */:
                    return true;
                case 96 /* ImportKeyword */:
                    return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
                case 81 /* ConstKeyword */:
                case 89 /* ExportKeyword */:
                    return isStartOfDeclaration();
                case 126 /* AsyncKeyword */:
                case 130 /* DeclareKeyword */:
                case 114 /* InterfaceKeyword */:
                case 135 /* ModuleKeyword */:
                case 136 /* NamespaceKeyword */:
                case 145 /* TypeKeyword */:
                case 150 /* GlobalKeyword */:
                    // When these don't start a declaration, they're an identifier in an expression statement
                    return true;
                case 119 /* PublicKeyword */:
                case 117 /* PrivateKeyword */:
                case 118 /* ProtectedKeyword */:
                case 120 /* StaticKeyword */:
                case 138 /* ReadonlyKeyword */:
                    // When these don't start a declaration, they may be the start of a class member if an identifier
                    // immediately follows. Otherwise they're an identifier in an expression statement.
                    return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine);
                default:
                    return isStartOfExpression();
            }
        }
        function nextTokenIsIdentifierOrStartOfDestructuring() {
            nextToken();
            return isIdentifier() || token() === 18 /* OpenBraceToken */ || token() === 22 /* OpenBracketToken */;
        }
        function isLetDeclaration() {
            // In ES6 'let' always starts a lexical declaration if followed by an identifier or {
            // or [.
            return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
        }
        function parseStatement() {
            switch (token()) {
                case 26 /* SemicolonToken */:
                    return parseEmptyStatement();
                case 18 /* OpenBraceToken */:
                    return parseBlock(/*ignoreMissingOpenBrace*/ false);
                case 109 /* VarKeyword */:
                    return parseVariableStatement(createNodeWithJSDoc(242 /* VariableDeclaration */));
                case 115 /* LetKeyword */:
                    if (isLetDeclaration()) {
                        return parseVariableStatement(createNodeWithJSDoc(242 /* VariableDeclaration */));
                    }
                    break;
                case 94 /* FunctionKeyword */:
                    return parseFunctionDeclaration(createNodeWithJSDoc(244 /* FunctionDeclaration */));
                case 80 /* ClassKeyword */:
                    return parseClassDeclaration(createNodeWithJSDoc(245 /* ClassDeclaration */));
                case 95 /* IfKeyword */:
                    return parseIfStatement();
                case 86 /* DoKeyword */:
                    return parseDoStatement();
                case 111 /* WhileKeyword */:
                    return parseWhileStatement();
                case 93 /* ForKeyword */:
                    return parseForOrForInOrForOfStatement();
                case 82 /* ContinueKeyword */:
                    return parseBreakOrContinueStatement(233 /* ContinueStatement */);
                case 77 /* BreakKeyword */:
                    return parseBreakOrContinueStatement(234 /* BreakStatement */);
                case 101 /* ReturnKeyword */:
                    return parseReturnStatement();
                case 112 /* WithKeyword */:
                    return parseWithStatement();
                case 103 /* SwitchKeyword */:
                    return parseSwitchStatement();
                case 105 /* ThrowKeyword */:
                    return parseThrowStatement();
                case 107 /* TryKeyword */:
                // Include 'catch' and 'finally' for error recovery.
                // falls through
                case 79 /* CatchKeyword */:
                case 92 /* FinallyKeyword */:
                    return parseTryStatement();
                case 83 /* DebuggerKeyword */:
                    return parseDebuggerStatement();
                case 59 /* AtToken */:
                    return parseDeclaration();
                case 126 /* AsyncKeyword */:
                case 114 /* InterfaceKeyword */:
                case 145 /* TypeKeyword */:
                case 135 /* ModuleKeyword */:
                case 136 /* NamespaceKeyword */:
                case 130 /* DeclareKeyword */:
                case 81 /* ConstKeyword */:
                case 88 /* EnumKeyword */:
                case 89 /* ExportKeyword */:
                case 96 /* ImportKeyword */:
                case 117 /* PrivateKeyword */:
                case 118 /* ProtectedKeyword */:
                case 119 /* PublicKeyword */:
                case 122 /* AbstractKeyword */:
                case 120 /* StaticKeyword */:
                case 138 /* ReadonlyKeyword */:
                case 150 /* GlobalKeyword */:
                    if (isStartOfDeclaration()) {
                        return parseDeclaration();
                    }
                    break;
            }
            return parseExpressionOrLabeledStatement();
        }
        function isDeclareModifier(modifier) {
            return modifier.kind === 130 /* DeclareKeyword */;
        }
        function parseDeclaration() {
            var modifiers = lookAhead(function () { return (parseDecorators(), parseModifiers()); });
            // `parseListElement` attempted to get the reused node at this position,
            // but the ambient context flag was not yet set, so the node appeared
            // not reusable in that context.
            var isAmbient = ts.some(modifiers, isDeclareModifier);
            if (isAmbient) {
                var node_3 = tryReuseAmbientDeclaration();
                if (node_3) {
                    return node_3;
                }
            }
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers();
            if (isAmbient) {
                for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                    var m = _a[_i];
                    m.flags |= 8388608 /* Ambient */;
                }
                return doInsideOfContext(8388608 /* Ambient */, function () { return parseDeclarationWorker(node); });
            }
            else {
                return parseDeclarationWorker(node);
            }
        }
        function tryReuseAmbientDeclaration() {
            return doInsideOfContext(8388608 /* Ambient */, function () {
                var node = currentNode(parsingContext);
                if (node) {
                    return consumeNode(node);
                }
            });
        }
        function parseDeclarationWorker(node) {
            switch (token()) {
                case 109 /* VarKeyword */:
                case 115 /* LetKeyword */:
                case 81 /* ConstKeyword */:
                    return parseVariableStatement(node);
                case 94 /* FunctionKeyword */:
                    return parseFunctionDeclaration(node);
                case 80 /* ClassKeyword */:
                    return parseClassDeclaration(node);
                case 114 /* InterfaceKeyword */:
                    return parseInterfaceDeclaration(node);
                case 145 /* TypeKeyword */:
                    return parseTypeAliasDeclaration(node);
                case 88 /* EnumKeyword */:
                    return parseEnumDeclaration(node);
                case 150 /* GlobalKeyword */:
                case 135 /* ModuleKeyword */:
                case 136 /* NamespaceKeyword */:
                    return parseModuleDeclaration(node);
                case 96 /* ImportKeyword */:
                    return parseImportDeclarationOrImportEqualsDeclaration(node);
                case 89 /* ExportKeyword */:
                    nextToken();
                    switch (token()) {
                        case 84 /* DefaultKeyword */:
                        case 62 /* EqualsToken */:
                            return parseExportAssignment(node);
                        case 123 /* AsKeyword */:
                            return parseNamespaceExportDeclaration(node);
                        default:
                            return parseExportDeclaration(node);
                    }
                default:
                    if (node.decorators || node.modifiers) {
                        // We reached this point because we encountered decorators and/or modifiers and assumed a declaration
                        // would follow. For recovery and error reporting purposes, return an incomplete declaration.
                        var missing = createMissingNode(264 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                        missing.pos = node.pos;
                        missing.decorators = node.decorators;
                        missing.modifiers = node.modifiers;
                        return finishNode(missing);
                    }
                    return undefined; // TODO: GH#18217
            }
        }
        function nextTokenIsIdentifierOrStringLiteralOnSameLine() {
            nextToken();
            return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === 10 /* StringLiteral */);
        }
        function parseFunctionBlockOrSemicolon(flags, diagnosticMessage) {
            if (token() !== 18 /* OpenBraceToken */ && canParseSemicolon()) {
                parseSemicolon();
                return;
            }
            return parseFunctionBlock(flags, diagnosticMessage);
        }
        // DECLARATIONS
        function parseArrayBindingElement() {
            if (token() === 27 /* CommaToken */) {
                return createNode(215 /* OmittedExpression */);
            }
            var node = createNode(191 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            node.name = parseIdentifierOrPattern();
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        function parseObjectBindingElement() {
            var node = createNode(191 /* BindingElement */);
            node.dotDotDotToken = parseOptionalToken(25 /* DotDotDotToken */);
            var tokenIsIdentifier = isIdentifier();
            var propertyName = parsePropertyName();
            if (tokenIsIdentifier && token() !== 58 /* ColonToken */) {
                node.name = propertyName;
            }
            else {
                parseExpected(58 /* ColonToken */);
                node.propertyName = propertyName;
                node.name = parseIdentifierOrPattern();
            }
            node.initializer = parseInitializer();
            return finishNode(node);
        }
        function parseObjectBindingPattern() {
            var node = createNode(189 /* ObjectBindingPattern */);
            parseExpected(18 /* OpenBraceToken */);
            node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement);
            parseExpected(19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseArrayBindingPattern() {
            var node = createNode(190 /* ArrayBindingPattern */);
            parseExpected(22 /* OpenBracketToken */);
            node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement);
            parseExpected(23 /* CloseBracketToken */);
            return finishNode(node);
        }
        function isIdentifierOrPrivateIdentifierOrPattern() {
            return token() === 18 /* OpenBraceToken */
                || token() === 22 /* OpenBracketToken */
                || token() === 76 /* PrivateIdentifier */
                || isIdentifier();
        }
        function parseIdentifierOrPattern(privateIdentifierDiagnosticMessage) {
            if (token() === 22 /* OpenBracketToken */) {
                return parseArrayBindingPattern();
            }
            if (token() === 18 /* OpenBraceToken */) {
                return parseObjectBindingPattern();
            }
            return parseIdentifier(/*diagnosticMessage*/ undefined, privateIdentifierDiagnosticMessage);
        }
        function parseVariableDeclarationAllowExclamation() {
            return parseVariableDeclaration(/*allowExclamation*/ true);
        }
        function parseVariableDeclaration(allowExclamation) {
            var node = createNode(242 /* VariableDeclaration */);
            node.name = parseIdentifierOrPattern(ts.Diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations);
            if (allowExclamation && node.name.kind === 75 /* Identifier */ &&
                token() === 53 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                node.exclamationToken = parseTokenNode();
            }
            node.type = parseTypeAnnotation();
            if (!isInOrOfKeyword(token())) {
                node.initializer = parseInitializer();
            }
            return finishNode(node);
        }
        function parseVariableDeclarationList(inForStatementInitializer) {
            var node = createNode(243 /* VariableDeclarationList */);
            switch (token()) {
                case 109 /* VarKeyword */:
                    break;
                case 115 /* LetKeyword */:
                    node.flags |= 1 /* Let */;
                    break;
                case 81 /* ConstKeyword */:
                    node.flags |= 2 /* Const */;
                    break;
                default:
                    ts.Debug.fail();
            }
            nextToken();
            // The user may have written the following:
            //
            //    for (let of X) { }
            //
            // In this case, we want to parse an empty declaration list, and then parse 'of'
            // as a keyword. The reason this is not automatic is that 'of' is a valid identifier.
            // So we need to look ahead to determine if 'of' should be treated as a keyword in
            // this context.
            // The checker will then give an error that there is an empty declaration list.
            if (token() === 152 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) {
                node.declarations = createMissingList();
            }
            else {
                var savedDisallowIn = inDisallowInContext();
                setDisallowInContext(inForStatementInitializer);
                node.declarations = parseDelimitedList(8 /* VariableDeclarations */, inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation);
                setDisallowInContext(savedDisallowIn);
            }
            return finishNode(node);
        }
        function canFollowContextualOfKeyword() {
            return nextTokenIsIdentifier() && nextToken() === 21 /* CloseParenToken */;
        }
        function parseVariableStatement(node) {
            node.kind = 225 /* VariableStatement */;
            node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false);
            parseSemicolon();
            return finishNode(node);
        }
        function parseFunctionDeclaration(node) {
            node.kind = 244 /* FunctionDeclaration */;
            parseExpected(94 /* FunctionKeyword */);
            node.asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
            node.name = hasModifierOfKind(node, 84 /* DefaultKeyword */) ? parseOptionalIdentifier() : parseIdentifier();
            var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = hasModifierOfKind(node, 126 /* AsyncKeyword */) ? 2 /* Await */ : 0 /* None */;
            fillSignature(58 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, ts.Diagnostics.or_expected);
            return finishNode(node);
        }
        function parseConstructorName() {
            if (token() === 129 /* ConstructorKeyword */) {
                return parseExpected(129 /* ConstructorKeyword */);
            }
            if (token() === 10 /* StringLiteral */ && lookAhead(nextToken) === 20 /* OpenParenToken */) {
                return tryParse(function () {
                    var literalNode = parseLiteralNode();
                    return literalNode.text === "constructor" ? literalNode : undefined;
                });
            }
        }
        function tryParseConstructorDeclaration(node) {
            return tryParse(function () {
                if (parseConstructorName()) {
                    node.kind = 162 /* Constructor */;
                    fillSignature(58 /* ColonToken */, 0 /* None */, node);
                    node.body = parseFunctionBlockOrSemicolon(0 /* None */, ts.Diagnostics.or_expected);
                    return finishNode(node);
                }
            });
        }
        function parseMethodDeclaration(node, asteriskToken, diagnosticMessage) {
            node.kind = 161 /* MethodDeclaration */;
            node.asteriskToken = asteriskToken;
            var isGenerator = asteriskToken ? 1 /* Yield */ : 0 /* None */;
            var isAsync = hasModifierOfKind(node, 126 /* AsyncKeyword */) ? 2 /* Await */ : 0 /* None */;
            fillSignature(58 /* ColonToken */, isGenerator | isAsync, node);
            node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage);
            return finishNode(node);
        }
        function parsePropertyDeclaration(node) {
            node.kind = 159 /* PropertyDeclaration */;
            if (!node.questionToken && token() === 53 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) {
                node.exclamationToken = parseTokenNode();
            }
            node.type = parseTypeAnnotation();
            node.initializer = doOutsideOfContext(8192 /* YieldContext */ | 32768 /* AwaitContext */ | 4096 /* DisallowInContext */, parseInitializer);
            parseSemicolon();
            return finishNode(node);
        }
        function parsePropertyOrMethodDeclaration(node) {
            var asteriskToken = parseOptionalToken(41 /* AsteriskToken */);
            node.name = parsePropertyName();
            // Note: this is not legal as per the grammar.  But we allow it in the parser and
            // report an error in the grammar checker.
            node.questionToken = parseOptionalToken(57 /* QuestionToken */);
            if (asteriskToken || token() === 20 /* OpenParenToken */ || token() === 29 /* LessThanToken */) {
                return parseMethodDeclaration(node, asteriskToken, ts.Diagnostics.or_expected);
            }
            return parsePropertyDeclaration(node);
        }
        function parseAccessorDeclaration(node, kind) {
            node.kind = kind;
            node.name = parsePropertyName();
            fillSignature(58 /* ColonToken */, 0 /* None */, node);
            node.body = parseFunctionBlockOrSemicolon(0 /* None */);
            return finishNode(node);
        }
        function isClassMemberStart() {
            var idToken;
            if (token() === 59 /* AtToken */) {
                return true;
            }
            // Eat up all modifiers, but hold on to the last one in case it is actually an identifier.
            while (ts.isModifierKind(token())) {
                idToken = token();
                // If the idToken is a class modifier (protected, private, public, and static), it is
                // certain that we are starting to parse class member. This allows better error recovery
                // Example:
                //      public foo() ...     // true
                //      public @dec blah ... // true; we will then report an error later
                //      export public ...    // true; we will then report an error later
                if (ts.isClassMemberModifier(idToken)) {
                    return true;
                }
                nextToken();
            }
            if (token() === 41 /* AsteriskToken */) {
                return true;
            }
            // Try to get the first property-like token following all modifiers.
            // This can either be an identifier or the 'get' or 'set' keywords.
            if (isLiteralPropertyName()) {
                idToken = token();
                nextToken();
            }
            // Index signatures and computed properties are class members; we can parse.
            if (token() === 22 /* OpenBracketToken */) {
                return true;
            }
            // If we were able to get any potential identifier...
            if (idToken !== undefined) {
                // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse.
                if (!ts.isKeyword(idToken) || idToken === 142 /* SetKeyword */ || idToken === 131 /* GetKeyword */) {
                    return true;
                }
                // If it *is* a keyword, but not an accessor, check a little farther along
                // to see if it should actually be parsed as a class member.
                switch (token()) {
                    case 20 /* OpenParenToken */: // Method declaration
                    case 29 /* LessThanToken */: // Generic Method declaration
                    case 53 /* ExclamationToken */: // Non-null assertion on property name
                    case 58 /* ColonToken */: // Type Annotation for declaration
                    case 62 /* EqualsToken */: // Initializer for declaration
                    case 57 /* QuestionToken */: // Not valid, but permitted so that it gets caught later on.
                        return true;
                    default:
                        // Covers
                        //  - Semicolons     (declaration termination)
                        //  - Closing braces (end-of-class, must be declaration)
                        //  - End-of-files   (not valid, but permitted so that it gets caught later on)
                        //  - Line-breaks    (enabling *automatic semicolon insertion*)
                        return canParseSemicolon();
                }
            }
            return false;
        }
        function parseDecorators() {
            var list;
            var listPos = getNodePos();
            while (true) {
                var decoratorStart = getNodePos();
                if (!parseOptional(59 /* AtToken */)) {
                    break;
                }
                var decorator = createNode(157 /* Decorator */, decoratorStart);
                decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher);
                finishNode(decorator);
                (list || (list = [])).push(decorator);
            }
            return list && createNodeArray(list, listPos);
        }
        /*
         * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member.
         * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect
         * and turns it into a standalone declaration), then it is better to parse it and report an error later.
         *
         * In such situations, 'permitInvalidConstAsModifier' should be set to true.
         */
        function parseModifiers(permitInvalidConstAsModifier) {
            var list;
            var listPos = getNodePos();
            while (true) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token();
                if (token() === 81 /* ConstKeyword */ && permitInvalidConstAsModifier) {
                    // We need to ensure that any subsequent modifiers appear on the same line
                    // so that when 'const' is a standalone declaration, we don't issue an error.
                    if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) {
                        break;
                    }
                }
                else {
                    if (!parseAnyContextualModifier()) {
                        break;
                    }
                }
                var modifier = finishNode(createNode(modifierKind, modifierStart));
                (list || (list = [])).push(modifier);
            }
            return list && createNodeArray(list, listPos);
        }
        function parseModifiersForArrowFunction() {
            var modifiers;
            if (token() === 126 /* AsyncKeyword */) {
                var modifierStart = scanner.getStartPos();
                var modifierKind = token();
                nextToken();
                var modifier = finishNode(createNode(modifierKind, modifierStart));
                modifiers = createNodeArray([modifier], modifierStart);
            }
            return modifiers;
        }
        function parseClassElement() {
            if (token() === 26 /* SemicolonToken */) {
                var result = createNode(222 /* SemicolonClassElement */);
                nextToken();
                return finishNode(result);
            }
            var node = createNodeWithJSDoc(0 /* Unknown */);
            node.decorators = parseDecorators();
            node.modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true);
            if (parseContextualModifier(131 /* GetKeyword */)) {
                return parseAccessorDeclaration(node, 163 /* GetAccessor */);
            }
            if (parseContextualModifier(142 /* SetKeyword */)) {
                return parseAccessorDeclaration(node, 164 /* SetAccessor */);
            }
            if (token() === 129 /* ConstructorKeyword */ || token() === 10 /* StringLiteral */) {
                var constructorDeclaration = tryParseConstructorDeclaration(node);
                if (constructorDeclaration) {
                    return constructorDeclaration;
                }
            }
            if (isIndexSignature()) {
                return parseIndexSignatureDeclaration(node);
            }
            // It is very important that we check this *after* checking indexers because
            // the [ token can start an index signature or a computed property name
            if (ts.tokenIsIdentifierOrKeyword(token()) ||
                token() === 10 /* StringLiteral */ ||
                token() === 8 /* NumericLiteral */ ||
                token() === 41 /* AsteriskToken */ ||
                token() === 22 /* OpenBracketToken */) {
                var isAmbient = node.modifiers && ts.some(node.modifiers, isDeclareModifier);
                if (isAmbient) {
                    for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                        var m = _a[_i];
                        m.flags |= 8388608 /* Ambient */;
                    }
                    return doInsideOfContext(8388608 /* Ambient */, function () { return parsePropertyOrMethodDeclaration(node); });
                }
                else {
                    return parsePropertyOrMethodDeclaration(node);
                }
            }
            if (node.decorators || node.modifiers) {
                // treat this as a property declaration with a missing name.
                node.name = createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected);
                return parsePropertyDeclaration(node);
            }
            // 'isClassMemberStart' should have hinted not to attempt parsing.
            return ts.Debug.fail("Should not have attempted to parse class member declaration.");
        }
        function parseClassExpression() {
            return parseClassDeclarationOrExpression(createNodeWithJSDoc(0 /* Unknown */), 214 /* ClassExpression */);
        }
        function parseClassDeclaration(node) {
            return parseClassDeclarationOrExpression(node, 245 /* ClassDeclaration */);
        }
        function parseClassDeclarationOrExpression(node, kind) {
            node.kind = kind;
            parseExpected(80 /* ClassKeyword */);
            node.name = parseNameOfClassDeclarationOrExpression();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses();
            if (parseExpected(18 /* OpenBraceToken */)) {
                // ClassTail[Yield,Await] : (Modified) See 14.5
                //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
                node.members = parseClassMembers();
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return finishNode(node);
        }
        function parseNameOfClassDeclarationOrExpression() {
            // implements is a future reserved word so
            // 'class implements' might mean either
            // - class expression with omitted name, 'implements' starts heritage clause
            // - class with name 'implements'
            // 'isImplementsClause' helps to disambiguate between these two cases
            return isIdentifier() && !isImplementsClause()
                ? parseIdentifier()
                : undefined;
        }
        function isImplementsClause() {
            return token() === 113 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword);
        }
        function parseHeritageClauses() {
            // ClassTail[Yield,Await] : (Modified) See 14.5
            //      ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
            if (isHeritageClause()) {
                return parseList(22 /* HeritageClauses */, parseHeritageClause);
            }
            return undefined;
        }
        function parseHeritageClause() {
            var tok = token();
            ts.Debug.assert(tok === 90 /* ExtendsKeyword */ || tok === 113 /* ImplementsKeyword */); // isListElement() should ensure this.
            var node = createNode(279 /* HeritageClause */);
            node.token = tok;
            nextToken();
            node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments);
            return finishNode(node);
        }
        function parseExpressionWithTypeArguments() {
            var node = createNode(216 /* ExpressionWithTypeArguments */);
            node.expression = parseLeftHandSideExpressionOrHigher();
            node.typeArguments = tryParseTypeArguments();
            return finishNode(node);
        }
        function tryParseTypeArguments() {
            return token() === 29 /* LessThanToken */ ?
                parseBracketedList(20 /* TypeArguments */, parseType, 29 /* LessThanToken */, 31 /* GreaterThanToken */) : undefined;
        }
        function isHeritageClause() {
            return token() === 90 /* ExtendsKeyword */ || token() === 113 /* ImplementsKeyword */;
        }
        function parseClassMembers() {
            return parseList(5 /* ClassMembers */, parseClassElement);
        }
        function parseInterfaceDeclaration(node) {
            node.kind = 246 /* InterfaceDeclaration */;
            parseExpected(114 /* InterfaceKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            node.heritageClauses = parseHeritageClauses();
            node.members = parseObjectTypeMembers();
            return finishNode(node);
        }
        function parseTypeAliasDeclaration(node) {
            node.kind = 247 /* TypeAliasDeclaration */;
            parseExpected(145 /* TypeKeyword */);
            node.name = parseIdentifier();
            node.typeParameters = parseTypeParameters();
            parseExpected(62 /* EqualsToken */);
            node.type = parseType();
            parseSemicolon();
            return finishNode(node);
        }
        // In an ambient declaration, the grammar only allows integer literals as initializers.
        // In a non-ambient declaration, the grammar allows uninitialized members only in a
        // ConstantEnumMemberSection, which starts at the beginning of an enum declaration
        // or any time an integer literal initializer is encountered.
        function parseEnumMember() {
            var node = createNodeWithJSDoc(284 /* EnumMember */);
            node.name = parsePropertyName();
            node.initializer = allowInAnd(parseInitializer);
            return finishNode(node);
        }
        function parseEnumDeclaration(node) {
            node.kind = 248 /* EnumDeclaration */;
            parseExpected(88 /* EnumKeyword */);
            node.name = parseIdentifier();
            if (parseExpected(18 /* OpenBraceToken */)) {
                node.members = doOutsideOfYieldAndAwaitContext(function () { return parseDelimitedList(6 /* EnumMembers */, parseEnumMember); });
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.members = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleBlock() {
            var node = createNode(250 /* ModuleBlock */);
            if (parseExpected(18 /* OpenBraceToken */)) {
                node.statements = parseList(1 /* BlockStatements */, parseStatement);
                parseExpected(19 /* CloseBraceToken */);
            }
            else {
                node.statements = createMissingList();
            }
            return finishNode(node);
        }
        function parseModuleOrNamespaceDeclaration(node, flags) {
            node.kind = 249 /* ModuleDeclaration */;
            // If we are parsing a dotted namespace name, we want to
            // propagate the 'Namespace' flag across the names if set.
            var namespaceFlag = flags & 16 /* Namespace */;
            node.flags |= flags;
            node.name = parseIdentifier();
            node.body = parseOptional(24 /* DotToken */)
                ? parseModuleOrNamespaceDeclaration(createNode(0 /* Unknown */), 4 /* NestedNamespace */ | namespaceFlag)
                : parseModuleBlock();
            return finishNode(node);
        }
        function parseAmbientExternalModuleDeclaration(node) {
            node.kind = 249 /* ModuleDeclaration */;
            if (token() === 150 /* GlobalKeyword */) {
                // parse 'global' as name of global scope augmentation
                node.name = parseIdentifier();
                node.flags |= 1024 /* GlobalAugmentation */;
            }
            else {
                node.name = parseLiteralNode();
                node.name.text = internIdentifier(node.name.text);
            }
            if (token() === 18 /* OpenBraceToken */) {
                node.body = parseModuleBlock();
            }
            else {
                parseSemicolon();
            }
            return finishNode(node);
        }
        function parseModuleDeclaration(node) {
            var flags = 0;
            if (token() === 150 /* GlobalKeyword */) {
                // global augmentation
                return parseAmbientExternalModuleDeclaration(node);
            }
            else if (parseOptional(136 /* NamespaceKeyword */)) {
                flags |= 16 /* Namespace */;
            }
            else {
                parseExpected(135 /* ModuleKeyword */);
                if (token() === 10 /* StringLiteral */) {
                    return parseAmbientExternalModuleDeclaration(node);
                }
            }
            return parseModuleOrNamespaceDeclaration(node, flags);
        }
        function isExternalModuleReference() {
            return token() === 139 /* RequireKeyword */ &&
                lookAhead(nextTokenIsOpenParen);
        }
        function nextTokenIsOpenParen() {
            return nextToken() === 20 /* OpenParenToken */;
        }
        function nextTokenIsSlash() {
            return nextToken() === 43 /* SlashToken */;
        }
        function parseNamespaceExportDeclaration(node) {
            node.kind = 252 /* NamespaceExportDeclaration */;
            parseExpected(123 /* AsKeyword */);
            parseExpected(136 /* NamespaceKeyword */);
            node.name = parseIdentifier();
            parseSemicolon();
            return finishNode(node);
        }
        function parseImportDeclarationOrImportEqualsDeclaration(node) {
            parseExpected(96 /* ImportKeyword */);
            var afterImportPos = scanner.getStartPos();
            var identifier;
            if (isIdentifier()) {
                identifier = parseIdentifier();
            }
            var isTypeOnly = false;
            if (token() !== 149 /* FromKeyword */ &&
                (identifier === null || identifier === void 0 ? void 0 : identifier.escapedText) === "type" &&
                (isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration())) {
                isTypeOnly = true;
                identifier = isIdentifier() ? parseIdentifier() : undefined;
            }
            if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration()) {
                return parseImportEqualsDeclaration(node, identifier, isTypeOnly);
            }
            // Import statement
            node.kind = 254 /* ImportDeclaration */;
            // ImportDeclaration:
            //  import ImportClause from ModuleSpecifier ;
            //  import ModuleSpecifier;
            if (identifier || // import id
                token() === 41 /* AsteriskToken */ || // import *
                token() === 18 /* OpenBraceToken */ // import {
            ) {
                node.importClause = parseImportClause(identifier, afterImportPos, isTypeOnly);
                parseExpected(149 /* FromKeyword */);
            }
            node.moduleSpecifier = parseModuleSpecifier();
            parseSemicolon();
            return finishNode(node);
        }
        function tokenAfterImportDefinitelyProducesImportDeclaration() {
            return token() === 41 /* AsteriskToken */ || token() === 18 /* OpenBraceToken */;
        }
        function tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() {
            // In `import id ___`, the current token decides whether to produce
            // an ImportDeclaration or ImportEqualsDeclaration.
            return token() === 27 /* CommaToken */ || token() === 149 /* FromKeyword */;
        }
        function parseImportEqualsDeclaration(node, identifier, isTypeOnly) {
            node.kind = 253 /* ImportEqualsDeclaration */;
            node.name = identifier;
            parseExpected(62 /* EqualsToken */);
            node.moduleReference = parseModuleReference();
            parseSemicolon();
            var finished = finishNode(node);
            if (isTypeOnly) {
                parseErrorAtRange(finished, ts.Diagnostics.Only_ECMAScript_imports_may_use_import_type);
            }
            return finished;
        }
        function parseImportClause(identifier, fullStart, isTypeOnly) {
            // ImportClause:
            //  ImportedDefaultBinding
            //  NameSpaceImport
            //  NamedImports
            //  ImportedDefaultBinding, NameSpaceImport
            //  ImportedDefaultBinding, NamedImports
            var importClause = createNode(255 /* ImportClause */, fullStart);
            importClause.isTypeOnly = isTypeOnly;
            if (identifier) {
                // ImportedDefaultBinding:
                //  ImportedBinding
                importClause.name = identifier;
            }
            // If there was no default import or if there is comma token after default import
            // parse namespace or named imports
            if (!importClause.name ||
                parseOptional(27 /* CommaToken */)) {
                importClause.namedBindings = token() === 41 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(257 /* NamedImports */);
            }
            return finishNode(importClause);
        }
        function parseModuleReference() {
            return isExternalModuleReference()
                ? parseExternalModuleReference()
                : parseEntityName(/*allowReservedWords*/ false);
        }
        function parseExternalModuleReference() {
            var node = createNode(265 /* ExternalModuleReference */);
            parseExpected(139 /* RequireKeyword */);
            parseExpected(20 /* OpenParenToken */);
            node.expression = parseModuleSpecifier();
            parseExpected(21 /* CloseParenToken */);
            return finishNode(node);
        }
        function parseModuleSpecifier() {
            if (token() === 10 /* StringLiteral */) {
                var result = parseLiteralNode();
                result.text = internIdentifier(result.text);
                return result;
            }
            else {
                // We allow arbitrary expressions here, even though the grammar only allows string
                // literals.  We check to ensure that it is only a string literal later in the grammar
                // check pass.
                return parseExpression();
            }
        }
        function parseNamespaceImport() {
            // NameSpaceImport:
            //  * as ImportedBinding
            var namespaceImport = createNode(256 /* NamespaceImport */);
            parseExpected(41 /* AsteriskToken */);
            parseExpected(123 /* AsKeyword */);
            namespaceImport.name = parseIdentifier();
            return finishNode(namespaceImport);
        }
        function parseNamedImportsOrExports(kind) {
            var node = createNode(kind);
            // NamedImports:
            //  { }
            //  { ImportsList }
            //  { ImportsList, }
            // ImportsList:
            //  ImportSpecifier
            //  ImportsList, ImportSpecifier
            node.elements = parseBracketedList(23 /* ImportOrExportSpecifiers */, kind === 257 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 18 /* OpenBraceToken */, 19 /* CloseBraceToken */);
            return finishNode(node);
        }
        function parseExportSpecifier() {
            return parseImportOrExportSpecifier(263 /* ExportSpecifier */);
        }
        function parseImportSpecifier() {
            return parseImportOrExportSpecifier(258 /* ImportSpecifier */);
        }
        function parseImportOrExportSpecifier(kind) {
            var node = createNode(kind);
            // ImportSpecifier:
            //   BindingIdentifier
            //   IdentifierName as BindingIdentifier
            // ExportSpecifier:
            //   IdentifierName
            //   IdentifierName as IdentifierName
            var checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
            var checkIdentifierStart = scanner.getTokenPos();
            var checkIdentifierEnd = scanner.getTextPos();
            var identifierName = parseIdentifierName();
            if (token() === 123 /* AsKeyword */) {
                node.propertyName = identifierName;
                parseExpected(123 /* AsKeyword */);
                checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier();
                checkIdentifierStart = scanner.getTokenPos();
                checkIdentifierEnd = scanner.getTextPos();
                node.name = parseIdentifierName();
            }
            else {
                node.name = identifierName;
            }
            if (kind === 258 /* ImportSpecifier */ && checkIdentifierIsKeyword) {
                parseErrorAt(checkIdentifierStart, checkIdentifierEnd, ts.Diagnostics.Identifier_expected);
            }
            return finishNode(node);
        }
        function parseNamespaceExport(pos) {
            var node = createNode(262 /* NamespaceExport */, pos);
            node.name = parseIdentifier();
            return finishNode(node);
        }
        function parseExportDeclaration(node) {
            node.kind = 260 /* ExportDeclaration */;
            node.isTypeOnly = parseOptional(145 /* TypeKeyword */);
            var namespaceExportPos = scanner.getStartPos();
            if (parseOptional(41 /* AsteriskToken */)) {
                if (parseOptional(123 /* AsKeyword */)) {
                    node.exportClause = parseNamespaceExport(namespaceExportPos);
                }
                parseExpected(149 /* FromKeyword */);
                node.moduleSpecifier = parseModuleSpecifier();
            }
            else {
                node.exportClause = parseNamedImportsOrExports(261 /* NamedExports */);
                // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios,
                // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`)
                // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect.
                if (token() === 149 /* FromKeyword */ || (token() === 10 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) {
                    parseExpected(149 /* FromKeyword */);
                    node.moduleSpecifier = parseModuleSpecifier();
                }
            }
            parseSemicolon();
            return finishNode(node);
        }
        function parseExportAssignment(node) {
            node.kind = 259 /* ExportAssignment */;
            if (parseOptional(62 /* EqualsToken */)) {
                node.isExportEquals = true;
            }
            else {
                parseExpected(84 /* DefaultKeyword */);
            }
            node.expression = parseAssignmentExpressionOrHigher();
            parseSemicolon();
            return finishNode(node);
        }
        function setExternalModuleIndicator(sourceFile) {
            // Try to use the first top-level import/export when available, then
            // fall back to looking for an 'import.meta' somewhere in the tree if necessary.
            sourceFile.externalModuleIndicator =
                ts.forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) ||
                    getImportMetaIfNecessary(sourceFile);
        }
        function isAnExternalModuleIndicatorNode(node) {
            return hasModifierOfKind(node, 89 /* ExportKeyword */)
                || node.kind === 253 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 265 /* ExternalModuleReference */
                || node.kind === 254 /* ImportDeclaration */
                || node.kind === 259 /* ExportAssignment */
                || node.kind === 260 /* ExportDeclaration */ ? node : undefined;
        }
        function getImportMetaIfNecessary(sourceFile) {
            return sourceFile.flags & 2097152 /* PossiblyContainsImportMeta */ ?
                walkTreeForExternalModuleIndicators(sourceFile) :
                undefined;
        }
        function walkTreeForExternalModuleIndicators(node) {
            return isImportMeta(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
        }
        /** Do not use hasModifier inside the parser; it relies on parent pointers. Use this instead. */
        function hasModifierOfKind(node, kind) {
            return ts.some(node.modifiers, function (m) { return m.kind === kind; });
        }
        function isImportMeta(node) {
            return ts.isMetaProperty(node) && node.keywordToken === 96 /* ImportKeyword */ && node.name.escapedText === "meta";
        }
        var ParsingContext;
        (function (ParsingContext) {
            ParsingContext[ParsingContext["SourceElements"] = 0] = "SourceElements";
            ParsingContext[ParsingContext["BlockStatements"] = 1] = "BlockStatements";
            ParsingContext[ParsingContext["SwitchClauses"] = 2] = "SwitchClauses";
            ParsingContext[ParsingContext["SwitchClauseStatements"] = 3] = "SwitchClauseStatements";
            ParsingContext[ParsingContext["TypeMembers"] = 4] = "TypeMembers";
            ParsingContext[ParsingContext["ClassMembers"] = 5] = "ClassMembers";
            ParsingContext[ParsingContext["EnumMembers"] = 6] = "EnumMembers";
            ParsingContext[ParsingContext["HeritageClauseElement"] = 7] = "HeritageClauseElement";
            ParsingContext[ParsingContext["VariableDeclarations"] = 8] = "VariableDeclarations";
            ParsingContext[ParsingContext["ObjectBindingElements"] = 9] = "ObjectBindingElements";
            ParsingContext[ParsingContext["ArrayBindingElements"] = 10] = "ArrayBindingElements";
            ParsingContext[ParsingContext["ArgumentExpressions"] = 11] = "ArgumentExpressions";
            ParsingContext[ParsingContext["ObjectLiteralMembers"] = 12] = "ObjectLiteralMembers";
            ParsingContext[ParsingContext["JsxAttributes"] = 13] = "JsxAttributes";
            ParsingContext[ParsingContext["JsxChildren"] = 14] = "JsxChildren";
            ParsingContext[ParsingContext["ArrayLiteralMembers"] = 15] = "ArrayLiteralMembers";
            ParsingContext[ParsingContext["Parameters"] = 16] = "Parameters";
            ParsingContext[ParsingContext["JSDocParameters"] = 17] = "JSDocParameters";
            ParsingContext[ParsingContext["RestProperties"] = 18] = "RestProperties";
            ParsingContext[ParsingContext["TypeParameters"] = 19] = "TypeParameters";
            ParsingContext[ParsingContext["TypeArguments"] = 20] = "TypeArguments";
            ParsingContext[ParsingContext["TupleElementTypes"] = 21] = "TupleElementTypes";
            ParsingContext[ParsingContext["HeritageClauses"] = 22] = "HeritageClauses";
            ParsingContext[ParsingContext["ImportOrExportSpecifiers"] = 23] = "ImportOrExportSpecifiers";
            ParsingContext[ParsingContext["Count"] = 24] = "Count"; // Number of parsing contexts
        })(ParsingContext || (ParsingContext = {}));
        var Tristate;
        (function (Tristate) {
            Tristate[Tristate["False"] = 0] = "False";
            Tristate[Tristate["True"] = 1] = "True";
            Tristate[Tristate["Unknown"] = 2] = "Unknown";
        })(Tristate || (Tristate = {}));
        var JSDocParser;
        (function (JSDocParser) {
            function parseJSDocTypeExpressionForTests(content, start, length) {
                initializeState(content, 99 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = createSourceFile("file.js", 99 /* Latest */, 1 /* JS */, /*isDeclarationFile*/ false);
                scanner.setText(content, start, length);
                currentToken = scanner.scan();
                var jsDocTypeExpression = parseJSDocTypeExpression();
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDocTypeExpression ? { jsDocTypeExpression: jsDocTypeExpression, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests;
            // Parses out a JSDoc type expression.
            function parseJSDocTypeExpression(mayOmitBraces) {
                var result = createNode(294 /* JSDocTypeExpression */);
                var hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(18 /* OpenBraceToken */);
                result.type = doInsideOfContext(4194304 /* JSDoc */, parseJSDocType);
                if (!mayOmitBraces || hasBrace) {
                    parseExpectedJSDoc(19 /* CloseBraceToken */);
                }
                fixupParentReferences(result);
                return finishNode(result);
            }
            JSDocParser.parseJSDocTypeExpression = parseJSDocTypeExpression;
            function parseIsolatedJSDocComment(content, start, length) {
                initializeState(content, 99 /* Latest */, /*_syntaxCursor:*/ undefined, 1 /* JS */);
                sourceFile = { languageVariant: 0 /* Standard */, text: content };
                var jsDoc = doInsideOfContext(4194304 /* JSDoc */, function () { return parseJSDocCommentWorker(start, length); });
                var diagnostics = parseDiagnostics;
                clearState();
                return jsDoc ? { jsDoc: jsDoc, diagnostics: diagnostics } : undefined;
            }
            JSDocParser.parseIsolatedJSDocComment = parseIsolatedJSDocComment;
            function parseJSDocComment(parent, start, length) {
                var _a;
                var saveToken = currentToken;
                var saveParseDiagnosticsLength = parseDiagnostics.length;
                var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
                var comment = doInsideOfContext(4194304 /* JSDoc */, function () { return parseJSDocCommentWorker(start, length); });
                if (comment) {
                    comment.parent = parent;
                }
                if (contextFlags & 131072 /* JavaScriptFile */) {
                    if (!sourceFile.jsDocDiagnostics) {
                        sourceFile.jsDocDiagnostics = [];
                    }
                    (_a = sourceFile.jsDocDiagnostics).push.apply(_a, parseDiagnostics);
                }
                currentToken = saveToken;
                parseDiagnostics.length = saveParseDiagnosticsLength;
                parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
                return comment;
            }
            JSDocParser.parseJSDocComment = parseJSDocComment;
            var JSDocState;
            (function (JSDocState) {
                JSDocState[JSDocState["BeginningOfLine"] = 0] = "BeginningOfLine";
                JSDocState[JSDocState["SawAsterisk"] = 1] = "SawAsterisk";
                JSDocState[JSDocState["SavingComments"] = 2] = "SavingComments";
                JSDocState[JSDocState["SavingBackticks"] = 3] = "SavingBackticks";
            })(JSDocState || (JSDocState = {}));
            var PropertyLikeParse;
            (function (PropertyLikeParse) {
                PropertyLikeParse[PropertyLikeParse["Property"] = 1] = "Property";
                PropertyLikeParse[PropertyLikeParse["Parameter"] = 2] = "Parameter";
                PropertyLikeParse[PropertyLikeParse["CallbackParameter"] = 4] = "CallbackParameter";
            })(PropertyLikeParse || (PropertyLikeParse = {}));
            function parseJSDocCommentWorker(start, length) {
                if (start === void 0) { start = 0; }
                var content = sourceText;
                var end = length === undefined ? content.length : start + length;
                length = end - start;
                ts.Debug.assert(start >= 0);
                ts.Debug.assert(start <= end);
                ts.Debug.assert(end <= content.length);
                // Check for /** (JSDoc opening part)
                if (!isJSDocLikeText(content, start)) {
                    return undefined;
                }
                var tags;
                var tagsPos;
                var tagsEnd;
                var comments = [];
                // + 3 for leading /**, - 5 in total for /** */
                return scanner.scanRange(start + 3, length - 5, function () {
                    // Initially we can parse out a tag.  We also have seen a starting asterisk.
                    // This is so that /** * @type */ doesn't parse.
                    var state = 1 /* SawAsterisk */;
                    var margin;
                    // + 4 for leading '/** '
                    var indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4;
                    function pushComment(text) {
                        if (!margin) {
                            margin = indent;
                        }
                        comments.push(text);
                        indent += text.length;
                    }
                    nextTokenJSDoc();
                    while (parseOptionalJsdoc(5 /* WhitespaceTrivia */))
                        ;
                    if (parseOptionalJsdoc(4 /* NewLineTrivia */)) {
                        state = 0 /* BeginningOfLine */;
                        indent = 0;
                    }
                    loop: while (true) {
                        switch (token()) {
                            case 59 /* AtToken */:
                                if (state === 0 /* BeginningOfLine */ || state === 1 /* SawAsterisk */) {
                                    removeTrailingWhitespace(comments);
                                    addTag(parseTag(indent));
                                    // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag.
                                    // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning
                                    // for malformed examples like `/** @param {string} x @returns {number} the length */`
                                    state = 0 /* BeginningOfLine */;
                                    margin = undefined;
                                }
                                else {
                                    pushComment(scanner.getTokenText());
                                }
                                break;
                            case 4 /* NewLineTrivia */:
                                comments.push(scanner.getTokenText());
                                state = 0 /* BeginningOfLine */;
                                indent = 0;
                                break;
                            case 41 /* AsteriskToken */:
                                var asterisk = scanner.getTokenText();
                                if (state === 1 /* SawAsterisk */ || state === 2 /* SavingComments */) {
                                    // If we've already seen an asterisk, then we can no longer parse a tag on this line
                                    state = 2 /* SavingComments */;
                                    pushComment(asterisk);
                                }
                                else {
                                    // Ignore the first asterisk on a line
                                    state = 1 /* SawAsterisk */;
                                    indent += asterisk.length;
                                }
                                break;
                            case 5 /* WhitespaceTrivia */:
                                // only collect whitespace if we're already saving comments or have just crossed the comment indent margin
                                var whitespace = scanner.getTokenText();
                                if (state === 2 /* SavingComments */) {
                                    comments.push(whitespace);
                                }
                                else if (margin !== undefined && indent + whitespace.length > margin) {
                                    comments.push(whitespace.slice(margin - indent - 1));
                                }
                                indent += whitespace.length;
                                break;
                            case 1 /* EndOfFileToken */:
                                break loop;
                            default:
                                // Anything else is doc comment text. We just save it. Because it
                                // wasn't a tag, we can no longer parse a tag on this line until we hit the next
                                // line break.
                                state = 2 /* SavingComments */;
                                pushComment(scanner.getTokenText());
                                break;
                        }
                        nextTokenJSDoc();
                    }
                    removeLeadingNewlines(comments);
                    removeTrailingWhitespace(comments);
                    return createJSDocComment();
                });
                function removeLeadingNewlines(comments) {
                    while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) {
                        comments.shift();
                    }
                }
                function removeTrailingWhitespace(comments) {
                    while (comments.length && comments[comments.length - 1].trim() === "") {
                        comments.pop();
                    }
                }
                function createJSDocComment() {
                    var result = createNode(303 /* JSDocComment */, start);
                    result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd);
                    result.comment = comments.length ? comments.join("") : undefined;
                    return finishNode(result, end);
                }
                function isNextNonwhitespaceTokenEndOfFile() {
                    // We must use infinite lookahead, as there could be any number of newlines :(
                    while (true) {
                        nextTokenJSDoc();
                        if (token() === 1 /* EndOfFileToken */) {
                            return true;
                        }
                        if (!(token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */)) {
                            return false;
                        }
                    }
                }
                function skipWhitespace() {
                    if (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
                            return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
                        }
                    }
                    while (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        nextTokenJSDoc();
                    }
                }
                function skipWhitespaceOrAsterisk() {
                    if (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
                            return ""; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
                        }
                    }
                    var precedingLineBreak = scanner.hasPrecedingLineBreak();
                    var seenLineBreak = false;
                    var indentText = "";
                    while ((precedingLineBreak && token() === 41 /* AsteriskToken */) || token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) {
                        indentText += scanner.getTokenText();
                        if (token() === 4 /* NewLineTrivia */) {
                            precedingLineBreak = true;
                            seenLineBreak = true;
                            indentText = "";
                        }
                        else if (token() === 41 /* AsteriskToken */) {
                            precedingLineBreak = false;
                        }
                        nextTokenJSDoc();
                    }
                    return seenLineBreak ? indentText : "";
                }
                function parseTag(margin) {
                    ts.Debug.assert(token() === 59 /* AtToken */);
                    var start = scanner.getTokenPos();
                    nextTokenJSDoc();
                    var tagName = parseJSDocIdentifierName(/*message*/ undefined);
                    var indentText = skipWhitespaceOrAsterisk();
                    var tag;
                    switch (tagName.escapedText) {
                        case "author":
                            tag = parseAuthorTag(start, tagName, margin);
                            break;
                        case "implements":
                            tag = parseImplementsTag(start, tagName);
                            break;
                        case "augments":
                        case "extends":
                            tag = parseAugmentsTag(start, tagName);
                            break;
                        case "class":
                        case "constructor":
                            tag = parseSimpleTag(start, 310 /* JSDocClassTag */, tagName);
                            break;
                        case "public":
                            tag = parseSimpleTag(start, 311 /* JSDocPublicTag */, tagName);
                            break;
                        case "private":
                            tag = parseSimpleTag(start, 312 /* JSDocPrivateTag */, tagName);
                            break;
                        case "protected":
                            tag = parseSimpleTag(start, 313 /* JSDocProtectedTag */, tagName);
                            break;
                        case "readonly":
                            tag = parseSimpleTag(start, 314 /* JSDocReadonlyTag */, tagName);
                            break;
                        case "this":
                            tag = parseThisTag(start, tagName);
                            break;
                        case "enum":
                            tag = parseEnumTag(start, tagName);
                            break;
                        case "arg":
                        case "argument":
                        case "param":
                            return parseParameterOrPropertyTag(start, tagName, 2 /* Parameter */, margin);
                        case "return":
                        case "returns":
                            tag = parseReturnTag(start, tagName);
                            break;
                        case "template":
                            tag = parseTemplateTag(start, tagName);
                            break;
                        case "type":
                            tag = parseTypeTag(start, tagName);
                            break;
                        case "typedef":
                            tag = parseTypedefTag(start, tagName, margin);
                            break;
                        case "callback":
                            tag = parseCallbackTag(start, tagName, margin);
                            break;
                        default:
                            tag = parseUnknownTag(start, tagName);
                            break;
                    }
                    if (!tag.comment) {
                        // some tags, like typedef and callback, have already parsed their comments earlier
                        if (!indentText) {
                            margin += tag.end - tag.pos;
                        }
                        tag.comment = parseTagComments(margin, indentText.slice(margin));
                    }
                    return tag;
                }
                function parseTagComments(indent, initialMargin) {
                    var comments = [];
                    var state = 0 /* BeginningOfLine */;
                    var margin;
                    function pushComment(text) {
                        if (!margin) {
                            margin = indent;
                        }
                        comments.push(text);
                        indent += text.length;
                    }
                    if (initialMargin !== undefined) {
                        // jump straight to saving comments if there is some initial indentation
                        if (initialMargin !== "") {
                            pushComment(initialMargin);
                        }
                        state = 1 /* SawAsterisk */;
                    }
                    var tok = token();
                    loop: while (true) {
                        switch (tok) {
                            case 4 /* NewLineTrivia */:
                                if (state >= 1 /* SawAsterisk */) {
                                    state = 0 /* BeginningOfLine */;
                                    // don't use pushComment here because we want to keep the margin unchanged
                                    comments.push(scanner.getTokenText());
                                }
                                indent = 0;
                                break;
                            case 59 /* AtToken */:
                                if (state === 3 /* SavingBackticks */) {
                                    comments.push(scanner.getTokenText());
                                    break;
                                }
                                scanner.setTextPos(scanner.getTextPos() - 1);
                            // falls through
                            case 1 /* EndOfFileToken */:
                                // Done
                                break loop;
                            case 5 /* WhitespaceTrivia */:
                                if (state === 2 /* SavingComments */ || state === 3 /* SavingBackticks */) {
                                    pushComment(scanner.getTokenText());
                                }
                                else {
                                    var whitespace = scanner.getTokenText();
                                    // if the whitespace crosses the margin, take only the whitespace that passes the margin
                                    if (margin !== undefined && indent + whitespace.length > margin) {
                                        comments.push(whitespace.slice(margin - indent));
                                    }
                                    indent += whitespace.length;
                                }
                                break;
                            case 18 /* OpenBraceToken */:
                                state = 2 /* SavingComments */;
                                if (lookAhead(function () { return nextTokenJSDoc() === 59 /* AtToken */ && ts.tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && scanner.getTokenText() === "link"; })) {
                                    pushComment(scanner.getTokenText());
                                    nextTokenJSDoc();
                                    pushComment(scanner.getTokenText());
                                    nextTokenJSDoc();
                                }
                                pushComment(scanner.getTokenText());
                                break;
                            case 61 /* BacktickToken */:
                                if (state === 3 /* SavingBackticks */) {
                                    state = 2 /* SavingComments */;
                                }
                                else {
                                    state = 3 /* SavingBackticks */;
                                }
                                pushComment(scanner.getTokenText());
                                break;
                            case 41 /* AsteriskToken */:
                                if (state === 0 /* BeginningOfLine */) {
                                    // leading asterisks start recording on the *next* (non-whitespace) token
                                    state = 1 /* SawAsterisk */;
                                    indent += 1;
                                    break;
                                }
                            // record the * as a comment
                            // falls through
                            default:
                                if (state !== 3 /* SavingBackticks */) {
                                    state = 2 /* SavingComments */; // leading identifiers start recording as well
                                }
                                pushComment(scanner.getTokenText());
                                break;
                        }
                        tok = nextTokenJSDoc();
                    }
                    removeLeadingNewlines(comments);
                    removeTrailingWhitespace(comments);
                    return comments.length === 0 ? undefined : comments.join("");
                }
                function parseUnknownTag(start, tagName) {
                    var result = createNode(306 /* JSDocTag */, start);
                    result.tagName = tagName;
                    return finishNode(result);
                }
                function addTag(tag) {
                    if (!tag) {
                        return;
                    }
                    if (!tags) {
                        tags = [tag];
                        tagsPos = tag.pos;
                    }
                    else {
                        tags.push(tag);
                    }
                    tagsEnd = tag.end;
                }
                function tryParseTypeExpression() {
                    skipWhitespaceOrAsterisk();
                    return token() === 18 /* OpenBraceToken */ ? parseJSDocTypeExpression() : undefined;
                }
                function parseBracketNameInPropertyAndParamTag() {
                    // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar'
                    var isBracketed = parseOptionalJsdoc(22 /* OpenBracketToken */);
                    if (isBracketed) {
                        skipWhitespace();
                    }
                    // a markdown-quoted name: `arg` is not legal jsdoc, but occurs in the wild
                    var isBackquoted = parseOptionalJsdoc(61 /* BacktickToken */);
                    var name = parseJSDocEntityName();
                    if (isBackquoted) {
                        parseExpectedTokenJSDoc(61 /* BacktickToken */);
                    }
                    if (isBracketed) {
                        skipWhitespace();
                        // May have an optional default, e.g. '[foo = 42]'
                        if (parseOptionalToken(62 /* EqualsToken */)) {
                            parseExpression();
                        }
                        parseExpected(23 /* CloseBracketToken */);
                    }
                    return { name: name, isBracketed: isBracketed };
                }
                function isObjectOrObjectArrayTypeReference(node) {
                    switch (node.kind) {
                        case 141 /* ObjectKeyword */:
                            return true;
                        case 174 /* ArrayType */:
                            return isObjectOrObjectArrayTypeReference(node.elementType);
                        default:
                            return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object" && !node.typeArguments;
                    }
                }
                function parseParameterOrPropertyTag(start, tagName, target, indent) {
                    var typeExpression = tryParseTypeExpression();
                    var isNameFirst = !typeExpression;
                    skipWhitespaceOrAsterisk();
                    var _a = parseBracketNameInPropertyAndParamTag(), name = _a.name, isBracketed = _a.isBracketed;
                    skipWhitespace();
                    if (isNameFirst) {
                        typeExpression = tryParseTypeExpression();
                    }
                    var result = target === 1 /* Property */ ?
                        createNode(323 /* JSDocPropertyTag */, start) :
                        createNode(317 /* JSDocParameterTag */, start);
                    var comment = parseTagComments(indent + scanner.getStartPos() - start);
                    var nestedTypeLiteral = target !== 4 /* CallbackParameter */ && parseNestedTypeLiteral(typeExpression, name, target, indent);
                    if (nestedTypeLiteral) {
                        typeExpression = nestedTypeLiteral;
                        isNameFirst = true;
                    }
                    result.tagName = tagName;
                    result.typeExpression = typeExpression;
                    result.name = name;
                    result.isNameFirst = isNameFirst;
                    result.isBracketed = isBracketed;
                    result.comment = comment;
                    return finishNode(result);
                }
                function parseNestedTypeLiteral(typeExpression, name, target, indent) {
                    if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
                        var typeLiteralExpression = createNode(294 /* JSDocTypeExpression */, scanner.getTokenPos());
                        var child = void 0;
                        var jsdocTypeLiteral = void 0;
                        var start_3 = scanner.getStartPos();
                        var children = void 0;
                        while (child = tryParse(function () { return parseChildParameterOrPropertyTag(target, indent, name); })) {
                            if (child.kind === 317 /* JSDocParameterTag */ || child.kind === 323 /* JSDocPropertyTag */) {
                                children = ts.append(children, child);
                            }
                        }
                        if (children) {
                            jsdocTypeLiteral = createNode(304 /* JSDocTypeLiteral */, start_3);
                            jsdocTypeLiteral.jsDocPropertyTags = children;
                            if (typeExpression.type.kind === 174 /* ArrayType */) {
                                jsdocTypeLiteral.isArrayType = true;
                            }
                            typeLiteralExpression.type = finishNode(jsdocTypeLiteral);
                            return finishNode(typeLiteralExpression);
                        }
                    }
                }
                function parseReturnTag(start, tagName) {
                    if (ts.some(tags, ts.isJSDocReturnTag)) {
                        parseErrorAt(tagName.pos, scanner.getTokenPos(), ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    var result = createNode(318 /* JSDocReturnTag */, start);
                    result.tagName = tagName;
                    result.typeExpression = tryParseTypeExpression();
                    return finishNode(result);
                }
                function parseTypeTag(start, tagName) {
                    if (ts.some(tags, ts.isJSDocTypeTag)) {
                        parseErrorAt(tagName.pos, scanner.getTokenPos(), ts.Diagnostics._0_tag_already_specified, tagName.escapedText);
                    }
                    var result = createNode(320 /* JSDocTypeTag */, start);
                    result.tagName = tagName;
                    result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    return finishNode(result);
                }
                function parseAuthorTag(start, tagName, indent) {
                    var result = createNode(309 /* JSDocAuthorTag */, start);
                    result.tagName = tagName;
                    var authorInfoWithEmail = tryParse(function () { return tryParseAuthorNameAndEmail(); });
                    if (!authorInfoWithEmail) {
                        return finishNode(result);
                    }
                    result.comment = authorInfoWithEmail;
                    if (lookAhead(function () { return nextToken() !== 4 /* NewLineTrivia */; })) {
                        var comment = parseTagComments(indent);
                        if (comment) {
                            result.comment += comment;
                        }
                    }
                    return finishNode(result);
                }
                function tryParseAuthorNameAndEmail() {
                    var comments = [];
                    var seenLessThan = false;
                    var seenGreaterThan = false;
                    var token = scanner.getToken();
                    loop: while (true) {
                        switch (token) {
                            case 75 /* Identifier */:
                            case 5 /* WhitespaceTrivia */:
                            case 24 /* DotToken */:
                            case 59 /* AtToken */:
                                comments.push(scanner.getTokenText());
                                break;
                            case 29 /* LessThanToken */:
                                if (seenLessThan || seenGreaterThan) {
                                    return;
                                }
                                seenLessThan = true;
                                comments.push(scanner.getTokenText());
                                break;
                            case 31 /* GreaterThanToken */:
                                if (!seenLessThan || seenGreaterThan) {
                                    return;
                                }
                                seenGreaterThan = true;
                                comments.push(scanner.getTokenText());
                                scanner.setTextPos(scanner.getTokenPos() + 1);
                                break loop;
                            case 4 /* NewLineTrivia */:
                            case 1 /* EndOfFileToken */:
                                break loop;
                        }
                        token = nextTokenJSDoc();
                    }
                    if (seenLessThan && seenGreaterThan) {
                        return comments.length === 0 ? undefined : comments.join("");
                    }
                }
                function parseImplementsTag(start, tagName) {
                    var result = createNode(308 /* JSDocImplementsTag */, start);
                    result.tagName = tagName;
                    result.class = parseExpressionWithTypeArgumentsForAugments();
                    return finishNode(result);
                }
                function parseAugmentsTag(start, tagName) {
                    var result = createNode(307 /* JSDocAugmentsTag */, start);
                    result.tagName = tagName;
                    result.class = parseExpressionWithTypeArgumentsForAugments();
                    return finishNode(result);
                }
                function parseExpressionWithTypeArgumentsForAugments() {
                    var usedBrace = parseOptional(18 /* OpenBraceToken */);
                    var node = createNode(216 /* ExpressionWithTypeArguments */);
                    node.expression = parsePropertyAccessEntityNameExpression();
                    node.typeArguments = tryParseTypeArguments();
                    var res = finishNode(node);
                    if (usedBrace) {
                        parseExpected(19 /* CloseBraceToken */);
                    }
                    return res;
                }
                function parsePropertyAccessEntityNameExpression() {
                    var node = parseJSDocIdentifierName();
                    while (parseOptional(24 /* DotToken */)) {
                        var prop = createNode(194 /* PropertyAccessExpression */, node.pos);
                        prop.expression = node;
                        prop.name = parseJSDocIdentifierName();
                        node = finishNode(prop);
                    }
                    return node;
                }
                function parseSimpleTag(start, kind, tagName) {
                    var tag = createNode(kind, start);
                    tag.tagName = tagName;
                    return finishNode(tag);
                }
                function parseThisTag(start, tagName) {
                    var tag = createNode(319 /* JSDocThisTag */, start);
                    tag.tagName = tagName;
                    tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    skipWhitespace();
                    return finishNode(tag);
                }
                function parseEnumTag(start, tagName) {
                    var tag = createNode(316 /* JSDocEnumTag */, start);
                    tag.tagName = tagName;
                    tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
                    skipWhitespace();
                    return finishNode(tag);
                }
                function parseTypedefTag(start, tagName, indent) {
                    var typeExpression = tryParseTypeExpression();
                    skipWhitespaceOrAsterisk();
                    var typedefTag = createNode(322 /* JSDocTypedefTag */, start);
                    typedefTag.tagName = tagName;
                    typedefTag.fullName = parseJSDocTypeNameWithNamespace();
                    typedefTag.name = getJSDocTypeAliasName(typedefTag.fullName);
                    skipWhitespace();
                    typedefTag.comment = parseTagComments(indent);
                    typedefTag.typeExpression = typeExpression;
                    var end;
                    if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
                        var child = void 0;
                        var jsdocTypeLiteral = void 0;
                        var childTypeTag = void 0;
                        while (child = tryParse(function () { return parseChildPropertyTag(indent); })) {
                            if (!jsdocTypeLiteral) {
                                jsdocTypeLiteral = createNode(304 /* JSDocTypeLiteral */, start);
                            }
                            if (child.kind === 320 /* JSDocTypeTag */) {
                                if (childTypeTag) {
                                    break;
                                }
                                else {
                                    childTypeTag = child;
                                }
                            }
                            else {
                                jsdocTypeLiteral.jsDocPropertyTags = ts.append(jsdocTypeLiteral.jsDocPropertyTags, child);
                            }
                        }
                        if (jsdocTypeLiteral) {
                            if (typeExpression && typeExpression.type.kind === 174 /* ArrayType */) {
                                jsdocTypeLiteral.isArrayType = true;
                            }
                            typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ?
                                childTypeTag.typeExpression :
                                finishNode(jsdocTypeLiteral);
                            end = typedefTag.typeExpression.end;
                        }
                    }
                    // Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace
                    return finishNode(typedefTag, end || typedefTag.comment !== undefined ? scanner.getStartPos() : (typedefTag.fullName || typedefTag.typeExpression || typedefTag.tagName).end);
                }
                function parseJSDocTypeNameWithNamespace(nested) {
                    var pos = scanner.getTokenPos();
                    if (!ts.tokenIsIdentifierOrKeyword(token())) {
                        return undefined;
                    }
                    var typeNameOrNamespaceName = parseJSDocIdentifierName();
                    if (parseOptional(24 /* DotToken */)) {
                        var jsDocNamespaceNode = createNode(249 /* ModuleDeclaration */, pos);
                        if (nested) {
                            jsDocNamespaceNode.flags |= 4 /* NestedNamespace */;
                        }
                        jsDocNamespaceNode.name = typeNameOrNamespaceName;
                        jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(/*nested*/ true);
                        return finishNode(jsDocNamespaceNode);
                    }
                    if (nested) {
                        typeNameOrNamespaceName.isInJSDocNamespace = true;
                    }
                    return typeNameOrNamespaceName;
                }
                function parseCallbackTag(start, tagName, indent) {
                    var callbackTag = createNode(315 /* JSDocCallbackTag */, start);
                    callbackTag.tagName = tagName;
                    callbackTag.fullName = parseJSDocTypeNameWithNamespace();
                    callbackTag.name = getJSDocTypeAliasName(callbackTag.fullName);
                    skipWhitespace();
                    callbackTag.comment = parseTagComments(indent);
                    var child;
                    var jsdocSignature = createNode(305 /* JSDocSignature */, start);
                    jsdocSignature.parameters = [];
                    while (child = tryParse(function () { return parseChildParameterOrPropertyTag(4 /* CallbackParameter */, indent); })) {
                        jsdocSignature.parameters = ts.append(jsdocSignature.parameters, child);
                    }
                    var returnTag = tryParse(function () {
                        if (parseOptionalJsdoc(59 /* AtToken */)) {
                            var tag = parseTag(indent);
                            if (tag && tag.kind === 318 /* JSDocReturnTag */) {
                                return tag;
                            }
                        }
                    });
                    if (returnTag) {
                        jsdocSignature.type = returnTag;
                    }
                    callbackTag.typeExpression = finishNode(jsdocSignature);
                    return finishNode(callbackTag);
                }
                function getJSDocTypeAliasName(fullName) {
                    if (fullName) {
                        var rightNode = fullName;
                        while (true) {
                            if (ts.isIdentifier(rightNode) || !rightNode.body) {
                                return ts.isIdentifier(rightNode) ? rightNode : rightNode.name;
                            }
                            rightNode = rightNode.body;
                        }
                    }
                }
                function escapedTextsEqual(a, b) {
                    while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) {
                        if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) {
                            a = a.left;
                            b = b.left;
                        }
                        else {
                            return false;
                        }
                    }
                    return a.escapedText === b.escapedText;
                }
                function parseChildPropertyTag(indent) {
                    return parseChildParameterOrPropertyTag(1 /* Property */, indent);
                }
                function parseChildParameterOrPropertyTag(target, indent, name) {
                    var canParseTag = true;
                    var seenAsterisk = false;
                    while (true) {
                        switch (nextTokenJSDoc()) {
                            case 59 /* AtToken */:
                                if (canParseTag) {
                                    var child = tryParseChildTag(target, indent);
                                    if (child && (child.kind === 317 /* JSDocParameterTag */ || child.kind === 323 /* JSDocPropertyTag */) &&
                                        target !== 4 /* CallbackParameter */ &&
                                        name && (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) {
                                        return false;
                                    }
                                    return child;
                                }
                                seenAsterisk = false;
                                break;
                            case 4 /* NewLineTrivia */:
                                canParseTag = true;
                                seenAsterisk = false;
                                break;
                            case 41 /* AsteriskToken */:
                                if (seenAsterisk) {
                                    canParseTag = false;
                                }
                                seenAsterisk = true;
                                break;
                            case 75 /* Identifier */:
                                canParseTag = false;
                                break;
                            case 1 /* EndOfFileToken */:
                                return false;
                        }
                    }
                }
                function tryParseChildTag(target, indent) {
                    ts.Debug.assert(token() === 59 /* AtToken */);
                    var start = scanner.getStartPos();
                    nextTokenJSDoc();
                    var tagName = parseJSDocIdentifierName();
                    skipWhitespace();
                    var t;
                    switch (tagName.escapedText) {
                        case "type":
                            return target === 1 /* Property */ && parseTypeTag(start, tagName);
                        case "prop":
                        case "property":
                            t = 1 /* Property */;
                            break;
                        case "arg":
                        case "argument":
                        case "param":
                            t = 2 /* Parameter */ | 4 /* CallbackParameter */;
                            break;
                        default:
                            return false;
                    }
                    if (!(target & t)) {
                        return false;
                    }
                    return parseParameterOrPropertyTag(start, tagName, target, indent);
                }
                function parseTemplateTag(start, tagName) {
                    // the template tag looks like '@template {Constraint} T,U,V'
                    var constraint;
                    if (token() === 18 /* OpenBraceToken */) {
                        constraint = parseJSDocTypeExpression();
                    }
                    var typeParameters = [];
                    var typeParametersPos = getNodePos();
                    do {
                        skipWhitespace();
                        var typeParameter = createNode(155 /* TypeParameter */);
                        typeParameter.name = parseJSDocIdentifierName(ts.Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces);
                        finishNode(typeParameter);
                        skipWhitespaceOrAsterisk();
                        typeParameters.push(typeParameter);
                    } while (parseOptionalJsdoc(27 /* CommaToken */));
                    var result = createNode(321 /* JSDocTemplateTag */, start);
                    result.tagName = tagName;
                    result.constraint = constraint;
                    result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
                    finishNode(result);
                    return result;
                }
                function parseOptionalJsdoc(t) {
                    if (token() === t) {
                        nextTokenJSDoc();
                        return true;
                    }
                    return false;
                }
                function parseJSDocEntityName() {
                    var entity = parseJSDocIdentifierName();
                    if (parseOptional(22 /* OpenBracketToken */)) {
                        parseExpected(23 /* CloseBracketToken */);
                        // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking.
                        // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}>
                        // but it's not worth it to enforce that restriction.
                    }
                    while (parseOptional(24 /* DotToken */)) {
                        var name = parseJSDocIdentifierName();
                        if (parseOptional(22 /* OpenBracketToken */)) {
                            parseExpected(23 /* CloseBracketToken */);
                        }
                        entity = createQualifiedName(entity, name);
                    }
                    return entity;
                }
                function parseJSDocIdentifierName(message) {
                    if (!ts.tokenIsIdentifierOrKeyword(token())) {
                        return createMissingNode(75 /* Identifier */, /*reportAtCurrentPosition*/ !message, message || ts.Diagnostics.Identifier_expected);
                    }
                    identifierCount++;
                    var pos = scanner.getTokenPos();
                    var end = scanner.getTextPos();
                    var result = createNode(75 /* Identifier */, pos);
                    if (token() !== 75 /* Identifier */) {
                        result.originalKeywordKind = token();
                    }
                    result.escapedText = ts.escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue()));
                    finishNode(result, end);
                    nextTokenJSDoc();
                    return result;
                }
            }
        })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {}));
    })(Parser || (Parser = {}));
    var IncrementalParser;
    (function (IncrementalParser) {
        function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) {
            aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */);
            checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks);
            if (ts.textChangeRangeIsUnchanged(textChangeRange)) {
                // if the text didn't change, then we can just return our current source file as-is.
                return sourceFile;
            }
            if (sourceFile.statements.length === 0) {
                // If we don't have any statements in the current source file, then there's no real
                // way to incrementally parse.  So just do a full parse instead.
                return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind);
            }
            // Make sure we're not trying to incrementally update a source file more than once.  Once
            // we do an update the original source file is considered unusable from that point onwards.
            //
            // This is because we do incremental parsing in-place.  i.e. we take nodes from the old
            // tree and give them new positions and parents.  From that point on, trusting the old
            // tree at all is not possible as far too much of it may violate invariants.
            var incrementalSourceFile = sourceFile;
            ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
            incrementalSourceFile.hasBeenIncrementallyParsed = true;
            var oldText = sourceFile.text;
            var syntaxCursor = createSyntaxCursor(sourceFile);
            // Make the actual change larger so that we know to reparse anything whose lookahead
            // might have intersected the change.
            var changeRange = extendToAffectedRange(sourceFile, textChangeRange);
            checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks);
            // Ensure that extending the affected range only moved the start of the change range
            // earlier in the file.
            ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start);
            ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span));
            ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)));
            // The is the amount the nodes after the edit range need to be adjusted.  It can be
            // positive (if the edit added characters), negative (if the edit deleted characters)
            // or zero (if this was a pure overwrite with nothing added/removed).
            var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length;
            // If we added or removed characters during the edit, then we need to go and adjust all
            // the nodes after the edit.  Those nodes may move forward (if we inserted chars) or they
            // may move backward (if we deleted chars).
            //
            // Doing this helps us out in two ways.  First, it means that any nodes/tokens we want
            // to reuse are already at the appropriate position in the new text.  That way when we
            // reuse them, we don't have to figure out if they need to be adjusted.  Second, it makes
            // it very easy to determine if we can reuse a node.  If the node's position is at where
            // we are in the text, then we can reuse it.  Otherwise we can't.  If the node's position
            // is ahead of us, then we'll need to rescan tokens.  If the node's position is behind
            // us, then we'll need to skip it or crumble it as appropriate
            //
            // We will also adjust the positions of nodes that intersect the change range as well.
            // By doing this, we ensure that all the positions in the old tree are consistent, not
            // just the positions of nodes entirely before/after the change range.  By being
            // consistent, we can then easily map from positions to nodes in the old tree easily.
            //
            // Also, mark any syntax elements that intersect the changed span.  We know, up front,
            // that we cannot reuse these elements.
            updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
            // Now that we've set up our internal incremental state just proceed and parse the
            // source file in the normal fashion.  When possible the parser will retrieve and
            // reuse nodes from the old tree.
            //
            // Note: passing in 'true' for setNodeParents is very important.  When incrementally
            // parsing, we will be reusing nodes from the old tree, and placing it into new
            // parents.  If we don't set the parents now, we'll end up with an observably
            // inconsistent tree.  Setting the parents on the new tree should be very fast.  We
            // will immediately bail out of walking any subtrees when we can see that their parents
            // are already correct.
            var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind);
            result.commentDirectives = getNewCommentDirectives(sourceFile.commentDirectives, result.commentDirectives, changeRange.span.start, ts.textSpanEnd(changeRange.span), delta, oldText, newText, aggressiveChecks);
            return result;
        }
        IncrementalParser.updateSourceFile = updateSourceFile;
        function getNewCommentDirectives(oldDirectives, newDirectives, changeStart, changeRangeOldEnd, delta, oldText, newText, aggressiveChecks) {
            if (!oldDirectives)
                return newDirectives;
            var commentDirectives;
            var addedNewlyScannedDirectives = false;
            for (var _i = 0, oldDirectives_1 = oldDirectives; _i < oldDirectives_1.length; _i++) {
                var directive = oldDirectives_1[_i];
                var range = directive.range, type = directive.type;
                // Range before the change
                if (range.end < changeStart) {
                    commentDirectives = ts.append(commentDirectives, directive);
                }
                else if (range.pos > changeRangeOldEnd) {
                    addNewlyScannedDirectives();
                    // Node is entirely past the change range.  We need to move both its pos and
                    // end, forward or backward appropriately.
                    var updatedDirective = {
                        range: { pos: range.pos + delta, end: range.end + delta },
                        type: type
                    };
                    commentDirectives = ts.append(commentDirectives, updatedDirective);
                    if (aggressiveChecks) {
                        ts.Debug.assert(oldText.substring(range.pos, range.end) === newText.substring(updatedDirective.range.pos, updatedDirective.range.end));
                    }
                }
                // Ignore ranges that fall in change range
            }
            addNewlyScannedDirectives();
            return commentDirectives;
            function addNewlyScannedDirectives() {
                if (addedNewlyScannedDirectives)
                    return;
                addedNewlyScannedDirectives = true;
                if (!commentDirectives) {
                    commentDirectives = newDirectives;
                }
                else if (newDirectives) {
                    commentDirectives.push.apply(commentDirectives, newDirectives);
                }
            }
        }
        function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) {
            if (isArray) {
                visitArray(element);
            }
            else {
                visitNode(element);
            }
            return;
            function visitNode(node) {
                var text = "";
                if (aggressiveChecks && shouldCheckNode(node)) {
                    text = oldText.substring(node.pos, node.end);
                }
                // Ditch any existing LS children we may have created.  This way we can avoid
                // moving them forward.
                if (node._children) {
                    node._children = undefined;
                }
                node.pos += delta;
                node.end += delta;
                if (aggressiveChecks && shouldCheckNode(node)) {
                    ts.Debug.assert(text === newText.substring(node.pos, node.end));
                }
                forEachChild(node, visitNode, visitArray);
                if (ts.hasJSDocNodes(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsDocComment = _a[_i];
                        visitNode(jsDocComment);
                    }
                }
                checkNodePositions(node, aggressiveChecks);
            }
            function visitArray(array) {
                array._children = undefined;
                array.pos += delta;
                array.end += delta;
                for (var _i = 0, array_8 = array; _i < array_8.length; _i++) {
                    var node = array_8[_i];
                    visitNode(node);
                }
            }
        }
        function shouldCheckNode(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 75 /* Identifier */:
                    return true;
            }
            return false;
        }
        function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) {
            ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
            ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
            ts.Debug.assert(element.pos <= element.end);
            // We have an element that intersects the change range in some way.  It may have its
            // start, or its end (or both) in the changed range.  We want to adjust any part
            // that intersects such that the final tree is in a consistent state.  i.e. all
            // children have spans within the span of their parent, and all siblings are ordered
            // properly.
            // We may need to update both the 'pos' and the 'end' of the element.
            // If the 'pos' is before the start of the change, then we don't need to touch it.
            // If it isn't, then the 'pos' must be inside the change.  How we update it will
            // depend if delta is positive or negative. If delta is positive then we have
            // something like:
            //
            //  -------------------AAA-----------------
            //  -------------------BBBCCCCCCC-----------------
            //
            // In this case, we consider any node that started in the change range to still be
            // starting at the same position.
            //
            // however, if the delta is negative, then we instead have something like this:
            //
            //  -------------------XXXYYYYYYY-----------------
            //  -------------------ZZZ-----------------
            //
            // In this case, any element that started in the 'X' range will keep its position.
            // However any element that started after that will have their pos adjusted to be
            // at the end of the new range.  i.e. any node that started in the 'Y' range will
            // be adjusted to have their start at the end of the 'Z' range.
            //
            // The element will keep its position if possible.  Or Move backward to the new-end
            // if it's in the 'Y' range.
            element.pos = Math.min(element.pos, changeRangeNewEnd);
            // If the 'end' is after the change range, then we always adjust it by the delta
            // amount.  However, if the end is in the change range, then how we adjust it
            // will depend on if delta is positive or negative.  If delta is positive then we
            // have something like:
            //
            //  -------------------AAA-----------------
            //  -------------------BBBCCCCCCC-----------------
            //
            // In this case, we consider any node that ended inside the change range to keep its
            // end position.
            //
            // however, if the delta is negative, then we instead have something like this:
            //
            //  -------------------XXXYYYYYYY-----------------
            //  -------------------ZZZ-----------------
            //
            // In this case, any element that ended in the 'X' range will keep its position.
            // However any element that ended after that will have their pos adjusted to be
            // at the end of the new range.  i.e. any node that ended in the 'Y' range will
            // be adjusted to have their end at the end of the 'Z' range.
            if (element.end >= changeRangeOldEnd) {
                // Element ends after the change range.  Always adjust the end pos.
                element.end += delta;
            }
            else {
                // Element ends in the change range.  The element will keep its position if
                // possible. Or Move backward to the new-end if it's in the 'Y' range.
                element.end = Math.min(element.end, changeRangeNewEnd);
            }
            ts.Debug.assert(element.pos <= element.end);
            if (element.parent) {
                ts.Debug.assert(element.pos >= element.parent.pos);
                ts.Debug.assert(element.end <= element.parent.end);
            }
        }
        function checkNodePositions(node, aggressiveChecks) {
            if (aggressiveChecks) {
                var pos_2 = node.pos;
                var visitNode_1 = function (child) {
                    ts.Debug.assert(child.pos >= pos_2);
                    pos_2 = child.end;
                };
                if (ts.hasJSDocNodes(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var jsDocComment = _a[_i];
                        visitNode_1(jsDocComment);
                    }
                }
                forEachChild(node, visitNode_1);
                ts.Debug.assert(pos_2 <= node.end);
            }
        }
        function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) {
            visitNode(sourceFile);
            return;
            function visitNode(child) {
                ts.Debug.assert(child.pos <= child.end);
                if (child.pos > changeRangeOldEnd) {
                    // Node is entirely past the change range.  We need to move both its pos and
                    // end, forward or backward appropriately.
                    moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
                    return;
                }
                // Check if the element intersects the change range.  If it does, then it is not
                // reusable.  Also, we'll need to recurse to see what constituent portions we may
                // be able to use.
                var fullEnd = child.end;
                if (fullEnd >= changeStart) {
                    child.intersectsChange = true;
                    child._children = undefined;
                    // Adjust the pos or end (or both) of the intersecting element accordingly.
                    adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
                    forEachChild(child, visitNode, visitArray);
                    if (ts.hasJSDocNodes(child)) {
                        for (var _i = 0, _a = child.jsDoc; _i < _a.length; _i++) {
                            var jsDocComment = _a[_i];
                            visitNode(jsDocComment);
                        }
                    }
                    checkNodePositions(child, aggressiveChecks);
                    return;
                }
                // Otherwise, the node is entirely before the change range.  No need to do anything with it.
                ts.Debug.assert(fullEnd < changeStart);
            }
            function visitArray(array) {
                ts.Debug.assert(array.pos <= array.end);
                if (array.pos > changeRangeOldEnd) {
                    // Array is entirely after the change range.  We need to move it, and move any of
                    // its children.
                    moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
                    return;
                }
                // Check if the element intersects the change range.  If it does, then it is not
                // reusable.  Also, we'll need to recurse to see what constituent portions we may
                // be able to use.
                var fullEnd = array.end;
                if (fullEnd >= changeStart) {
                    array.intersectsChange = true;
                    array._children = undefined;
                    // Adjust the pos or end (or both) of the intersecting array accordingly.
                    adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
                    for (var _i = 0, array_9 = array; _i < array_9.length; _i++) {
                        var node = array_9[_i];
                        visitNode(node);
                    }
                    return;
                }
                // Otherwise, the array is entirely before the change range.  No need to do anything with it.
                ts.Debug.assert(fullEnd < changeStart);
            }
        }
        function extendToAffectedRange(sourceFile, changeRange) {
            // Consider the following code:
            //      void foo() { /; }
            //
            // If the text changes with an insertion of / just before the semicolon then we end up with:
            //      void foo() { //; }
            //
            // If we were to just use the changeRange a is, then we would not rescan the { token
            // (as it does not intersect the actual original change range).  Because an edit may
            // change the token touching it, we actually need to look back *at least* one token so
            // that the prior token sees that change.
            var maxLookahead = 1;
            var start = changeRange.span.start;
            // the first iteration aligns us with the change start. subsequent iteration move us to
            // the left by maxLookahead tokens.  We only need to do this as long as we're not at the
            // start of the tree.
            for (var i = 0; start > 0 && i <= maxLookahead; i++) {
                var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start);
                ts.Debug.assert(nearestNode.pos <= start);
                var position = nearestNode.pos;
                start = Math.max(0, position - 1);
            }
            var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span));
            var finalLength = changeRange.newLength + (changeRange.span.start - start);
            return ts.createTextChangeRange(finalSpan, finalLength);
        }
        function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) {
            var bestResult = sourceFile;
            var lastNodeEntirelyBeforePosition;
            forEachChild(sourceFile, visit);
            if (lastNodeEntirelyBeforePosition) {
                var lastChildOfLastEntireNodeBeforePosition = getLastDescendant(lastNodeEntirelyBeforePosition);
                if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) {
                    bestResult = lastChildOfLastEntireNodeBeforePosition;
                }
            }
            return bestResult;
            function getLastDescendant(node) {
                while (true) {
                    var lastChild = ts.getLastChild(node);
                    if (lastChild) {
                        node = lastChild;
                    }
                    else {
                        return node;
                    }
                }
            }
            function visit(child) {
                if (ts.nodeIsMissing(child)) {
                    // Missing nodes are effectively invisible to us.  We never even consider them
                    // When trying to find the nearest node before us.
                    return;
                }
                // If the child intersects this position, then this node is currently the nearest
                // node that starts before the position.
                if (child.pos <= position) {
                    if (child.pos >= bestResult.pos) {
                        // This node starts before the position, and is closer to the position than
                        // the previous best node we found.  It is now the new best node.
                        bestResult = child;
                    }
                    // Now, the node may overlap the position, or it may end entirely before the
                    // position.  If it overlaps with the position, then either it, or one of its
                    // children must be the nearest node before the position.  So we can just
                    // recurse into this child to see if we can find something better.
                    if (position < child.end) {
                        // The nearest node is either this child, or one of the children inside
                        // of it.  We've already marked this child as the best so far.  Recurse
                        // in case one of the children is better.
                        forEachChild(child, visit);
                        // Once we look at the children of this node, then there's no need to
                        // continue any further.
                        return true;
                    }
                    else {
                        ts.Debug.assert(child.end <= position);
                        // The child ends entirely before this position.  Say you have the following
                        // (where $ is the position)
                        //
                        //      <complex expr 1> ? <complex expr 2> $ : <...> <...>
                        //
                        // We would want to find the nearest preceding node in "complex expr 2".
                        // To support that, we keep track of this node, and once we're done searching
                        // for a best node, we recurse down this node to see if we can find a good
                        // result in it.
                        //
                        // This approach allows us to quickly skip over nodes that are entirely
                        // before the position, while still allowing us to find any nodes in the
                        // last one that might be what we want.
                        lastNodeEntirelyBeforePosition = child;
                    }
                }
                else {
                    ts.Debug.assert(child.pos > position);
                    // We're now at a node that is entirely past the position we're searching for.
                    // This node (and all following nodes) could never contribute to the result,
                    // so just skip them by returning 'true' here.
                    return true;
                }
            }
        }
        function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) {
            var oldText = sourceFile.text;
            if (textChangeRange) {
                ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length);
                if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) {
                    var oldTextPrefix = oldText.substr(0, textChangeRange.span.start);
                    var newTextPrefix = newText.substr(0, textChangeRange.span.start);
                    ts.Debug.assert(oldTextPrefix === newTextPrefix);
                    var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length);
                    var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length);
                    ts.Debug.assert(oldTextSuffix === newTextSuffix);
                }
            }
        }
        function createSyntaxCursor(sourceFile) {
            var currentArray = sourceFile.statements;
            var currentArrayIndex = 0;
            ts.Debug.assert(currentArrayIndex < currentArray.length);
            var current = currentArray[currentArrayIndex];
            var lastQueriedPosition = -1 /* Value */;
            return {
                currentNode: function (position) {
                    // Only compute the current node if the position is different than the last time
                    // we were asked.  The parser commonly asks for the node at the same position
                    // twice.  Once to know if can read an appropriate list element at a certain point,
                    // and then to actually read and consume the node.
                    if (position !== lastQueriedPosition) {
                        // Much of the time the parser will need the very next node in the array that
                        // we just returned a node from.So just simply check for that case and move
                        // forward in the array instead of searching for the node again.
                        if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) {
                            currentArrayIndex++;
                            current = currentArray[currentArrayIndex];
                        }
                        // If we don't have a node, or the node we have isn't in the right position,
                        // then try to find a viable node at the position requested.
                        if (!current || current.pos !== position) {
                            findHighestListElementThatStartsAtPosition(position);
                        }
                    }
                    // Cache this query so that we don't do any extra work if the parser calls back
                    // into us.  Note: this is very common as the parser will make pairs of calls like
                    // 'isListElement -> parseListElement'.  If we were unable to find a node when
                    // called with 'isListElement', we don't want to redo the work when parseListElement
                    // is called immediately after.
                    lastQueriedPosition = position;
                    // Either we don'd have a node, or we have a node at the position being asked for.
                    ts.Debug.assert(!current || current.pos === position);
                    return current;
                }
            };
            // Finds the highest element in the tree we can find that starts at the provided position.
            // The element must be a direct child of some node list in the tree.  This way after we
            // return it, we can easily return its next sibling in the list.
            function findHighestListElementThatStartsAtPosition(position) {
                // Clear out any cached state about the last node we found.
                currentArray = undefined;
                currentArrayIndex = -1 /* Value */;
                current = undefined;
                // Recurse into the source file to find the highest node at this position.
                forEachChild(sourceFile, visitNode, visitArray);
                return;
                function visitNode(node) {
                    if (position >= node.pos && position < node.end) {
                        // Position was within this node.  Keep searching deeper to find the node.
                        forEachChild(node, visitNode, visitArray);
                        // don't proceed any further in the search.
                        return true;
                    }
                    // position wasn't in this node, have to keep searching.
                    return false;
                }
                function visitArray(array) {
                    if (position >= array.pos && position < array.end) {
                        // position was in this array.  Search through this array to see if we find a
                        // viable element.
                        for (var i = 0; i < array.length; i++) {
                            var child = array[i];
                            if (child) {
                                if (child.pos === position) {
                                    // Found the right node.  We're done.
                                    currentArray = array;
                                    currentArrayIndex = i;
                                    current = child;
                                    return true;
                                }
                                else {
                                    if (child.pos < position && position < child.end) {
                                        // Position in somewhere within this child.  Search in it and
                                        // stop searching in this array.
                                        forEachChild(child, visitNode, visitArray);
                                        return true;
                                    }
                                }
                            }
                        }
                    }
                    // position wasn't in this array, have to keep searching.
                    return false;
                }
            }
        }
        var InvalidPosition;
        (function (InvalidPosition) {
            InvalidPosition[InvalidPosition["Value"] = -1] = "Value";
        })(InvalidPosition || (InvalidPosition = {}));
    })(IncrementalParser || (IncrementalParser = {}));
    /** @internal */
    function isDeclarationFileName(fileName) {
        return ts.fileExtensionIs(fileName, ".d.ts" /* Dts */);
    }
    ts.isDeclarationFileName = isDeclarationFileName;
    /*@internal*/
    function processCommentPragmas(context, sourceText) {
        var pragmas = [];
        for (var _i = 0, _a = ts.getLeadingCommentRanges(sourceText, 0) || ts.emptyArray; _i < _a.length; _i++) {
            var range = _a[_i];
            var comment = sourceText.substring(range.pos, range.end);
            extractPragmas(pragmas, range, comment);
        }
        context.pragmas = ts.createMap();
        for (var _b = 0, pragmas_1 = pragmas; _b < pragmas_1.length; _b++) {
            var pragma = pragmas_1[_b];
            if (context.pragmas.has(pragma.name)) {
                var currentValue = context.pragmas.get(pragma.name);
                if (currentValue instanceof Array) {
                    currentValue.push(pragma.args);
                }
                else {
                    context.pragmas.set(pragma.name, [currentValue, pragma.args]);
                }
                continue;
            }
            context.pragmas.set(pragma.name, pragma.args);
        }
    }
    ts.processCommentPragmas = processCommentPragmas;
    /*@internal*/
    function processPragmasIntoFields(context, reportDiagnostic) {
        context.checkJsDirective = undefined;
        context.referencedFiles = [];
        context.typeReferenceDirectives = [];
        context.libReferenceDirectives = [];
        context.amdDependencies = [];
        context.hasNoDefaultLib = false;
        context.pragmas.forEach(function (entryOrList, key) {
            // TODO: The below should be strongly type-guarded and not need casts/explicit annotations, since entryOrList is related to
            // key and key is constrained to a union; but it's not (see GH#21483 for at least partial fix) :(
            switch (key) {
                case "reference": {
                    var referencedFiles_1 = context.referencedFiles;
                    var typeReferenceDirectives_1 = context.typeReferenceDirectives;
                    var libReferenceDirectives_1 = context.libReferenceDirectives;
                    ts.forEach(ts.toArray(entryOrList), function (arg) {
                        var _a = arg.arguments, types = _a.types, lib = _a.lib, path = _a.path;
                        if (arg.arguments["no-default-lib"]) {
                            context.hasNoDefaultLib = true;
                        }
                        else if (types) {
                            typeReferenceDirectives_1.push({ pos: types.pos, end: types.end, fileName: types.value });
                        }
                        else if (lib) {
                            libReferenceDirectives_1.push({ pos: lib.pos, end: lib.end, fileName: lib.value });
                        }
                        else if (path) {
                            referencedFiles_1.push({ pos: path.pos, end: path.end, fileName: path.value });
                        }
                        else {
                            reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, ts.Diagnostics.Invalid_reference_directive_syntax);
                        }
                    });
                    break;
                }
                case "amd-dependency": {
                    context.amdDependencies = ts.map(ts.toArray(entryOrList), function (x) { return ({ name: x.arguments.name, path: x.arguments.path }); });
                    break;
                }
                case "amd-module": {
                    if (entryOrList instanceof Array) {
                        for (var _i = 0, entryOrList_1 = entryOrList; _i < entryOrList_1.length; _i++) {
                            var entry = entryOrList_1[_i];
                            if (context.moduleName) {
                                // TODO: It's probably fine to issue this diagnostic on all instances of the pragma
                                reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, ts.Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments);
                            }
                            context.moduleName = entry.arguments.name;
                        }
                    }
                    else {
                        context.moduleName = entryOrList.arguments.name;
                    }
                    break;
                }
                case "ts-nocheck":
                case "ts-check": {
                    // _last_ of either nocheck or check in a file is the "winner"
                    ts.forEach(ts.toArray(entryOrList), function (entry) {
                        if (!context.checkJsDirective || entry.range.pos > context.checkJsDirective.pos) {
                            context.checkJsDirective = {
                                enabled: key === "ts-check",
                                end: entry.range.end,
                                pos: entry.range.pos
                            };
                        }
                    });
                    break;
                }
                case "jsx": return; // Accessed directly
                default: ts.Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future?
            }
        });
    }
    ts.processPragmasIntoFields = processPragmasIntoFields;
    var namedArgRegExCache = ts.createMap();
    function getNamedArgRegEx(name) {
        if (namedArgRegExCache.has(name)) {
            return namedArgRegExCache.get(name);
        }
        var result = new RegExp("(\\s" + name + "\\s*=\\s*)('|\")(.+?)\\2", "im");
        namedArgRegExCache.set(name, result);
        return result;
    }
    var tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/im;
    var singleLinePragmaRegEx = /^\/\/\/?\s*@(\S+)\s*(.*)\s*$/im;
    function extractPragmas(pragmas, range, text) {
        var tripleSlash = range.kind === 2 /* SingleLineCommentTrivia */ && tripleSlashXMLCommentStartRegEx.exec(text);
        if (tripleSlash) {
            var name = tripleSlash[1].toLowerCase(); // Technically unsafe cast, but we do it so the below check to make it safe typechecks
            var pragma = ts.commentPragmas[name];
            if (!pragma || !(pragma.kind & 1 /* TripleSlashXML */)) {
                return;
            }
            if (pragma.args) {
                var argument = {};
                for (var _i = 0, _a = pragma.args; _i < _a.length; _i++) {
                    var arg = _a[_i];
                    var matcher = getNamedArgRegEx(arg.name);
                    var matchResult = matcher.exec(text);
                    if (!matchResult && !arg.optional) {
                        return; // Missing required argument, don't parse
                    }
                    else if (matchResult) {
                        if (arg.captureSpan) {
                            var startPos = range.pos + matchResult.index + matchResult[1].length + matchResult[2].length;
                            argument[arg.name] = {
                                value: matchResult[3],
                                pos: startPos,
                                end: startPos + matchResult[3].length
                            };
                        }
                        else {
                            argument[arg.name] = matchResult[3];
                        }
                    }
                }
                pragmas.push({ name: name, args: { arguments: argument, range: range } });
            }
            else {
                pragmas.push({ name: name, args: { arguments: {}, range: range } });
            }
            return;
        }
        var singleLine = range.kind === 2 /* SingleLineCommentTrivia */ && singleLinePragmaRegEx.exec(text);
        if (singleLine) {
            return addPragmaForMatch(pragmas, range, 2 /* SingleLine */, singleLine);
        }
        if (range.kind === 3 /* MultiLineCommentTrivia */) {
            var multiLinePragmaRegEx = /\s*@(\S+)\s*(.*)\s*$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
            var multiLineMatch = void 0;
            while (multiLineMatch = multiLinePragmaRegEx.exec(text)) {
                addPragmaForMatch(pragmas, range, 4 /* MultiLine */, multiLineMatch);
            }
        }
    }
    function addPragmaForMatch(pragmas, range, kind, match) {
        if (!match)
            return;
        var name = match[1].toLowerCase(); // Technically unsafe cast, but we do it so they below check to make it safe typechecks
        var pragma = ts.commentPragmas[name];
        if (!pragma || !(pragma.kind & kind)) {
            return;
        }
        var args = match[2]; // Split on spaces and match up positionally with definition
        var argument = getNamedPragmaArguments(pragma, args);
        if (argument === "fail")
            return; // Missing required argument, fail to parse it
        pragmas.push({ name: name, args: { arguments: argument, range: range } });
        return;
    }
    function getNamedPragmaArguments(pragma, text) {
        if (!text)
            return {};
        if (!pragma.args)
            return {};
        var args = text.split(/\s+/);
        var argMap = {};
        for (var i = 0; i < pragma.args.length; i++) {
            var argument = pragma.args[i];
            if (!args[i] && !argument.optional) {
                return "fail";
            }
            if (argument.captureSpan) {
                return ts.Debug.fail("Capture spans not yet implemented for non-xml pragmas");
            }
            argMap[argument.name] = args[i];
        }
        return argMap;
    }
    /** @internal */
    function tagNamesAreEquivalent(lhs, rhs) {
        if (lhs.kind !== rhs.kind) {
            return false;
        }
        if (lhs.kind === 75 /* Identifier */) {
            return lhs.escapedText === rhs.escapedText;
        }
        if (lhs.kind === 104 /* ThisKeyword */) {
            return true;
        }
        // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only
        // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression
        // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element
        return lhs.name.escapedText === rhs.name.escapedText &&
            tagNamesAreEquivalent(lhs.expression, rhs.expression);
    }
    ts.tagNamesAreEquivalent = tagNamesAreEquivalent;
})(ts || (ts = {}));
var ts;
(function (ts) {
    /* @internal */
    ts.compileOnSaveCommandLineOption = { name: "compileOnSave", type: "boolean" };
    // NOTE: The order here is important to default lib ordering as entries will have the same
    //       order in the generated program (see `getDefaultLibPriority` in program.ts). This
    //       order also affects overload resolution when a type declared in one lib is
    //       augmented in another lib.
    var libEntries = [
        // JavaScript only
        ["es5", "lib.es5.d.ts"],
        ["es6", "lib.es2015.d.ts"],
        ["es2015", "lib.es2015.d.ts"],
        ["es7", "lib.es2016.d.ts"],
        ["es2016", "lib.es2016.d.ts"],
        ["es2017", "lib.es2017.d.ts"],
        ["es2018", "lib.es2018.d.ts"],
        ["es2019", "lib.es2019.d.ts"],
        ["es2020", "lib.es2020.d.ts"],
        ["esnext", "lib.esnext.d.ts"],
        // Host only
        ["dom", "lib.dom.d.ts"],
        ["dom.iterable", "lib.dom.iterable.d.ts"],
        ["webworker", "lib.webworker.d.ts"],
        ["webworker.importscripts", "lib.webworker.importscripts.d.ts"],
        ["scripthost", "lib.scripthost.d.ts"],
        // ES2015 Or ESNext By-feature options
        ["es2015.core", "lib.es2015.core.d.ts"],
        ["es2015.collection", "lib.es2015.collection.d.ts"],
        ["es2015.generator", "lib.es2015.generator.d.ts"],
        ["es2015.iterable", "lib.es2015.iterable.d.ts"],
        ["es2015.promise", "lib.es2015.promise.d.ts"],
        ["es2015.proxy", "lib.es2015.proxy.d.ts"],
        ["es2015.reflect", "lib.es2015.reflect.d.ts"],
        ["es2015.symbol", "lib.es2015.symbol.d.ts"],
        ["es2015.symbol.wellknown", "lib.es2015.symbol.wellknown.d.ts"],
        ["es2016.array.include", "lib.es2016.array.include.d.ts"],
        ["es2017.object", "lib.es2017.object.d.ts"],
        ["es2017.sharedmemory", "lib.es2017.sharedmemory.d.ts"],
        ["es2017.string", "lib.es2017.string.d.ts"],
        ["es2017.intl", "lib.es2017.intl.d.ts"],
        ["es2017.typedarrays", "lib.es2017.typedarrays.d.ts"],
        ["es2018.asyncgenerator", "lib.es2018.asyncgenerator.d.ts"],
        ["es2018.asynciterable", "lib.es2018.asynciterable.d.ts"],
        ["es2018.intl", "lib.es2018.intl.d.ts"],
        ["es2018.promise", "lib.es2018.promise.d.ts"],
        ["es2018.regexp", "lib.es2018.regexp.d.ts"],
        ["es2019.array", "lib.es2019.array.d.ts"],
        ["es2019.object", "lib.es2019.object.d.ts"],
        ["es2019.string", "lib.es2019.string.d.ts"],
        ["es2019.symbol", "lib.es2019.symbol.d.ts"],
        ["es2020.bigint", "lib.es2020.bigint.d.ts"],
        ["es2020.promise", "lib.es2020.promise.d.ts"],
        ["es2020.string", "lib.es2020.string.d.ts"],
        ["es2020.symbol.wellknown", "lib.es2020.symbol.wellknown.d.ts"],
        ["esnext.array", "lib.es2019.array.d.ts"],
        ["esnext.symbol", "lib.es2019.symbol.d.ts"],
        ["esnext.asynciterable", "lib.es2018.asynciterable.d.ts"],
        ["esnext.intl", "lib.esnext.intl.d.ts"],
        ["esnext.bigint", "lib.es2020.bigint.d.ts"],
        ["esnext.string", "lib.esnext.string.d.ts"],
        ["esnext.promise", "lib.esnext.promise.d.ts"]
    ];
    /**
     * An array of supported "lib" reference file names used to determine the order for inclusion
     * when referenced, as well as for spelling suggestions. This ensures the correct ordering for
     * overload resolution when a type declared in one lib is extended by another.
     */
    /* @internal */
    ts.libs = libEntries.map(function (entry) { return entry[0]; });
    /**
     * A map of lib names to lib files. This map is used both for parsing the "lib" command line
     * option as well as for resolving lib reference directives.
     */
    /* @internal */
    ts.libMap = ts.createMapFromEntries(libEntries);
    // Watch related options
    /* @internal */
    ts.optionsForWatch = [
        {
            name: "watchFile",
            type: ts.createMapFromTemplate({
                fixedpollinginterval: ts.WatchFileKind.FixedPollingInterval,
                prioritypollinginterval: ts.WatchFileKind.PriorityPollingInterval,
                dynamicprioritypolling: ts.WatchFileKind.DynamicPriorityPolling,
                usefsevents: ts.WatchFileKind.UseFsEvents,
                usefseventsonparentdirectory: ts.WatchFileKind.UseFsEventsOnParentDirectory,
            }),
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_strategy_for_watching_file_Colon_FixedPollingInterval_default_PriorityPollingInterval_DynamicPriorityPolling_UseFsEvents_UseFsEventsOnParentDirectory,
        },
        {
            name: "watchDirectory",
            type: ts.createMapFromTemplate({
                usefsevents: ts.WatchDirectoryKind.UseFsEvents,
                fixedpollinginterval: ts.WatchDirectoryKind.FixedPollingInterval,
                dynamicprioritypolling: ts.WatchDirectoryKind.DynamicPriorityPolling,
            }),
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_strategy_for_watching_directory_on_platforms_that_don_t_support_recursive_watching_natively_Colon_UseFsEvents_default_FixedPollingInterval_DynamicPriorityPolling,
        },
        {
            name: "fallbackPolling",
            type: ts.createMapFromTemplate({
                fixedinterval: ts.PollingWatchKind.FixedInterval,
                priorityinterval: ts.PollingWatchKind.PriorityInterval,
                dynamicpriority: ts.PollingWatchKind.DynamicPriority,
            }),
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_strategy_for_creating_a_polling_watch_when_it_fails_to_create_using_file_system_events_Colon_FixedInterval_default_PriorityInterval_DynamicPriority,
        },
        {
            name: "synchronousWatchDirectory",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively,
        },
    ];
    /* @internal */
    ts.commonOptionsWithBuild = [
        {
            name: "help",
            shortName: "h",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Print_this_message,
        },
        {
            name: "help",
            shortName: "?",
            type: "boolean"
        },
        {
            name: "watch",
            shortName: "w",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Watch_input_files,
        },
        {
            name: "preserveWatchOutput",
            type: "boolean",
            showInSimplifiedHelpView: false,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen,
        },
        {
            name: "listFiles",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Print_names_of_files_part_of_the_compilation
        },
        {
            name: "listEmittedFiles",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Print_names_of_generated_files_part_of_the_compilation
        },
        {
            name: "pretty",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
        },
        {
            name: "traceResolution",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Enable_tracing_of_the_name_resolution_process
        },
        {
            name: "diagnostics",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Show_diagnostic_information
        },
        {
            name: "extendedDiagnostics",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Show_verbose_diagnostic_information
        },
        {
            name: "generateCpuProfile",
            type: "string",
            isFilePath: true,
            paramType: ts.Diagnostics.FILE_OR_DIRECTORY,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Generates_a_CPU_profile
        },
        {
            name: "incremental",
            shortName: "i",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Enable_incremental_compilation,
            transpileOptionValue: undefined
        },
        {
            name: "assumeChangesOnlyAffectDirectDependencies",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it
        },
        {
            name: "locale",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us
        },
    ];
    /* @internal */
    ts.optionDeclarations = __spreadArrays(ts.commonOptionsWithBuild, [
        {
            name: "all",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Show_all_compiler_options,
        },
        {
            name: "version",
            shortName: "v",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Print_the_compiler_s_version,
        },
        {
            name: "init",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file,
        },
        {
            name: "project",
            shortName: "p",
            type: "string",
            isFilePath: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            paramType: ts.Diagnostics.FILE_OR_DIRECTORY,
            description: ts.Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json,
        },
        {
            name: "build",
            type: "boolean",
            shortName: "b",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date
        },
        {
            name: "showConfig",
            type: "boolean",
            category: ts.Diagnostics.Command_line_Options,
            isCommandLineOnly: true,
            description: ts.Diagnostics.Print_the_final_configuration_instead_of_building
        },
        {
            name: "listFilesOnly",
            type: "boolean",
            category: ts.Diagnostics.Command_line_Options,
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            isCommandLineOnly: true,
            description: ts.Diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing
        },
        // Basic
        {
            name: "target",
            shortName: "t",
            type: ts.createMapFromTemplate({
                es3: 0 /* ES3 */,
                es5: 1 /* ES5 */,
                es6: 2 /* ES2015 */,
                es2015: 2 /* ES2015 */,
                es2016: 3 /* ES2016 */,
                es2017: 4 /* ES2017 */,
                es2018: 5 /* ES2018 */,
                es2019: 6 /* ES2019 */,
                es2020: 7 /* ES2020 */,
                esnext: 99 /* ESNext */,
            }),
            affectsSourceFile: true,
            affectsModuleResolution: true,
            affectsEmit: true,
            paramType: ts.Diagnostics.VERSION,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_ES2019_ES2020_or_ESNEXT,
        },
        {
            name: "module",
            shortName: "m",
            type: ts.createMapFromTemplate({
                none: ts.ModuleKind.None,
                commonjs: ts.ModuleKind.CommonJS,
                amd: ts.ModuleKind.AMD,
                system: ts.ModuleKind.System,
                umd: ts.ModuleKind.UMD,
                es6: ts.ModuleKind.ES2015,
                es2015: ts.ModuleKind.ES2015,
                es2020: ts.ModuleKind.ES2020,
                esnext: ts.ModuleKind.ESNext
            }),
            affectsModuleResolution: true,
            affectsEmit: true,
            paramType: ts.Diagnostics.KIND,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_es2020_or_ESNext,
        },
        {
            name: "lib",
            type: "list",
            element: {
                name: "lib",
                type: ts.libMap
            },
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_library_files_to_be_included_in_the_compilation,
            transpileOptionValue: undefined
        },
        {
            name: "allowJs",
            type: "boolean",
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Allow_javascript_files_to_be_compiled
        },
        {
            name: "checkJs",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Report_errors_in_js_files
        },
        {
            name: "jsx",
            type: ts.createMapFromTemplate({
                "preserve": 1 /* Preserve */,
                "react-native": 3 /* ReactNative */,
                "react": 2 /* React */
            }),
            affectsSourceFile: true,
            paramType: ts.Diagnostics.KIND,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react,
        },
        {
            name: "declaration",
            shortName: "d",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_corresponding_d_ts_file,
            transpileOptionValue: undefined
        },
        {
            name: "declarationMap",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_a_sourcemap_for_each_corresponding_d_ts_file,
            transpileOptionValue: undefined
        },
        {
            name: "emitDeclarationOnly",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Only_emit_d_ts_declaration_files,
            transpileOptionValue: undefined
        },
        {
            name: "sourceMap",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Generates_corresponding_map_file,
        },
        {
            name: "outFile",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.FILE,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Concatenate_and_emit_output_to_single_file,
            transpileOptionValue: undefined
        },
        {
            name: "outDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Redirect_output_structure_to_the_directory,
        },
        {
            name: "rootDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
        },
        {
            name: "composite",
            type: "boolean",
            affectsEmit: true,
            isTSConfigOnly: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Enable_project_compilation,
            transpileOptionValue: undefined
        },
        {
            name: "tsBuildInfoFile",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.FILE,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Specify_file_to_store_incremental_compilation_information,
            transpileOptionValue: undefined
        },
        {
            name: "removeComments",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Do_not_emit_comments_to_output,
        },
        {
            name: "noEmit",
            type: "boolean",
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Do_not_emit_outputs,
            transpileOptionValue: undefined
        },
        {
            name: "importHelpers",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Import_emit_helpers_from_tslib
        },
        {
            name: "importsNotUsedAsValues",
            type: ts.createMapFromTemplate({
                remove: 0 /* Remove */,
                preserve: 1 /* Preserve */,
                error: 2 /* Error */
            }),
            affectsEmit: true,
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_emit_Slashchecking_behavior_for_imports_that_are_only_used_for_types
        },
        {
            name: "downlevelIteration",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3
        },
        {
            name: "isolatedModules",
            type: "boolean",
            category: ts.Diagnostics.Basic_Options,
            description: ts.Diagnostics.Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule,
            transpileOptionValue: true
        },
        // Strict Type Checks
        {
            name: "strict",
            type: "boolean",
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_all_strict_type_checking_options
        },
        {
            name: "noImplicitAny",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type
        },
        {
            name: "strictNullChecks",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_null_checks
        },
        {
            name: "strictFunctionTypes",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_checking_of_function_types
        },
        {
            name: "strictBindCallApply",
            type: "boolean",
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_bind_call_and_apply_methods_on_functions
        },
        {
            name: "strictPropertyInitialization",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Enable_strict_checking_of_property_initialization_in_classes
        },
        {
            name: "noImplicitThis",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type,
        },
        {
            name: "alwaysStrict",
            type: "boolean",
            affectsSourceFile: true,
            strictFlag: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Strict_Type_Checking_Options,
            description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
        },
        // Additional Checks
        {
            name: "noUnusedLocals",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_on_unused_locals,
        },
        {
            name: "noUnusedParameters",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_on_unused_parameters,
        },
        {
            name: "noImplicitReturns",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value
        },
        {
            name: "noFallthroughCasesInSwitch",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Additional_Checks,
            description: ts.Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement
        },
        // Module Resolution
        {
            name: "moduleResolution",
            type: ts.createMapFromTemplate({
                node: ts.ModuleResolutionKind.NodeJs,
                classic: ts.ModuleResolutionKind.Classic,
            }),
            affectsModuleResolution: true,
            paramType: ts.Diagnostics.STRATEGY,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
        },
        {
            name: "baseUrl",
            type: "string",
            affectsModuleResolution: true,
            isFilePath: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Base_directory_to_resolve_non_absolute_module_names
        },
        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "paths",
            type: "object",
            affectsModuleResolution: true,
            isTSConfigOnly: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl,
            transpileOptionValue: undefined
        },
        {
            // this option can only be specified in tsconfig.json
            // use type = object to copy the value as-is
            name: "rootDirs",
            type: "list",
            isTSConfigOnly: true,
            element: {
                name: "rootDirs",
                type: "string",
                isFilePath: true
            },
            affectsModuleResolution: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime,
            transpileOptionValue: undefined
        },
        {
            name: "typeRoots",
            type: "list",
            element: {
                name: "typeRoots",
                type: "string",
                isFilePath: true
            },
            affectsModuleResolution: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.List_of_folders_to_include_type_definitions_from
        },
        {
            name: "types",
            type: "list",
            element: {
                name: "types",
                type: "string"
            },
            affectsModuleResolution: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Type_declaration_files_to_be_included_in_compilation,
            transpileOptionValue: undefined
        },
        {
            name: "allowSyntheticDefaultImports",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
        },
        {
            name: "esModuleInterop",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            showInSimplifiedHelpView: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports
        },
        {
            name: "preserveSymlinks",
            type: "boolean",
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks,
        },
        {
            name: "allowUmdGlobalAccess",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Module_Resolution_Options,
            description: ts.Diagnostics.Allow_accessing_UMD_globals_from_modules,
        },
        // Source Maps
        {
            name: "sourceRoot",
            type: "string",
            affectsEmit: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
        },
        {
            name: "mapRoot",
            type: "string",
            affectsEmit: true,
            paramType: ts.Diagnostics.LOCATION,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
        },
        {
            name: "inlineSourceMap",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file
        },
        {
            name: "inlineSources",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Source_Map_Options,
            description: ts.Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set
        },
        // Experimental
        {
            name: "experimentalDecorators",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Experimental_Options,
            description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators
        },
        {
            name: "emitDecoratorMetadata",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            category: ts.Diagnostics.Experimental_Options,
            description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
        },
        // Advanced
        {
            name: "jsxFactory",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h
        },
        {
            name: "resolveJsonModule",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Include_modules_imported_with_json_extension
        },
        {
            name: "out",
            type: "string",
            affectsEmit: true,
            isFilePath: false,
            // for correct behaviour, please use outFile
            category: ts.Diagnostics.Advanced_Options,
            paramType: ts.Diagnostics.FILE,
            description: ts.Diagnostics.Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file,
            transpileOptionValue: undefined
        },
        {
            name: "reactNamespace",
            type: "string",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit
        },
        {
            name: "skipDefaultLibCheck",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files
        },
        {
            name: "charset",
            type: "string",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_character_set_of_the_input_files
        },
        {
            name: "emitBOM",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files
        },
        {
            name: "newLine",
            type: ts.createMapFromTemplate({
                crlf: 0 /* CarriageReturnLineFeed */,
                lf: 1 /* LineFeed */
            }),
            affectsEmit: true,
            paramType: ts.Diagnostics.NEWLINE,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
        },
        {
            name: "noErrorTruncation",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_truncate_error_messages
        },
        {
            name: "noLib",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_include_the_default_library_file_lib_d_ts,
            // We are not returning a sourceFile for lib file when asked by the program,
            // so pass --noLib to avoid reporting a file not found error.
            transpileOptionValue: true
        },
        {
            name: "noResolve",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files,
            // We are not doing a full typecheck, we are not resolving the whole context,
            // so pass --noResolve to avoid reporting missing file errors.
            transpileOptionValue: true
        },
        {
            name: "stripInternal",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation,
        },
        {
            name: "disableSizeLimit",
            type: "boolean",
            affectsSourceFile: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_size_limitations_on_JavaScript_projects
        },
        {
            name: "disableSourceOfProjectReferenceRedirect",
            type: "boolean",
            isTSConfigOnly: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_use_of_source_files_instead_of_declaration_files_from_referenced_projects
        },
        {
            name: "disableSolutionSearching",
            type: "boolean",
            isTSConfigOnly: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_solution_searching_for_this_project
        },
        {
            name: "noImplicitUseStrict",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_use_strict_directives_in_module_output
        },
        {
            name: "noEmitHelpers",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output
        },
        {
            name: "noEmitOnError",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported,
            transpileOptionValue: undefined
        },
        {
            name: "preserveConstEnums",
            type: "boolean",
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code
        },
        {
            name: "declarationDir",
            type: "string",
            affectsEmit: true,
            isFilePath: true,
            paramType: ts.Diagnostics.DIRECTORY,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Output_directory_for_generated_declaration_files,
            transpileOptionValue: undefined
        },
        {
            name: "skipLibCheck",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Skip_type_checking_of_declaration_files,
        },
        {
            name: "allowUnusedLabels",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_report_errors_on_unused_labels
        },
        {
            name: "allowUnreachableCode",
            type: "boolean",
            affectsBindDiagnostics: true,
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Do_not_report_errors_on_unreachable_code
        },
        {
            name: "suppressExcessPropertyErrors",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals,
        },
        {
            name: "suppressImplicitAnyIndexErrors",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures,
        },
        {
            name: "forceConsistentCasingInFileNames",
            type: "boolean",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
        },
        {
            name: "maxNodeModuleJsDepth",
            type: "number",
            affectsModuleResolution: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
        },
        {
            name: "noStrictGenericChecks",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
        },
        {
            name: "useDefineForClassFields",
            type: "boolean",
            affectsSemanticDiagnostics: true,
            affectsEmit: true,
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Emit_class_fields_with_Define_instead_of_Set,
        },
        {
            name: "keyofStringsOnly",
            type: "boolean",
            category: ts.Diagnostics.Advanced_Options,
            description: ts.Diagnostics.Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols,
        },
        {
            // A list of plugins to load in the language service
            name: "plugins",
            type: "list",
            isTSConfigOnly: true,
            element: {
                name: "plugin",
                type: "object"
            },
            description: ts.Diagnostics.List_of_language_service_plugins
        },
    ]);
    /* @internal */
    ts.semanticDiagnosticsOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsSemanticDiagnostics; });
    /* @internal */
    ts.affectsEmitOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsEmit; });
    /* @internal */
    ts.moduleResolutionOptionDeclarations = ts.optionDeclarations.filter(function (option) { return !!option.affectsModuleResolution; });
    /* @internal */
    ts.sourceFileAffectingCompilerOptions = ts.optionDeclarations.filter(function (option) {
        return !!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics;
    });
    /* @internal */
    ts.transpileOptionValueCompilerOptions = ts.optionDeclarations.filter(function (option) {
        return ts.hasProperty(option, "transpileOptionValue");
    });
    /* @internal */
    ts.buildOpts = __spreadArrays(ts.commonOptionsWithBuild, [
        {
            name: "verbose",
            shortName: "v",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Enable_verbose_logging,
            type: "boolean"
        },
        {
            name: "dry",
            shortName: "d",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean,
            type: "boolean"
        },
        {
            name: "force",
            shortName: "f",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date,
            type: "boolean"
        },
        {
            name: "clean",
            category: ts.Diagnostics.Command_line_Options,
            description: ts.Diagnostics.Delete_the_outputs_of_all_projects,
            type: "boolean"
        }
    ]);
    /* @internal */
    ts.typeAcquisitionDeclarations = [
        {
            /* @deprecated typingOptions.enableAutoDiscovery
             * Use typeAcquisition.enable instead.
             */
            name: "enableAutoDiscovery",
            type: "boolean",
        },
        {
            name: "enable",
            type: "boolean",
        },
        {
            name: "include",
            type: "list",
            element: {
                name: "include",
                type: "string"
            }
        },
        {
            name: "exclude",
            type: "list",
            element: {
                name: "exclude",
                type: "string"
            }
        }
    ];
    /*@internal*/
    function createOptionNameMap(optionDeclarations) {
        var optionsNameMap = ts.createMap();
        var shortOptionNames = ts.createMap();
        ts.forEach(optionDeclarations, function (option) {
            optionsNameMap.set(option.name.toLowerCase(), option);
            if (option.shortName) {
                shortOptionNames.set(option.shortName, option.name);
            }
        });
        return { optionsNameMap: optionsNameMap, shortOptionNames: shortOptionNames };
    }
    ts.createOptionNameMap = createOptionNameMap;
    var optionsNameMapCache;
    /* @internal */
    function getOptionsNameMap() {
        return optionsNameMapCache || (optionsNameMapCache = createOptionNameMap(ts.optionDeclarations));
    }
    ts.getOptionsNameMap = getOptionsNameMap;
    /* @internal */
    ts.defaultInitCompilerOptions = {
        module: ts.ModuleKind.CommonJS,
        target: 1 /* ES5 */,
        strict: true,
        esModuleInterop: true,
        forceConsistentCasingInFileNames: true,
        skipLibCheck: true
    };
    /* @internal */
    function convertEnableAutoDiscoveryToEnable(typeAcquisition) {
        // Convert deprecated typingOptions.enableAutoDiscovery to typeAcquisition.enable
        if (typeAcquisition && typeAcquisition.enableAutoDiscovery !== undefined && typeAcquisition.enable === undefined) {
            return {
                enable: typeAcquisition.enableAutoDiscovery,
                include: typeAcquisition.include || [],
                exclude: typeAcquisition.exclude || []
            };
        }
        return typeAcquisition;
    }
    ts.convertEnableAutoDiscoveryToEnable = convertEnableAutoDiscoveryToEnable;
    /* @internal */
    function createCompilerDiagnosticForInvalidCustomType(opt) {
        return createDiagnosticForInvalidCustomType(opt, ts.createCompilerDiagnostic);
    }
    ts.createCompilerDiagnosticForInvalidCustomType = createCompilerDiagnosticForInvalidCustomType;
    function createDiagnosticForInvalidCustomType(opt, createDiagnostic) {
        var namesOfType = ts.arrayFrom(opt.type.keys()).map(function (key) { return "'" + key + "'"; }).join(", ");
        return createDiagnostic(ts.Diagnostics.Argument_for_0_option_must_be_Colon_1, "--" + opt.name, namesOfType);
    }
    /* @internal */
    function parseCustomTypeOption(opt, value, errors) {
        return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
    }
    ts.parseCustomTypeOption = parseCustomTypeOption;
    /* @internal */
    function parseListTypeOption(opt, value, errors) {
        if (value === void 0) { value = ""; }
        value = trimString(value);
        if (ts.startsWith(value, "-")) {
            return undefined;
        }
        if (value === "") {
            return [];
        }
        var values = value.split(",");
        switch (opt.element.type) {
            case "number":
                return ts.map(values, parseInt);
            case "string":
                return ts.map(values, function (v) { return v || ""; });
            default:
                return ts.mapDefined(values, function (v) { return parseCustomTypeOption(opt.element, v, errors); });
        }
    }
    ts.parseListTypeOption = parseListTypeOption;
    function getOptionName(option) {
        return option.name;
    }
    function createUnknownOptionError(unknownOption, diagnostics, createDiagnostics, unknownOptionErrorText) {
        var possibleOption = ts.getSpellingSuggestion(unknownOption, diagnostics.optionDeclarations, getOptionName);
        return possibleOption ?
            createDiagnostics(diagnostics.unknownDidYouMeanDiagnostic, unknownOptionErrorText || unknownOption, possibleOption.name) :
            createDiagnostics(diagnostics.unknownOptionDiagnostic, unknownOptionErrorText || unknownOption);
    }
    /*@internal*/
    function parseCommandLineWorker(diagnostics, commandLine, readFile) {
        var options = {};
        var watchOptions;
        var fileNames = [];
        var errors = [];
        parseStrings(commandLine);
        return {
            options: options,
            watchOptions: watchOptions,
            fileNames: fileNames,
            errors: errors
        };
        function parseStrings(args) {
            var i = 0;
            while (i < args.length) {
                var s = args[i];
                i++;
                if (s.charCodeAt(0) === 64 /* at */) {
                    parseResponseFile(s.slice(1));
                }
                else if (s.charCodeAt(0) === 45 /* minus */) {
                    var inputOptionName = s.slice(s.charCodeAt(1) === 45 /* minus */ ? 2 : 1);
                    var opt = getOptionDeclarationFromName(diagnostics.getOptionsNameMap, inputOptionName, /*allowShort*/ true);
                    if (opt) {
                        i = parseOptionValue(args, i, diagnostics, opt, options, errors);
                    }
                    else {
                        var watchOpt = getOptionDeclarationFromName(watchOptionsDidYouMeanDiagnostics.getOptionsNameMap, inputOptionName, /*allowShort*/ true);
                        if (watchOpt) {
                            i = parseOptionValue(args, i, watchOptionsDidYouMeanDiagnostics, watchOpt, watchOptions || (watchOptions = {}), errors);
                        }
                        else {
                            errors.push(createUnknownOptionError(inputOptionName, diagnostics, ts.createCompilerDiagnostic, s));
                        }
                    }
                }
                else {
                    fileNames.push(s);
                }
            }
        }
        function parseResponseFile(fileName) {
            var text = tryReadFile(fileName, readFile || (function (fileName) { return ts.sys.readFile(fileName); }));
            if (!ts.isString(text)) {
                errors.push(text);
                return;
            }
            var args = [];
            var pos = 0;
            while (true) {
                while (pos < text.length && text.charCodeAt(pos) <= 32 /* space */)
                    pos++;
                if (pos >= text.length)
                    break;
                var start = pos;
                if (text.charCodeAt(start) === 34 /* doubleQuote */) {
                    pos++;
                    while (pos < text.length && text.charCodeAt(pos) !== 34 /* doubleQuote */)
                        pos++;
                    if (pos < text.length) {
                        args.push(text.substring(start + 1, pos));
                        pos++;
                    }
                    else {
                        errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unterminated_quoted_string_in_response_file_0, fileName));
                    }
                }
                else {
                    while (text.charCodeAt(pos) > 32 /* space */)
                        pos++;
                    args.push(text.substring(start, pos));
                }
            }
            parseStrings(args);
        }
    }
    ts.parseCommandLineWorker = parseCommandLineWorker;
    function parseOptionValue(args, i, diagnostics, opt, options, errors) {
        if (opt.isTSConfigOnly) {
            var optValue = args[i];
            if (optValue === "null") {
                options[opt.name] = undefined;
                i++;
            }
            else if (opt.type === "boolean") {
                if (optValue === "false") {
                    options[opt.name] = false;
                    i++;
                }
                else {
                    if (optValue === "true")
                        i++;
                    errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line, opt.name));
                }
            }
            else {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line, opt.name));
                if (optValue && !ts.startsWith(optValue, "-"))
                    i++;
            }
        }
        else {
            // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
            if (!args[i] && opt.type !== "boolean") {
                errors.push(ts.createCompilerDiagnostic(diagnostics.optionTypeMismatchDiagnostic, opt.name, getCompilerOptionValueTypeString(opt)));
            }
            if (args[i] !== "null") {
                switch (opt.type) {
                    case "number":
                        options[opt.name] = parseInt(args[i]);
                        i++;
                        break;
                    case "boolean":
                        // boolean flag has optional value true, false, others
                        var optValue = args[i];
                        options[opt.name] = optValue !== "false";
                        // consume next argument as boolean flag value
                        if (optValue === "false" || optValue === "true") {
                            i++;
                        }
                        break;
                    case "string":
                        options[opt.name] = args[i] || "";
                        i++;
                        break;
                    case "list":
                        var result = parseListTypeOption(opt, args[i], errors);
                        options[opt.name] = result || [];
                        if (result) {
                            i++;
                        }
                        break;
                    // If not a primitive, the possible types are specified in what is effectively a map of options.
                    default:
                        options[opt.name] = parseCustomTypeOption(opt, args[i], errors);
                        i++;
                        break;
                }
            }
            else {
                options[opt.name] = undefined;
                i++;
            }
        }
        return i;
    }
    /*@internal*/
    ts.compilerOptionsDidYouMeanDiagnostics = {
        getOptionsNameMap: getOptionsNameMap,
        optionDeclarations: ts.optionDeclarations,
        unknownOptionDiagnostic: ts.Diagnostics.Unknown_compiler_option_0,
        unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_compiler_option_0_Did_you_mean_1,
        optionTypeMismatchDiagnostic: ts.Diagnostics.Compiler_option_0_expects_an_argument
    };
    function parseCommandLine(commandLine, readFile) {
        return parseCommandLineWorker(ts.compilerOptionsDidYouMeanDiagnostics, commandLine, readFile);
    }
    ts.parseCommandLine = parseCommandLine;
    /** @internal */
    function getOptionFromName(optionName, allowShort) {
        return getOptionDeclarationFromName(getOptionsNameMap, optionName, allowShort);
    }
    ts.getOptionFromName = getOptionFromName;
    function getOptionDeclarationFromName(getOptionNameMap, optionName, allowShort) {
        if (allowShort === void 0) { allowShort = false; }
        optionName = optionName.toLowerCase();
        var _a = getOptionNameMap(), optionsNameMap = _a.optionsNameMap, shortOptionNames = _a.shortOptionNames;
        // Try to translate short option names to their full equivalents.
        if (allowShort) {
            var short = shortOptionNames.get(optionName);
            if (short !== undefined) {
                optionName = short;
            }
        }
        return optionsNameMap.get(optionName);
    }
    var buildOptionsNameMapCache;
    function getBuildOptionsNameMap() {
        return buildOptionsNameMapCache || (buildOptionsNameMapCache = createOptionNameMap(ts.buildOpts));
    }
    var buildOptionsDidYouMeanDiagnostics = {
        getOptionsNameMap: getBuildOptionsNameMap,
        optionDeclarations: ts.buildOpts,
        unknownOptionDiagnostic: ts.Diagnostics.Unknown_build_option_0,
        unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_build_option_0_Did_you_mean_1,
        optionTypeMismatchDiagnostic: ts.Diagnostics.Build_option_0_requires_a_value_of_type_1
    };
    /*@internal*/
    function parseBuildCommand(args) {
        var _a = parseCommandLineWorker(buildOptionsDidYouMeanDiagnostics, args), options = _a.options, watchOptions = _a.watchOptions, projects = _a.fileNames, errors = _a.errors;
        var buildOptions = options;
        if (projects.length === 0) {
            // tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ."
            projects.push(".");
        }
        // Nonsensical combinations
        if (buildOptions.clean && buildOptions.force) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"));
        }
        if (buildOptions.clean && buildOptions.verbose) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"));
        }
        if (buildOptions.clean && buildOptions.watch) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"));
        }
        if (buildOptions.watch && buildOptions.dry) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"));
        }
        return { buildOptions: buildOptions, watchOptions: watchOptions, projects: projects, errors: errors };
    }
    ts.parseBuildCommand = parseBuildCommand;
    /* @internal */
    function getDiagnosticText(_message) {
        var _args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            _args[_i - 1] = arguments[_i];
        }
        var diagnostic = ts.createCompilerDiagnostic.apply(undefined, arguments);
        return diagnostic.messageText;
    }
    ts.getDiagnosticText = getDiagnosticText;
    /**
     * Reads the config file, reports errors if any and exits if the config file cannot be found
     */
    function getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host, extendedConfigCache, watchOptionsToExtend, extraFileExtensions) {
        var configFileText = tryReadFile(configFileName, function (fileName) { return host.readFile(fileName); });
        if (!ts.isString(configFileText)) {
            host.onUnRecoverableConfigFileDiagnostic(configFileText);
            return undefined;
        }
        var result = ts.parseJsonText(configFileName, configFileText);
        var cwd = host.getCurrentDirectory();
        result.path = ts.toPath(configFileName, cwd, ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames));
        result.resolvedPath = result.path;
        result.originalFileName = result.fileName;
        return parseJsonSourceFileConfigFileContent(result, host, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), cwd), optionsToExtend, ts.getNormalizedAbsolutePath(configFileName, cwd), 
        /*resolutionStack*/ undefined, extraFileExtensions, extendedConfigCache, watchOptionsToExtend);
    }
    ts.getParsedCommandLineOfConfigFile = getParsedCommandLineOfConfigFile;
    /**
     * Read tsconfig.json file
     * @param fileName The path to the config file
     */
    function readConfigFile(fileName, readFile) {
        var textOrDiagnostic = tryReadFile(fileName, readFile);
        return ts.isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic };
    }
    ts.readConfigFile = readConfigFile;
    /**
     * Parse the text of the tsconfig.json file
     * @param fileName The path to the config file
     * @param jsonText The text of the config file
     */
    function parseConfigFileTextToJson(fileName, jsonText) {
        var jsonSourceFile = ts.parseJsonText(fileName, jsonText);
        return {
            config: convertToObject(jsonSourceFile, jsonSourceFile.parseDiagnostics),
            error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined
        };
    }
    ts.parseConfigFileTextToJson = parseConfigFileTextToJson;
    /**
     * Read tsconfig.json file
     * @param fileName The path to the config file
     */
    function readJsonConfigFile(fileName, readFile) {
        var textOrDiagnostic = tryReadFile(fileName, readFile);
        return ts.isString(textOrDiagnostic) ? ts.parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] };
    }
    ts.readJsonConfigFile = readJsonConfigFile;
    /*@internal*/
    function tryReadFile(fileName, readFile) {
        var text;
        try {
            text = readFile(fileName);
        }
        catch (e) {
            return ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message);
        }
        return text === undefined ? ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0, fileName) : text;
    }
    ts.tryReadFile = tryReadFile;
    function commandLineOptionsToMap(options) {
        return ts.arrayToMap(options, getOptionName);
    }
    var typeAcquisitionDidYouMeanDiagnostics = {
        optionDeclarations: ts.typeAcquisitionDeclarations,
        unknownOptionDiagnostic: ts.Diagnostics.Unknown_type_acquisition_option_0,
        unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1,
    };
    var watchOptionsNameMapCache;
    function getWatchOptionsNameMap() {
        return watchOptionsNameMapCache || (watchOptionsNameMapCache = createOptionNameMap(ts.optionsForWatch));
    }
    var watchOptionsDidYouMeanDiagnostics = {
        getOptionsNameMap: getWatchOptionsNameMap,
        optionDeclarations: ts.optionsForWatch,
        unknownOptionDiagnostic: ts.Diagnostics.Unknown_watch_option_0,
        unknownDidYouMeanDiagnostic: ts.Diagnostics.Unknown_watch_option_0_Did_you_mean_1,
        optionTypeMismatchDiagnostic: ts.Diagnostics.Watch_option_0_requires_a_value_of_type_1
    };
    var commandLineCompilerOptionsMapCache;
    function getCommandLineCompilerOptionsMap() {
        return commandLineCompilerOptionsMapCache || (commandLineCompilerOptionsMapCache = commandLineOptionsToMap(ts.optionDeclarations));
    }
    var commandLineWatchOptionsMapCache;
    function getCommandLineWatchOptionsMap() {
        return commandLineWatchOptionsMapCache || (commandLineWatchOptionsMapCache = commandLineOptionsToMap(ts.optionsForWatch));
    }
    var commandLineTypeAcquisitionMapCache;
    function getCommandLineTypeAcquisitionMap() {
        return commandLineTypeAcquisitionMapCache || (commandLineTypeAcquisitionMapCache = commandLineOptionsToMap(ts.typeAcquisitionDeclarations));
    }
    var _tsconfigRootOptions;
    function getTsconfigRootOptionsMap() {
        if (_tsconfigRootOptions === undefined) {
            _tsconfigRootOptions = {
                name: undefined,
                type: "object",
                elementOptions: commandLineOptionsToMap([
                    {
                        name: "compilerOptions",
                        type: "object",
                        elementOptions: getCommandLineCompilerOptionsMap(),
                        extraKeyDiagnostics: ts.compilerOptionsDidYouMeanDiagnostics,
                    },
                    {
                        name: "watchOptions",
                        type: "object",
                        elementOptions: getCommandLineWatchOptionsMap(),
                        extraKeyDiagnostics: watchOptionsDidYouMeanDiagnostics,
                    },
                    {
                        name: "typingOptions",
                        type: "object",
                        elementOptions: getCommandLineTypeAcquisitionMap(),
                        extraKeyDiagnostics: typeAcquisitionDidYouMeanDiagnostics,
                    },
                    {
                        name: "typeAcquisition",
                        type: "object",
                        elementOptions: getCommandLineTypeAcquisitionMap(),
                        extraKeyDiagnostics: typeAcquisitionDidYouMeanDiagnostics
                    },
                    {
                        name: "extends",
                        type: "string"
                    },
                    {
                        name: "references",
                        type: "list",
                        element: {
                            name: "references",
                            type: "object"
                        }
                    },
                    {
                        name: "files",
                        type: "list",
                        element: {
                            name: "files",
                            type: "string"
                        }
                    },
                    {
                        name: "include",
                        type: "list",
                        element: {
                            name: "include",
                            type: "string"
                        }
                    },
                    {
                        name: "exclude",
                        type: "list",
                        element: {
                            name: "exclude",
                            type: "string"
                        }
                    },
                    ts.compileOnSaveCommandLineOption
                ])
            };
        }
        return _tsconfigRootOptions;
    }
    /**
     * Convert the json syntax tree into the json value
     */
    function convertToObject(sourceFile, errors) {
        return convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
    }
    ts.convertToObject = convertToObject;
    /**
     * Convert the json syntax tree into the json value and report errors
     * This returns the json value (apart from checking errors) only if returnValue provided is true.
     * Otherwise it just checks the errors and returns undefined
     */
    /*@internal*/
    function convertToObjectWorker(sourceFile, errors, returnValue, knownRootOptions, jsonConversionNotifier) {
        if (!sourceFile.statements.length) {
            return returnValue ? {} : undefined;
        }
        return convertPropertyValueToJson(sourceFile.statements[0].expression, knownRootOptions);
        function isRootOptionMap(knownOptions) {
            return knownRootOptions && knownRootOptions.elementOptions === knownOptions;
        }
        function convertObjectLiteralExpressionToJson(node, knownOptions, extraKeyDiagnostics, parentOption) {
            var result = returnValue ? {} : undefined;
            var _loop_3 = function (element) {
                if (element.kind !== 281 /* PropertyAssignment */) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element, ts.Diagnostics.Property_assignment_expected));
                    return "continue";
                }
                if (element.questionToken) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.questionToken, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?"));
                }
                if (!isDoubleQuotedString(element.name)) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, ts.Diagnostics.String_literal_with_double_quotes_expected));
                }
                var textOfKey = ts.isComputedNonLiteralName(element.name) ? undefined : ts.getTextOfPropertyName(element.name);
                var keyText = textOfKey && ts.unescapeLeadingUnderscores(textOfKey);
                var option = keyText && knownOptions ? knownOptions.get(keyText) : undefined;
                if (keyText && extraKeyDiagnostics && !option) {
                    if (knownOptions) {
                        errors.push(createUnknownOptionError(keyText, extraKeyDiagnostics, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, message, arg0, arg1); }));
                    }
                    else {
                        errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnostics.unknownOptionDiagnostic, keyText));
                    }
                }
                var value = convertPropertyValueToJson(element.initializer, option);
                if (typeof keyText !== "undefined") {
                    if (returnValue) {
                        result[keyText] = value;
                    }
                    // Notify key value set, if user asked for it
                    if (jsonConversionNotifier &&
                        // Current callbacks are only on known parent option or if we are setting values in the root
                        (parentOption || isRootOptionMap(knownOptions))) {
                        var isValidOptionValue = isCompilerOptionsValue(option, value);
                        if (parentOption) {
                            if (isValidOptionValue) {
                                // Notify option set in the parent if its a valid option value
                                jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option, value);
                            }
                        }
                        else if (isRootOptionMap(knownOptions)) {
                            if (isValidOptionValue) {
                                // Notify about the valid root key value being set
                                jsonConversionNotifier.onSetValidOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
                            }
                            else if (!option) {
                                // Notify about the unknown root key value being set
                                jsonConversionNotifier.onSetUnknownOptionKeyValueInRoot(keyText, element.name, value, element.initializer);
                            }
                        }
                    }
                }
            };
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var element = _a[_i];
                _loop_3(element);
            }
            return result;
        }
        function convertArrayLiteralExpressionToJson(elements, elementOption) {
            if (!returnValue) {
                return elements.forEach(function (element) { return convertPropertyValueToJson(element, elementOption); });
            }
            // Filter out invalid values
            return ts.filter(elements.map(function (element) { return convertPropertyValueToJson(element, elementOption); }), function (v) { return v !== undefined; });
        }
        function convertPropertyValueToJson(valueExpression, option) {
            switch (valueExpression.kind) {
                case 106 /* TrueKeyword */:
                    reportInvalidOptionValue(option && option.type !== "boolean");
                    return true;
                case 91 /* FalseKeyword */:
                    reportInvalidOptionValue(option && option.type !== "boolean");
                    return false;
                case 100 /* NullKeyword */:
                    reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for
                    return null; // eslint-disable-line no-null/no-null
                case 10 /* StringLiteral */:
                    if (!isDoubleQuotedString(valueExpression)) {
                        errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.String_literal_with_double_quotes_expected));
                    }
                    reportInvalidOptionValue(option && (ts.isString(option.type) && option.type !== "string"));
                    var text = valueExpression.text;
                    if (option && !ts.isString(option.type)) {
                        var customOption = option;
                        // Validate custom option type
                        if (!customOption.type.has(text.toLowerCase())) {
                            errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); }));
                        }
                    }
                    return text;
                case 8 /* NumericLiteral */:
                    reportInvalidOptionValue(option && option.type !== "number");
                    return Number(valueExpression.text);
                case 207 /* PrefixUnaryExpression */:
                    if (valueExpression.operator !== 40 /* MinusToken */ || valueExpression.operand.kind !== 8 /* NumericLiteral */) {
                        break; // not valid JSON syntax
                    }
                    reportInvalidOptionValue(option && option.type !== "number");
                    return -Number(valueExpression.operand.text);
                case 193 /* ObjectLiteralExpression */:
                    reportInvalidOptionValue(option && option.type !== "object");
                    var objectLiteralExpression = valueExpression;
                    // Currently having element option declaration in the tsconfig with type "object"
                    // determines if it needs onSetValidOptionKeyValueInParent callback or not
                    // At moment there are only "compilerOptions", "typeAcquisition" and "typingOptions"
                    // that satifies it and need it to modify options set in them (for normalizing file paths)
                    // vs what we set in the json
                    // If need arises, we can modify this interface and callbacks as needed
                    if (option) {
                        var _a = option, elementOptions = _a.elementOptions, extraKeyDiagnostics = _a.extraKeyDiagnostics, optionName = _a.name;
                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, elementOptions, extraKeyDiagnostics, optionName);
                    }
                    else {
                        return convertObjectLiteralExpressionToJson(objectLiteralExpression, /* knownOptions*/ undefined, 
                        /*extraKeyDiagnosticMessage */ undefined, /*parentOption*/ undefined);
                    }
                case 192 /* ArrayLiteralExpression */:
                    reportInvalidOptionValue(option && option.type !== "list");
                    return convertArrayLiteralExpressionToJson(valueExpression.elements, option && option.element);
            }
            // Not in expected format
            if (option) {
                reportInvalidOptionValue(/*isError*/ true);
            }
            else {
                errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal));
            }
            return undefined;
            function reportInvalidOptionValue(isError) {
                if (isError) {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option.name, getCompilerOptionValueTypeString(option)));
                }
            }
        }
        function isDoubleQuotedString(node) {
            return ts.isStringLiteral(node) && ts.isStringDoubleQuoted(node, sourceFile);
        }
    }
    ts.convertToObjectWorker = convertToObjectWorker;
    function getCompilerOptionValueTypeString(option) {
        return option.type === "list" ?
            "Array" :
            ts.isString(option.type) ? option.type : "string";
    }
    function isCompilerOptionsValue(option, value) {
        if (option) {
            if (isNullOrUndefined(value))
                return true; // All options are undefinable/nullable
            if (option.type === "list") {
                return ts.isArray(value);
            }
            var expectedType = ts.isString(option.type) ? option.type : "string";
            return typeof value === expectedType;
        }
        return false;
    }
    /**
     * Generate an uncommented, complete tsconfig for use with "--showConfig"
     * @param configParseResult options to be generated into tsconfig.json
     * @param configFileName name of the parsed config file - output paths will be generated relative to this
     * @param host provides current directory and case sensitivity services
     */
    /** @internal */
    function convertToTSConfig(configParseResult, configFileName, host) {
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        var files = ts.map(ts.filter(configParseResult.fileNames, (!configParseResult.configFileSpecs || !configParseResult.configFileSpecs.validatedIncludeSpecs) ? function (_) { return true; } : matchesSpecs(configFileName, configParseResult.configFileSpecs.validatedIncludeSpecs, configParseResult.configFileSpecs.validatedExcludeSpecs, host)), function (f) { return ts.getRelativePathFromFile(ts.getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), ts.getNormalizedAbsolutePath(f, host.getCurrentDirectory()), getCanonicalFileName); });
        var optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: ts.getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames });
        var watchOptionMap = configParseResult.watchOptions && serializeWatchOptions(configParseResult.watchOptions);
        var config = __assign(__assign({ compilerOptions: __assign(__assign({}, optionMapToObject(optionMap)), { showConfig: undefined, configFile: undefined, configFilePath: undefined, help: undefined, init: undefined, listFiles: undefined, listEmittedFiles: undefined, project: undefined, build: undefined, version: undefined }), watchOptions: watchOptionMap && optionMapToObject(watchOptionMap), references: ts.map(configParseResult.projectReferences, function (r) { return (__assign(__assign({}, r), { path: r.originalPath ? r.originalPath : "", originalPath: undefined })); }), files: ts.length(files) ? files : undefined }, (configParseResult.configFileSpecs ? {
            include: filterSameAsDefaultInclude(configParseResult.configFileSpecs.validatedIncludeSpecs),
            exclude: configParseResult.configFileSpecs.validatedExcludeSpecs
        } : {})), { compileOnSave: !!configParseResult.compileOnSave ? true : undefined });
        return config;
    }
    ts.convertToTSConfig = convertToTSConfig;
    function optionMapToObject(optionMap) {
        return __assign({}, ts.arrayFrom(optionMap.entries()).reduce(function (prev, cur) {
            var _a;
            return (__assign(__assign({}, prev), (_a = {}, _a[cur[0]] = cur[1], _a)));
        }, {}));
    }
    function filterSameAsDefaultInclude(specs) {
        if (!ts.length(specs))
            return undefined;
        if (ts.length(specs) !== 1)
            return specs;
        if (specs[0] === "**/*")
            return undefined;
        return specs;
    }
    function matchesSpecs(path, includeSpecs, excludeSpecs, host) {
        if (!includeSpecs)
            return function (_) { return true; };
        var patterns = ts.getFileMatcherPatterns(path, excludeSpecs, includeSpecs, host.useCaseSensitiveFileNames, host.getCurrentDirectory());
        var excludeRe = patterns.excludePattern && ts.getRegexFromPattern(patterns.excludePattern, host.useCaseSensitiveFileNames);
        var includeRe = patterns.includeFilePattern && ts.getRegexFromPattern(patterns.includeFilePattern, host.useCaseSensitiveFileNames);
        if (includeRe) {
            if (excludeRe) {
                return function (path) { return !(includeRe.test(path) && !excludeRe.test(path)); };
            }
            return function (path) { return !includeRe.test(path); };
        }
        if (excludeRe) {
            return function (path) { return excludeRe.test(path); };
        }
        return function (_) { return true; };
    }
    function getCustomTypeMapOfCommandLineOption(optionDefinition) {
        if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean" || optionDefinition.type === "object") {
            // this is of a type CommandLineOptionOfPrimitiveType
            return undefined;
        }
        else if (optionDefinition.type === "list") {
            return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
        }
        else {
            return optionDefinition.type;
        }
    }
    function getNameOfCompilerOptionValue(value, customTypeMap) {
        // There is a typeMap associated with this command-line option so use it to map value back to its name
        return ts.forEachEntry(customTypeMap, function (mapValue, key) {
            if (mapValue === value) {
                return key;
            }
        });
    }
    function serializeCompilerOptions(options, pathOptions) {
        return serializeOptionBaseObject(options, getOptionsNameMap(), pathOptions);
    }
    function serializeWatchOptions(options) {
        return serializeOptionBaseObject(options, getWatchOptionsNameMap());
    }
    function serializeOptionBaseObject(options, _a, pathOptions) {
        var optionsNameMap = _a.optionsNameMap;
        var result = ts.createMap();
        var getCanonicalFileName = pathOptions && ts.createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames);
        var _loop_4 = function (name) {
            if (ts.hasProperty(options, name)) {
                // tsconfig only options cannot be specified via command line,
                // so we can assume that only types that can appear here string | number | boolean
                if (optionsNameMap.has(name) && optionsNameMap.get(name).category === ts.Diagnostics.Command_line_Options) {
                    return "continue";
                }
                var value = options[name];
                var optionDefinition = optionsNameMap.get(name.toLowerCase());
                if (optionDefinition) {
                    var customTypeMap_1 = getCustomTypeMapOfCommandLineOption(optionDefinition);
                    if (!customTypeMap_1) {
                        // There is no map associated with this compiler option then use the value as-is
                        // This is the case if the value is expect to be string, number, boolean or list of string
                        if (pathOptions && optionDefinition.isFilePath) {
                            result.set(name, ts.getRelativePathFromFile(pathOptions.configFilePath, ts.getNormalizedAbsolutePath(value, ts.getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName));
                        }
                        else {
                            result.set(name, value);
                        }
                    }
                    else {
                        if (optionDefinition.type === "list") {
                            result.set(name, value.map(function (element) { return getNameOfCompilerOptionValue(element, customTypeMap_1); })); // TODO: GH#18217
                        }
                        else {
                            // There is a typeMap associated with this command-line option so use it to map value back to its name
                            result.set(name, getNameOfCompilerOptionValue(value, customTypeMap_1));
                        }
                    }
                }
            }
        };
        for (var name in options) {
            _loop_4(name);
        }
        return result;
    }
    /**
     * Generate tsconfig configuration when running command line "--init"
     * @param options commandlineOptions to be generated into tsconfig.json
     * @param fileNames array of filenames to be generated into tsconfig.json
     */
    /* @internal */
    function generateTSConfig(options, fileNames, newLine) {
        var compilerOptions = ts.extend(options, ts.defaultInitCompilerOptions);
        var compilerOptionsMap = serializeCompilerOptions(compilerOptions);
        return writeConfigurations();
        function getDefaultValueForOption(option) {
            switch (option.type) {
                case "number":
                    return 1;
                case "boolean":
                    return true;
                case "string":
                    return option.isFilePath ? "./" : "";
                case "list":
                    return [];
                case "object":
                    return {};
                default:
                    var iterResult = option.type.keys().next();
                    if (!iterResult.done)
                        return iterResult.value;
                    return ts.Debug.fail("Expected 'option.type' to have entries.");
            }
        }
        function makePadding(paddingLength) {
            return Array(paddingLength + 1).join(" ");
        }
        function isAllowedOption(_a) {
            var category = _a.category, name = _a.name;
            // Skip options which do not have a category or have category `Command_line_Options`
            // Exclude all possible `Advanced_Options` in tsconfig.json which were NOT defined in command line
            return category !== undefined
                && category !== ts.Diagnostics.Command_line_Options
                && (category !== ts.Diagnostics.Advanced_Options || compilerOptionsMap.has(name));
        }
        function writeConfigurations() {
            // Filter applicable options to place in the file
            var categorizedOptions = ts.createMultiMap();
            for (var _i = 0, optionDeclarations_1 = ts.optionDeclarations; _i < optionDeclarations_1.length; _i++) {
                var option = optionDeclarations_1[_i];
                var category = option.category;
                if (isAllowedOption(option)) {
                    categorizedOptions.add(ts.getLocaleSpecificMessage(category), option);
                }
            }
            // Serialize all options and their descriptions
            var marginLength = 0;
            var seenKnownKeys = 0;
            var entries = [];
            categorizedOptions.forEach(function (options, category) {
                if (entries.length !== 0) {
                    entries.push({ value: "" });
                }
                entries.push({ value: "/* " + category + " */" });
                for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
                    var option = options_1[_i];
                    var optionName = void 0;
                    if (compilerOptionsMap.has(option.name)) {
                        optionName = "\"" + option.name + "\": " + JSON.stringify(compilerOptionsMap.get(option.name)) + ((seenKnownKeys += 1) === compilerOptionsMap.size ? "" : ",");
                    }
                    else {
                        optionName = "// \"" + option.name + "\": " + JSON.stringify(getDefaultValueForOption(option)) + ",";
                    }
                    entries.push({
                        value: optionName,
                        description: "/* " + (option.description && ts.getLocaleSpecificMessage(option.description) || option.name) + " */"
                    });
                    marginLength = Math.max(optionName.length, marginLength);
                }
            });
            // Write the output
            var tab = makePadding(2);
            var result = [];
            result.push("{");
            result.push(tab + "\"compilerOptions\": {");
            result.push("" + tab + tab + "/* " + ts.getLocaleSpecificMessage(ts.Diagnostics.Visit_https_Colon_Slash_Slashaka_ms_Slashtsconfig_json_to_read_more_about_this_file) + " */");
            result.push("");
            // Print out each row, aligning all the descriptions on the same column.
            for (var _a = 0, entries_3 = entries; _a < entries_3.length; _a++) {
                var entry = entries_3[_a];
                var value = entry.value, _b = entry.description, description = _b === void 0 ? "" : _b;
                result.push(value && "" + tab + tab + value + (description && (makePadding(marginLength - value.length + 2) + description)));
            }
            if (fileNames.length) {
                result.push(tab + "},");
                result.push(tab + "\"files\": [");
                for (var i = 0; i < fileNames.length; i++) {
                    result.push("" + tab + tab + JSON.stringify(fileNames[i]) + (i === fileNames.length - 1 ? "" : ","));
                }
                result.push(tab + "]");
            }
            else {
                result.push(tab + "}");
            }
            result.push("}");
            return result.join(newLine) + newLine;
        }
    }
    ts.generateTSConfig = generateTSConfig;
    /* @internal */
    function convertToOptionsWithAbsolutePaths(options, toAbsolutePath) {
        var result = {};
        var optionsNameMap = getOptionsNameMap().optionsNameMap;
        for (var name in options) {
            if (ts.hasProperty(options, name)) {
                result[name] = convertToOptionValueWithAbsolutePaths(optionsNameMap.get(name.toLowerCase()), options[name], toAbsolutePath);
            }
        }
        if (result.configFilePath) {
            result.configFilePath = toAbsolutePath(result.configFilePath);
        }
        return result;
    }
    ts.convertToOptionsWithAbsolutePaths = convertToOptionsWithAbsolutePaths;
    function convertToOptionValueWithAbsolutePaths(option, value, toAbsolutePath) {
        if (option && !isNullOrUndefined(value)) {
            if (option.type === "list") {
                var values = value;
                if (option.element.isFilePath && values.length) {
                    return values.map(toAbsolutePath);
                }
            }
            else if (option.isFilePath) {
                return toAbsolutePath(value);
            }
        }
        return value;
    }
    /**
     * Parse the contents of a config file (tsconfig.json).
     * @param json The contents of the config file to parse
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     */
    function parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache, existingWatchOptions) {
        return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache);
    }
    ts.parseJsonConfigFileContent = parseJsonConfigFileContent;
    /**
     * Parse the contents of a config file (tsconfig.json).
     * @param jsonNode The contents of the config file to parse
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     */
    function parseJsonSourceFileConfigFileContent(sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache, existingWatchOptions) {
        return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache);
    }
    ts.parseJsonSourceFileConfigFileContent = parseJsonSourceFileConfigFileContent;
    /*@internal*/
    function setConfigFileInOptions(options, configFile) {
        if (configFile) {
            Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile });
        }
    }
    ts.setConfigFileInOptions = setConfigFileInOptions;
    function isNullOrUndefined(x) {
        return x === undefined || x === null; // eslint-disable-line no-null/no-null
    }
    function directoryOfCombinedPath(fileName, basePath) {
        // Use the `getNormalizedAbsolutePath` function to avoid canonicalizing the path, as it must remain noncanonical
        // until consistent casing errors are reported
        return ts.getDirectoryPath(ts.getNormalizedAbsolutePath(fileName, basePath));
    }
    /**
     * Parse the contents of a config file from json or json source file (tsconfig.json).
     * @param json The contents of the config file to parse
     * @param sourceFile sourceFile corresponding to the Json
     * @param host Instance of ParseConfigHost used to enumerate files in folder.
     * @param basePath A root directory to resolve relative path entries in the config
     *    file to. e.g. outDir
     * @param resolutionStack Only present for backwards-compatibility. Should be empty.
     */
    function parseJsonConfigFileContentWorker(json, sourceFile, host, basePath, existingOptions, existingWatchOptions, configFileName, resolutionStack, extraFileExtensions, extendedConfigCache) {
        if (existingOptions === void 0) { existingOptions = {}; }
        if (resolutionStack === void 0) { resolutionStack = []; }
        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
        ts.Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
        var errors = [];
        var parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache);
        var raw = parsedConfig.raw;
        var options = ts.extend(existingOptions, parsedConfig.options || {});
        var watchOptions = existingWatchOptions && parsedConfig.watchOptions ?
            ts.extend(existingWatchOptions, parsedConfig.watchOptions) :
            parsedConfig.watchOptions || existingWatchOptions;
        options.configFilePath = configFileName && ts.normalizeSlashes(configFileName);
        setConfigFileInOptions(options, sourceFile);
        var projectReferences;
        var _a = getFileNames(), fileNames = _a.fileNames, wildcardDirectories = _a.wildcardDirectories, spec = _a.spec;
        return {
            options: options,
            watchOptions: watchOptions,
            fileNames: fileNames,
            projectReferences: projectReferences,
            typeAcquisition: parsedConfig.typeAcquisition || getDefaultTypeAcquisition(),
            raw: raw,
            errors: errors,
            wildcardDirectories: wildcardDirectories,
            compileOnSave: !!raw.compileOnSave,
            configFileSpecs: spec
        };
        function getFileNames() {
            var filesSpecs;
            if (ts.hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) {
                if (ts.isArray(raw.files)) {
                    filesSpecs = raw.files;
                    var hasReferences = ts.hasProperty(raw, "references") && !isNullOrUndefined(raw.references);
                    var hasZeroOrNoReferences = !hasReferences || raw.references.length === 0;
                    var hasExtends = ts.hasProperty(raw, "extends");
                    if (filesSpecs.length === 0 && hasZeroOrNoReferences && !hasExtends) {
                        if (sourceFile) {
                            var fileName = configFileName || "tsconfig.json";
                            var diagnosticMessage = ts.Diagnostics.The_files_list_in_config_file_0_is_empty;
                            var nodeValue = ts.firstDefined(ts.getTsConfigPropArray(sourceFile, "files"), function (property) { return property.initializer; });
                            var error = nodeValue
                                ? ts.createDiagnosticForNodeInSourceFile(sourceFile, nodeValue, diagnosticMessage, fileName)
                                : ts.createCompilerDiagnostic(diagnosticMessage, fileName);
                            errors.push(error);
                        }
                        else {
                            createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
                        }
                    }
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array");
                }
            }
            var includeSpecs;
            if (ts.hasProperty(raw, "include") && !isNullOrUndefined(raw.include)) {
                if (ts.isArray(raw.include)) {
                    includeSpecs = raw.include;
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array");
                }
            }
            var excludeSpecs;
            if (ts.hasProperty(raw, "exclude") && !isNullOrUndefined(raw.exclude)) {
                if (ts.isArray(raw.exclude)) {
                    excludeSpecs = raw.exclude;
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array");
                }
            }
            else if (raw.compilerOptions) {
                var outDir = raw.compilerOptions.outDir;
                var declarationDir = raw.compilerOptions.declarationDir;
                if (outDir || declarationDir) {
                    excludeSpecs = [outDir, declarationDir].filter(function (d) { return !!d; });
                }
            }
            if (filesSpecs === undefined && includeSpecs === undefined) {
                includeSpecs = ["**/*"];
            }
            var result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
            if (shouldReportNoInputFiles(result, canJsonReportNoInutFiles(raw), resolutionStack)) {
                errors.push(getErrorForNoInputFiles(result.spec, configFileName));
            }
            if (ts.hasProperty(raw, "references") && !isNullOrUndefined(raw.references)) {
                if (ts.isArray(raw.references)) {
                    for (var _i = 0, _a = raw.references; _i < _a.length; _i++) {
                        var ref = _a[_i];
                        if (typeof ref.path !== "string") {
                            createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "reference.path", "string");
                        }
                        else {
                            (projectReferences || (projectReferences = [])).push({
                                path: ts.getNormalizedAbsolutePath(ref.path, basePath),
                                originalPath: ref.path,
                                prepend: ref.prepend,
                                circular: ref.circular
                            });
                        }
                    }
                }
                else {
                    createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "references", "Array");
                }
            }
            return result;
        }
        function createCompilerDiagnosticOnlyIfJson(message, arg0, arg1) {
            if (!sourceFile) {
                errors.push(ts.createCompilerDiagnostic(message, arg0, arg1));
            }
        }
    }
    function isErrorNoInputFiles(error) {
        return error.code === ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code;
    }
    function getErrorForNoInputFiles(_a, configFileName) {
        var includeSpecs = _a.includeSpecs, excludeSpecs = _a.excludeSpecs;
        return ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName || "tsconfig.json", JSON.stringify(includeSpecs || []), JSON.stringify(excludeSpecs || []));
    }
    function shouldReportNoInputFiles(result, canJsonReportNoInutFiles, resolutionStack) {
        return result.fileNames.length === 0 && canJsonReportNoInutFiles && (!resolutionStack || resolutionStack.length === 0);
    }
    /*@internal*/
    function canJsonReportNoInutFiles(raw) {
        return !ts.hasProperty(raw, "files") && !ts.hasProperty(raw, "references");
    }
    ts.canJsonReportNoInutFiles = canJsonReportNoInutFiles;
    /*@internal*/
    function updateErrorForNoInputFiles(result, configFileName, configFileSpecs, configParseDiagnostics, canJsonReportNoInutFiles) {
        var existingErrors = configParseDiagnostics.length;
        if (shouldReportNoInputFiles(result, canJsonReportNoInutFiles)) {
            configParseDiagnostics.push(getErrorForNoInputFiles(configFileSpecs, configFileName));
        }
        else {
            ts.filterMutate(configParseDiagnostics, function (error) { return !isErrorNoInputFiles(error); });
        }
        return existingErrors !== configParseDiagnostics.length;
    }
    ts.updateErrorForNoInputFiles = updateErrorForNoInputFiles;
    function isSuccessfulParsedTsconfig(value) {
        return !!value.options;
    }
    /**
     * This *just* extracts options/include/exclude/files out of a config file.
     * It does *not* resolve the included files.
     */
    function parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache) {
        basePath = ts.normalizeSlashes(basePath);
        var resolvedPath = ts.getNormalizedAbsolutePath(configFileName || "", basePath);
        if (resolutionStack.indexOf(resolvedPath) >= 0) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, __spreadArrays(resolutionStack, [resolvedPath]).join(" -> ")));
            return { raw: json || convertToObject(sourceFile, errors) };
        }
        var ownConfig = json ?
            parseOwnConfigOfJson(json, host, basePath, configFileName, errors) :
            parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, configFileName, errors);
        if (ownConfig.extendedConfigPath) {
            // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios.
            resolutionStack = resolutionStack.concat([resolvedPath]);
            var extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, resolutionStack, errors, extendedConfigCache);
            if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) {
                var baseRaw_1 = extendedConfig.raw;
                var raw_1 = ownConfig.raw;
                var setPropertyInRawIfNotUndefined = function (propertyName) {
                    var value = raw_1[propertyName] || baseRaw_1[propertyName];
                    if (value) {
                        raw_1[propertyName] = value;
                    }
                };
                setPropertyInRawIfNotUndefined("include");
                setPropertyInRawIfNotUndefined("exclude");
                setPropertyInRawIfNotUndefined("files");
                if (raw_1.compileOnSave === undefined) {
                    raw_1.compileOnSave = baseRaw_1.compileOnSave;
                }
                ownConfig.options = ts.assign({}, extendedConfig.options, ownConfig.options);
                ownConfig.watchOptions = ownConfig.watchOptions && extendedConfig.watchOptions ?
                    ts.assign({}, extendedConfig.watchOptions, ownConfig.watchOptions) :
                    ownConfig.watchOptions || extendedConfig.watchOptions;
                // TODO extend type typeAcquisition
            }
        }
        return ownConfig;
    }
    function parseOwnConfigOfJson(json, host, basePath, configFileName, errors) {
        if (ts.hasProperty(json, "excludes")) {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
        }
        var options = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName);
        // typingOptions has been deprecated and is only supported for backward compatibility purposes.
        // It should be removed in future releases - use typeAcquisition instead.
        var typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName);
        var watchOptions = convertWatchOptionsFromJsonWorker(json.watchOptions, basePath, errors);
        json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
        var extendedConfigPath;
        if (json.extends) {
            if (!ts.isString(json.extends)) {
                errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string"));
            }
            else {
                var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
                extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, errors, ts.createCompilerDiagnostic);
            }
        }
        return { raw: json, options: options, watchOptions: watchOptions, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
    }
    function parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, configFileName, errors) {
        var options = getDefaultCompilerOptions(configFileName);
        var typeAcquisition, typingOptionstypeAcquisition;
        var watchOptions;
        var extendedConfigPath;
        var optionsIterator = {
            onSetValidOptionKeyValueInParent: function (parentOption, option, value) {
                var currentOption;
                switch (parentOption) {
                    case "compilerOptions":
                        currentOption = options;
                        break;
                    case "watchOptions":
                        currentOption = (watchOptions || (watchOptions = {}));
                        break;
                    case "typeAcquisition":
                        currentOption = (typeAcquisition || (typeAcquisition = getDefaultTypeAcquisition(configFileName)));
                        break;
                    case "typingOptions":
                        currentOption = (typingOptionstypeAcquisition || (typingOptionstypeAcquisition = getDefaultTypeAcquisition(configFileName)));
                        break;
                    default:
                        ts.Debug.fail("Unknown option");
                }
                currentOption[option.name] = normalizeOptionValue(option, basePath, value);
            },
            onSetValidOptionKeyValueInRoot: function (key, _keyNode, value, valueNode) {
                switch (key) {
                    case "extends":
                        var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath;
                        extendedConfigPath = getExtendsConfigPath(value, host, newBase, errors, function (message, arg0) {
                            return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0);
                        });
                        return;
                }
            },
            onSetUnknownOptionKeyValueInRoot: function (key, keyNode, _value, _valueNode) {
                if (key === "excludes") {
                    errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, keyNode, ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
                }
            }
        };
        var json = convertToObjectWorker(sourceFile, errors, /*returnValue*/ true, getTsconfigRootOptionsMap(), optionsIterator);
        if (!typeAcquisition) {
            if (typingOptionstypeAcquisition) {
                typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ?
                    {
                        enable: typingOptionstypeAcquisition.enableAutoDiscovery,
                        include: typingOptionstypeAcquisition.include,
                        exclude: typingOptionstypeAcquisition.exclude
                    } :
                    typingOptionstypeAcquisition;
            }
            else {
                typeAcquisition = getDefaultTypeAcquisition(configFileName);
            }
        }
        return { raw: json, options: options, watchOptions: watchOptions, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath };
    }
    function getExtendsConfigPath(extendedConfig, host, basePath, errors, createDiagnostic) {
        extendedConfig = ts.normalizeSlashes(extendedConfig);
        if (ts.isRootedDiskPath(extendedConfig) || ts.startsWith(extendedConfig, "./") || ts.startsWith(extendedConfig, "../")) {
            var extendedConfigPath = ts.getNormalizedAbsolutePath(extendedConfig, basePath);
            if (!host.fileExists(extendedConfigPath) && !ts.endsWith(extendedConfigPath, ".json" /* Json */)) {
                extendedConfigPath = extendedConfigPath + ".json";
                if (!host.fileExists(extendedConfigPath)) {
                    errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig));
                    return undefined;
                }
            }
            return extendedConfigPath;
        }
        // If the path isn't a rooted or relative path, resolve like a module
        var resolved = ts.nodeModuleNameResolver(extendedConfig, ts.combinePaths(basePath, "tsconfig.json"), { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true);
        if (resolved.resolvedModule) {
            return resolved.resolvedModule.resolvedFileName;
        }
        errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig));
        return undefined;
    }
    function getExtendedConfig(sourceFile, extendedConfigPath, host, basePath, resolutionStack, errors, extendedConfigCache) {
        var _a;
        var path = host.useCaseSensitiveFileNames ? extendedConfigPath : ts.toFileNameLowerCase(extendedConfigPath);
        var value;
        var extendedResult;
        var extendedConfig;
        if (extendedConfigCache && (value = extendedConfigCache.get(path))) {
            (extendedResult = value.extendedResult, extendedConfig = value.extendedConfig);
        }
        else {
            extendedResult = readJsonConfigFile(extendedConfigPath, function (path) { return host.readFile(path); });
            if (!extendedResult.parseDiagnostics.length) {
                var extendedDirname = ts.getDirectoryPath(extendedConfigPath);
                extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname, ts.getBaseFileName(extendedConfigPath), resolutionStack, errors, extendedConfigCache);
                if (isSuccessfulParsedTsconfig(extendedConfig)) {
                    // Update the paths to reflect base path
                    var relativeDifference_1 = ts.convertToRelativePath(extendedDirname, basePath, ts.identity);
                    var updatePath_1 = function (path) { return ts.isRootedDiskPath(path) ? path : ts.combinePaths(relativeDifference_1, path); };
                    var mapPropertiesInRawIfNotUndefined = function (propertyName) {
                        if (raw_2[propertyName]) {
                            raw_2[propertyName] = ts.map(raw_2[propertyName], updatePath_1);
                        }
                    };
                    var raw_2 = extendedConfig.raw;
                    mapPropertiesInRawIfNotUndefined("include");
                    mapPropertiesInRawIfNotUndefined("exclude");
                    mapPropertiesInRawIfNotUndefined("files");
                }
            }
            if (extendedConfigCache) {
                extendedConfigCache.set(path, { extendedResult: extendedResult, extendedConfig: extendedConfig });
            }
        }
        if (sourceFile) {
            sourceFile.extendedSourceFiles = [extendedResult.fileName];
            if (extendedResult.extendedSourceFiles) {
                (_a = sourceFile.extendedSourceFiles).push.apply(_a, extendedResult.extendedSourceFiles);
            }
        }
        if (extendedResult.parseDiagnostics.length) {
            errors.push.apply(errors, extendedResult.parseDiagnostics);
            return undefined;
        }
        return extendedConfig;
    }
    function convertCompileOnSaveOptionFromJson(jsonOption, basePath, errors) {
        if (!ts.hasProperty(jsonOption, ts.compileOnSaveCommandLineOption.name)) {
            return false;
        }
        var result = convertJsonOption(ts.compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors);
        return typeof result === "boolean" && result;
    }
    function convertCompilerOptionsFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertCompilerOptionsFromJson = convertCompilerOptionsFromJson;
    function convertTypeAcquisitionFromJson(jsonOptions, basePath, configFileName) {
        var errors = [];
        var options = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName);
        return { options: options, errors: errors };
    }
    ts.convertTypeAcquisitionFromJson = convertTypeAcquisitionFromJson;
    function getDefaultCompilerOptions(configFileName) {
        var options = configFileName && ts.getBaseFileName(configFileName) === "jsconfig.json"
            ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true, noEmit: true }
            : {};
        return options;
    }
    function convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = getDefaultCompilerOptions(configFileName);
        convertOptionsFromJson(getCommandLineCompilerOptionsMap(), jsonOptions, basePath, options, ts.compilerOptionsDidYouMeanDiagnostics, errors);
        if (configFileName) {
            options.configFilePath = ts.normalizeSlashes(configFileName);
        }
        return options;
    }
    function getDefaultTypeAcquisition(configFileName) {
        return { enable: !!configFileName && ts.getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
    }
    function convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName) {
        var options = getDefaultTypeAcquisition(configFileName);
        var typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions);
        convertOptionsFromJson(getCommandLineTypeAcquisitionMap(), typeAcquisition, basePath, options, typeAcquisitionDidYouMeanDiagnostics, errors);
        return options;
    }
    function convertWatchOptionsFromJsonWorker(jsonOptions, basePath, errors) {
        return convertOptionsFromJson(getCommandLineWatchOptionsMap(), jsonOptions, basePath, /*defaultOptions*/ undefined, watchOptionsDidYouMeanDiagnostics, errors);
    }
    function convertOptionsFromJson(optionsNameMap, jsonOptions, basePath, defaultOptions, diagnostics, errors) {
        if (!jsonOptions) {
            return;
        }
        for (var id in jsonOptions) {
            var opt = optionsNameMap.get(id);
            if (opt) {
                (defaultOptions || (defaultOptions = {}))[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
            }
            else {
                errors.push(createUnknownOptionError(id, diagnostics, ts.createCompilerDiagnostic));
            }
        }
        return defaultOptions;
    }
    function convertJsonOption(opt, value, basePath, errors) {
        if (isCompilerOptionsValue(opt, value)) {
            var optType = opt.type;
            if (optType === "list" && ts.isArray(value)) {
                return convertJsonOptionOfListType(opt, value, basePath, errors);
            }
            else if (!ts.isString(optType)) {
                return convertJsonOptionOfCustomType(opt, value, errors);
            }
            return normalizeNonListOptionValue(opt, basePath, value);
        }
        else {
            errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, getCompilerOptionValueTypeString(opt)));
        }
    }
    function normalizeOptionValue(option, basePath, value) {
        if (isNullOrUndefined(value))
            return undefined;
        if (option.type === "list") {
            var listOption_1 = option;
            if (listOption_1.element.isFilePath || !ts.isString(listOption_1.element.type)) {
                return ts.filter(ts.map(value, function (v) { return normalizeOptionValue(listOption_1.element, basePath, v); }), function (v) { return !!v; });
            }
            return value;
        }
        else if (!ts.isString(option.type)) {
            return option.type.get(ts.isString(value) ? value.toLowerCase() : value);
        }
        return normalizeNonListOptionValue(option, basePath, value);
    }
    function normalizeNonListOptionValue(option, basePath, value) {
        if (option.isFilePath) {
            value = ts.getNormalizedAbsolutePath(value, basePath);
            if (value === "") {
                value = ".";
            }
        }
        return value;
    }
    function convertJsonOptionOfCustomType(opt, value, errors) {
        if (isNullOrUndefined(value))
            return undefined;
        var key = value.toLowerCase();
        var val = opt.type.get(key);
        if (val !== undefined) {
            return val;
        }
        else {
            errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
        }
    }
    function convertJsonOptionOfListType(option, values, basePath, errors) {
        return ts.filter(ts.map(values, function (v) { return convertJsonOption(option.element, v, basePath, errors); }), function (v) { return !!v; });
    }
    function trimString(s) {
        return typeof s.trim === "function" ? s.trim() : s.replace(/^[\s]+|[\s]+$/g, "");
    }
    /**
     * Tests for a path that ends in a recursive directory wildcard.
     * Matches **, \**, **\, and \**\, but not a**b.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*        # matches the recursive directory wildcard "**".
     *  \/?$        # matches an optional trailing directory separator at the end of the string.
     */
    var invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
    /**
     * Tests for a path where .. appears after a recursive directory wildcard.
     * Matches **\..\*, **\a\..\*, and **\.., but not ..\**\*
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  (^|\/)      # matches either the beginning of the string or a directory separator.
     *  \*\*\/      # matches a recursive directory wildcard "**" followed by a directory separator.
     *  (.*\/)?     # optionally matches any number of characters followed by a directory separator.
     *  \.\.        # matches a parent directory path component ".."
     *  ($|\/)      # matches either the end of the string or a directory separator.
     */
    var invalidDotDotAfterRecursiveWildcardPattern = /(^|\/)\*\*\/(.*\/)?\.\.($|\/)/;
    /**
     * Tests for a path containing a wildcard character in a directory component of the path.
     * Matches \*\, \?\, and \a*b\, but not \a\ or \a\*.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  \/          # matches a directory separator.
     *  [^/]*?      # matches any number of characters excluding directory separators (non-greedy).
     *  [*?]        # matches either a wildcard character (* or ?)
     *  [^/]*       # matches any number of characters excluding directory separators (greedy).
     *  \/          # matches a directory separator.
     */
    var watchRecursivePattern = /\/[^/]*?[*?][^/]*\//;
    /**
     * Matches the portion of a wildcard path that does not contain wildcards.
     * Matches \a of \a\*, or \a\b\c of \a\b\c\?\d.
     *
     * NOTE: used \ in place of / above to avoid issues with multiline comments.
     *
     * Breakdown:
     *  ^                   # matches the beginning of the string
     *  [^*?]*              # matches any number of non-wildcard characters
     *  (?=\/[^/]*[*?])     # lookahead that matches a directory separator followed by
     *                      # a path component that contains at least one wildcard character (* or ?).
     */
    var wildcardDirectoryPattern = /^[^*?]*(?=\/[^/]*[*?])/;
    /**
     * Expands an array of file specifications.
     *
     * @param filesSpecs The literal file names to include.
     * @param includeSpecs The wildcard file specifications to include.
     * @param excludeSpecs The wildcard file specifications to exclude.
     * @param basePath The base path for any relative file specifications.
     * @param options Compiler options.
     * @param host The host used to resolve files and directories.
     * @param errors An array for diagnostic reporting.
     */
    function matchFileNames(filesSpecs, includeSpecs, excludeSpecs, basePath, options, host, errors, extraFileExtensions, jsonSourceFile) {
        basePath = ts.normalizePath(basePath);
        var validatedIncludeSpecs, validatedExcludeSpecs;
        // The exclude spec list is converted into a regular expression, which allows us to quickly
        // test whether a file or directory should be excluded before recursively traversing the
        // file system.
        if (includeSpecs) {
            validatedIncludeSpecs = validateSpecs(includeSpecs, errors, /*allowTrailingRecursion*/ false, jsonSourceFile, "include");
        }
        if (excludeSpecs) {
            validatedExcludeSpecs = validateSpecs(excludeSpecs, errors, /*allowTrailingRecursion*/ true, jsonSourceFile, "exclude");
        }
        // Wildcard directories (provided as part of a wildcard path) are stored in a
        // file map that marks whether it was a regular wildcard match (with a `*` or `?` token),
        // or a recursive directory. This information is used by filesystem watchers to monitor for
        // new entries in these paths.
        var wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames);
        var spec = { filesSpecs: filesSpecs, includeSpecs: includeSpecs, excludeSpecs: excludeSpecs, validatedIncludeSpecs: validatedIncludeSpecs, validatedExcludeSpecs: validatedExcludeSpecs, wildcardDirectories: wildcardDirectories };
        return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions);
    }
    /**
     * Gets the file names from the provided config file specs that contain, files, include, exclude and
     * other properties needed to resolve the file names
     * @param spec The config file specs extracted with file names to include, wildcards to include/exclude and other details
     * @param basePath The base path for any relative file specifications.
     * @param options Compiler options.
     * @param host The host used to resolve files and directories.
     * @param extraFileExtensions optionaly file extra file extension information from host
     */
    /* @internal */
    function getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions) {
        if (extraFileExtensions === void 0) { extraFileExtensions = []; }
        basePath = ts.normalizePath(basePath);
        var keyMapper = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames);
        // Literal file names (provided via the "files" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map later when when including
        // wildcard paths.
        var literalFileMap = ts.createMap();
        // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map to store paths matched
        // via wildcard, and to handle extension priority.
        var wildcardFileMap = ts.createMap();
        // Wildcard paths of json files (provided via the "includes" array in tsconfig.json) are stored in a
        // file map with a possibly case insensitive key. We use this map to store paths matched
        // via wildcard of *.json kind
        var wildCardJsonFileMap = ts.createMap();
        var filesSpecs = spec.filesSpecs, validatedIncludeSpecs = spec.validatedIncludeSpecs, validatedExcludeSpecs = spec.validatedExcludeSpecs, wildcardDirectories = spec.wildcardDirectories;
        // Rather than requery this for each file and filespec, we query the supported extensions
        // once and store it on the expansion context.
        var supportedExtensions = ts.getSupportedExtensions(options, extraFileExtensions);
        var supportedExtensionsWithJsonIfResolveJsonModule = ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
        // Literal files are always included verbatim. An "include" or "exclude" specification cannot
        // remove a literal file.
        if (filesSpecs) {
            for (var _i = 0, filesSpecs_1 = filesSpecs; _i < filesSpecs_1.length; _i++) {
                var fileName = filesSpecs_1[_i];
                var file = ts.getNormalizedAbsolutePath(fileName, basePath);
                literalFileMap.set(keyMapper(file), file);
            }
        }
        var jsonOnlyIncludeRegexes;
        if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) {
            var _loop_5 = function (file) {
                if (ts.fileExtensionIs(file, ".json" /* Json */)) {
                    // Valid only if *.json specified
                    if (!jsonOnlyIncludeRegexes) {
                        var includes = validatedIncludeSpecs.filter(function (s) { return ts.endsWith(s, ".json" /* Json */); });
                        var includeFilePatterns = ts.map(ts.getRegularExpressionsForWildcards(includes, basePath, "files"), function (pattern) { return "^" + pattern + "$"; });
                        jsonOnlyIncludeRegexes = includeFilePatterns ? includeFilePatterns.map(function (pattern) { return ts.getRegexFromPattern(pattern, host.useCaseSensitiveFileNames); }) : ts.emptyArray;
                    }
                    var includeIndex = ts.findIndex(jsonOnlyIncludeRegexes, function (re) { return re.test(file); });
                    if (includeIndex !== -1) {
                        var key_1 = keyMapper(file);
                        if (!literalFileMap.has(key_1) && !wildCardJsonFileMap.has(key_1)) {
                            wildCardJsonFileMap.set(key_1, file);
                        }
                    }
                    return "continue";
                }
                // If we have already included a literal or wildcard path with a
                // higher priority extension, we should skip this file.
                //
                // This handles cases where we may encounter both <file>.ts and
                // <file>.d.ts (or <file>.js if "allowJs" is enabled) in the same
                // directory when they are compilation outputs.
                if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) {
                    return "continue";
                }
                // We may have included a wildcard path with a lower priority
                // extension due to the user-defined order of entries in the
                // "include" array. If there is a lower priority extension in the
                // same directory, we should remove it.
                removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper);
                var key = keyMapper(file);
                if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) {
                    wildcardFileMap.set(key, file);
                }
            };
            for (var _a = 0, _b = host.readDirectory(basePath, supportedExtensionsWithJsonIfResolveJsonModule, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined); _a < _b.length; _a++) {
                var file = _b[_a];
                _loop_5(file);
            }
        }
        var literalFiles = ts.arrayFrom(literalFileMap.values());
        var wildcardFiles = ts.arrayFrom(wildcardFileMap.values());
        return {
            fileNames: literalFiles.concat(wildcardFiles, ts.arrayFrom(wildCardJsonFileMap.values())),
            wildcardDirectories: wildcardDirectories,
            spec: spec
        };
    }
    ts.getFileNamesFromConfigSpecs = getFileNamesFromConfigSpecs;
    function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) {
        return specs.filter(function (spec) {
            var diag = specToDiagnostic(spec, allowTrailingRecursion);
            if (diag !== undefined) {
                errors.push(createDiagnostic(diag, spec));
            }
            return diag === undefined;
        });
        function createDiagnostic(message, spec) {
            var element = ts.getTsConfigPropArrayElementValue(jsonSourceFile, specKey, spec);
            return element ?
                ts.createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec) :
                ts.createCompilerDiagnostic(message, spec);
        }
    }
    function specToDiagnostic(spec, allowTrailingRecursion) {
        if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
        }
        else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
            return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
        }
    }
    /**
     * Gets directories in a set of include patterns that should be watched for changes.
     */
    function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) {
        // We watch a directory recursively if it contains a wildcard anywhere in a directory segment
        // of the pattern:
        //
        //  /a/b/**/d   - Watch /a/b recursively to catch changes to any d in any subfolder recursively
        //  /a/b/*/d    - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added
        //  /a/b        - Watch /a/b recursively to catch changes to anything in any recursive subfoler
        //
        // We watch a directory without recursion if it contains a wildcard in the file segment of
        // the pattern:
        //
        //  /a/b/*      - Watch /a/b directly to catch any new file
        //  /a/b/a?z    - Watch /a/b directly to catch any new file matching a?z
        var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude");
        var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i");
        var wildcardDirectories = {};
        if (include !== undefined) {
            var recursiveKeys = [];
            for (var _i = 0, include_1 = include; _i < include_1.length; _i++) {
                var file = include_1[_i];
                var spec = ts.normalizePath(ts.combinePaths(path, file));
                if (excludeRegex && excludeRegex.test(spec)) {
                    continue;
                }
                var match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames);
                if (match) {
                    var key = match.key, flags = match.flags;
                    var existingFlags = wildcardDirectories[key];
                    if (existingFlags === undefined || existingFlags < flags) {
                        wildcardDirectories[key] = flags;
                        if (flags === 1 /* Recursive */) {
                            recursiveKeys.push(key);
                        }
                    }
                }
            }
            // Remove any subpaths under an existing recursively watched directory.
            for (var key in wildcardDirectories) {
                if (ts.hasProperty(wildcardDirectories, key)) {
                    for (var _a = 0, recursiveKeys_1 = recursiveKeys; _a < recursiveKeys_1.length; _a++) {
                        var recursiveKey = recursiveKeys_1[_a];
                        if (key !== recursiveKey && ts.containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) {
                            delete wildcardDirectories[key];
                        }
                    }
                }
            }
        }
        return wildcardDirectories;
    }
    function getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames) {
        var match = wildcardDirectoryPattern.exec(spec);
        if (match) {
            return {
                key: useCaseSensitiveFileNames ? match[0] : ts.toFileNameLowerCase(match[0]),
                flags: watchRecursivePattern.test(spec) ? 1 /* Recursive */ : 0 /* None */
            };
        }
        if (ts.isImplicitGlob(spec)) {
            return { key: spec, flags: 1 /* Recursive */ };
        }
        return undefined;
    }
    /**
     * Determines whether a literal or wildcard file has already been included that has a higher
     * extension priority.
     *
     * @param file The path to the file.
     * @param extensionPriority The priority of the extension.
     * @param context The expansion context.
     */
    function hasFileWithHigherPriorityExtension(file, literalFiles, wildcardFiles, extensions, keyMapper) {
        var extensionPriority = ts.getExtensionPriority(file, extensions);
        var adjustedExtensionPriority = ts.adjustExtensionPriority(extensionPriority, extensions);
        for (var i = 0 /* Highest */; i < adjustedExtensionPriority; i++) {
            var higherPriorityExtension = extensions[i];
            var higherPriorityPath = keyMapper(ts.changeExtension(file, higherPriorityExtension));
            if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) {
                return true;
            }
        }
        return false;
    }
    /**
     * Removes files included via wildcard expansion with a lower extension priority that have
     * already been included.
     *
     * @param file The path to the file.
     * @param extensionPriority The priority of the extension.
     * @param context The expansion context.
     */
    function removeWildcardFilesWithLowerPriorityExtension(file, wildcardFiles, extensions, keyMapper) {
        var extensionPriority = ts.getExtensionPriority(file, extensions);
        var nextExtensionPriority = ts.getNextLowestExtensionPriority(extensionPriority, extensions);
        for (var i = nextExtensionPriority; i < extensions.length; i++) {
            var lowerPriorityExtension = extensions[i];
            var lowerPriorityPath = keyMapper(ts.changeExtension(file, lowerPriorityExtension));
            wildcardFiles.delete(lowerPriorityPath);
        }
    }
    /**
     * Produces a cleaned version of compiler options with personally identifying info (aka, paths) removed.
     * Also converts enum values back to strings.
     */
    /* @internal */
    function convertCompilerOptionsForTelemetry(opts) {
        var out = {};
        for (var key in opts) {
            if (opts.hasOwnProperty(key)) {
                var type = getOptionFromName(key);
                if (type !== undefined) { // Ignore unknown options
                    out[key] = getOptionValueWithEmptyStrings(opts[key], type);
                }
            }
        }
        return out;
    }
    ts.convertCompilerOptionsForTelemetry = convertCompilerOptionsForTelemetry;
    function getOptionValueWithEmptyStrings(value, option) {
        switch (option.type) {
            case "object": // "paths". Can't get any useful information from the value since we blank out strings, so just return "".
                return "";
            case "string": // Could be any arbitrary string -- use empty string instead.
                return "";
            case "number": // Allow numbers, but be sure to check it's actually a number.
                return typeof value === "number" ? value : "";
            case "boolean":
                return typeof value === "boolean" ? value : "";
            case "list":
                var elementType_1 = option.element;
                return ts.isArray(value) ? value.map(function (v) { return getOptionValueWithEmptyStrings(v, elementType_1); }) : "";
            default:
                return ts.forEachEntry(option.type, function (optionEnumValue, optionStringValue) {
                    if (optionEnumValue === value) {
                        return optionStringValue;
                    }
                }); // TODO: GH#18217
        }
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    function trace(host) {
        host.trace(ts.formatMessage.apply(undefined, arguments));
    }
    ts.trace = trace;
    /* @internal */
    function isTraceEnabled(compilerOptions, host) {
        return !!compilerOptions.traceResolution && host.trace !== undefined;
    }
    ts.isTraceEnabled = isTraceEnabled;
    function withPackageId(packageInfo, r) {
        var packageId;
        if (r && packageInfo) {
            var packageJsonContent = packageInfo.packageJsonContent;
            if (typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string") {
                packageId = {
                    name: packageJsonContent.name,
                    subModuleName: r.path.slice(packageInfo.packageDirectory.length + ts.directorySeparator.length),
                    version: packageJsonContent.version
                };
            }
        }
        return r && { path: r.path, extension: r.ext, packageId: packageId };
    }
    function noPackageId(r) {
        return withPackageId(/*packageInfo*/ undefined, r);
    }
    function removeIgnoredPackageId(r) {
        if (r) {
            ts.Debug.assert(r.packageId === undefined);
            return { path: r.path, ext: r.extension };
        }
    }
    /**
     * Kinds of file that we are currently looking for.
     * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript.
     */
    var Extensions;
    (function (Extensions) {
        Extensions[Extensions["TypeScript"] = 0] = "TypeScript";
        Extensions[Extensions["JavaScript"] = 1] = "JavaScript";
        Extensions[Extensions["Json"] = 2] = "Json";
        Extensions[Extensions["TSConfig"] = 3] = "TSConfig";
        Extensions[Extensions["DtsOnly"] = 4] = "DtsOnly"; /** Only '.d.ts' */
    })(Extensions || (Extensions = {}));
    /** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
    function resolvedTypeScriptOnly(resolved) {
        if (!resolved) {
            return undefined;
        }
        ts.Debug.assert(ts.extensionIsTS(resolved.extension));
        return { fileName: resolved.path, packageId: resolved.packageId };
    }
    function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations, resultFromCache) {
        var _a;
        if (resultFromCache) {
            (_a = resultFromCache.failedLookupLocations).push.apply(_a, failedLookupLocations);
            return resultFromCache;
        }
        return {
            resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId },
            failedLookupLocations: failedLookupLocations
        };
    }
    function readPackageJsonField(jsonContent, fieldName, typeOfTag, state) {
        if (!ts.hasProperty(jsonContent, fieldName)) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_does_not_have_a_0_field, fieldName);
            }
            return;
        }
        var value = jsonContent[fieldName];
        if (typeof value !== typeOfTag || value === null) { // eslint-disable-line no-null/no-null
            if (state.traceEnabled) {
                // eslint-disable-next-line no-null/no-null
                trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value);
            }
            return;
        }
        return value;
    }
    function readPackageJsonPathField(jsonContent, fieldName, baseDirectory, state) {
        var fileName = readPackageJsonField(jsonContent, fieldName, "string", state);
        if (fileName === undefined) {
            return;
        }
        if (!fileName) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_had_a_falsy_0_field, fieldName);
            }
            return;
        }
        var path = ts.normalizePath(ts.combinePaths(baseDirectory, fileName));
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path);
        }
        return path;
    }
    function readPackageJsonTypesFields(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "typings", baseDirectory, state)
            || readPackageJsonPathField(jsonContent, "types", baseDirectory, state);
    }
    function readPackageJsonTSConfigField(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "tsconfig", baseDirectory, state);
    }
    function readPackageJsonMainField(jsonContent, baseDirectory, state) {
        return readPackageJsonPathField(jsonContent, "main", baseDirectory, state);
    }
    function readPackageJsonTypesVersionsField(jsonContent, state) {
        var typesVersions = readPackageJsonField(jsonContent, "typesVersions", "object", state);
        if (typesVersions === undefined)
            return;
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_field_with_version_specific_path_mappings);
        }
        return typesVersions;
    }
    function readPackageJsonTypesVersionPaths(jsonContent, state) {
        var typesVersions = readPackageJsonTypesVersionsField(jsonContent, state);
        if (typesVersions === undefined)
            return;
        if (state.traceEnabled) {
            for (var key in typesVersions) {
                if (ts.hasProperty(typesVersions, key) && !ts.VersionRange.tryParse(key)) {
                    trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_is_not_a_valid_semver_range, key);
                }
            }
        }
        var result = getPackageJsonTypesVersionsPaths(typesVersions);
        if (!result) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_does_not_have_a_typesVersions_entry_that_matches_version_0, ts.versionMajorMinor);
            }
            return;
        }
        var bestVersionKey = result.version, bestVersionPaths = result.paths;
        if (typeof bestVersionPaths !== "object") {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, "typesVersions['" + bestVersionKey + "']", "object", typeof bestVersionPaths);
            }
            return;
        }
        return result;
    }
    var typeScriptVersion;
    /* @internal */
    function getPackageJsonTypesVersionsPaths(typesVersions) {
        if (!typeScriptVersion)
            typeScriptVersion = new ts.Version(ts.version);
        for (var key in typesVersions) {
            if (!ts.hasProperty(typesVersions, key))
                continue;
            var keyRange = ts.VersionRange.tryParse(key);
            if (keyRange === undefined) {
                continue;
            }
            // return the first entry whose range matches the current compiler version.
            if (keyRange.test(typeScriptVersion)) {
                return { version: key, paths: typesVersions[key] };
            }
        }
    }
    ts.getPackageJsonTypesVersionsPaths = getPackageJsonTypesVersionsPaths;
    function getEffectiveTypeRoots(options, host) {
        if (options.typeRoots) {
            return options.typeRoots;
        }
        var currentDirectory;
        if (options.configFilePath) {
            currentDirectory = ts.getDirectoryPath(options.configFilePath);
        }
        else if (host.getCurrentDirectory) {
            currentDirectory = host.getCurrentDirectory();
        }
        if (currentDirectory !== undefined) {
            return getDefaultTypeRoots(currentDirectory, host);
        }
    }
    ts.getEffectiveTypeRoots = getEffectiveTypeRoots;
    /**
     * Returns the path to every node_modules/@types directory from some ancestor directory.
     * Returns undefined if there are none.
     */
    function getDefaultTypeRoots(currentDirectory, host) {
        if (!host.directoryExists) {
            return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)];
            // And if it doesn't exist, tough.
        }
        var typeRoots;
        ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) {
            var atTypes = ts.combinePaths(directory, nodeModulesAtTypes);
            if (host.directoryExists(atTypes)) {
                (typeRoots || (typeRoots = [])).push(atTypes);
            }
            return undefined;
        });
        return typeRoots;
    }
    var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types");
    /**
     * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
     * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
     * is assumed to be the same as root directory of the project.
     */
    function resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host, redirectedReference) {
        var traceEnabled = isTraceEnabled(options, host);
        if (redirectedReference) {
            options = redirectedReference.commandLine.options;
        }
        var failedLookupLocations = [];
        var moduleResolutionState = { compilerOptions: options, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var typeRoots = getEffectiveTypeRoots(options, host);
        if (traceEnabled) {
            if (containingFile === undefined) {
                if (typeRoots === undefined) {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName);
                }
                else {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, typeRoots);
                }
            }
            else {
                if (typeRoots === undefined) {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile);
                }
                else {
                    trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots);
                }
            }
            if (redirectedReference) {
                trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
            }
        }
        var resolved = primaryLookup();
        var primary = true;
        if (!resolved) {
            resolved = secondaryLookup();
            primary = false;
        }
        var resolvedTypeReferenceDirective;
        if (resolved) {
            var fileName = resolved.fileName, packageId = resolved.packageId;
            var resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
            if (traceEnabled) {
                if (packageId) {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_with_Package_ID_2_primary_Colon_3, typeReferenceDirectiveName, resolvedFileName, ts.packageIdToString(packageId), primary);
                }
                else {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
                }
            }
            resolvedTypeReferenceDirective = { primary: primary, resolvedFileName: resolvedFileName, packageId: packageId, isExternalLibraryImport: pathContainsNodeModules(fileName) };
        }
        return { resolvedTypeReferenceDirective: resolvedTypeReferenceDirective, failedLookupLocations: failedLookupLocations };
        function primaryLookup() {
            // Check primary library paths
            if (typeRoots && typeRoots.length) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
                }
                return ts.firstDefined(typeRoots, function (typeRoot) {
                    var candidate = ts.combinePaths(typeRoot, typeReferenceDirectiveName);
                    var candidateDirectory = ts.getDirectoryPath(candidate);
                    var directoryExists = ts.directoryProbablyExists(candidateDirectory, host);
                    if (!directoryExists && traceEnabled) {
                        trace(host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory);
                    }
                    return resolvedTypeScriptOnly(loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, !directoryExists, moduleResolutionState));
                });
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths);
                }
            }
        }
        function secondaryLookup() {
            var initialLocationForSecondaryLookup = containingFile && ts.getDirectoryPath(containingFile);
            if (initialLocationForSecondaryLookup !== undefined) {
                // check secondary locations
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
                }
                var result = void 0;
                if (!ts.isExternalModuleNameRelative(typeReferenceDirectiveName)) {
                    var searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
                    result = searchResult && searchResult.value;
                }
                else {
                    var candidate = ts.normalizePathAndParts(ts.combinePaths(initialLocationForSecondaryLookup, typeReferenceDirectiveName)).path;
                    result = nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true);
                }
                var resolvedFile = resolvedTypeScriptOnly(result);
                if (!resolvedFile && traceEnabled) {
                    trace(host, ts.Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
                }
                return resolvedFile;
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder);
                }
            }
        }
    }
    ts.resolveTypeReferenceDirective = resolveTypeReferenceDirective;
    /**
     * Given a set of options, returns the set of type directive names
     *   that should be included for this program automatically.
     * This list could either come from the config file,
     *   or from enumerating the types root + initial secondary types lookup location.
     * More type directives might appear in the program later as a result of loading actual source files;
     *   this list is only the set of defaults that are implicitly included.
     */
    function getAutomaticTypeDirectiveNames(options, host) {
        // Use explicit type list from tsconfig.json
        if (options.types) {
            return options.types;
        }
        // Walk the primary type lookup locations
        var result = [];
        if (host.directoryExists && host.getDirectories) {
            var typeRoots = getEffectiveTypeRoots(options, host);
            if (typeRoots) {
                for (var _i = 0, typeRoots_1 = typeRoots; _i < typeRoots_1.length; _i++) {
                    var root = typeRoots_1[_i];
                    if (host.directoryExists(root)) {
                        for (var _a = 0, _b = host.getDirectories(root); _a < _b.length; _a++) {
                            var typeDirectivePath = _b[_a];
                            var normalized = ts.normalizePath(typeDirectivePath);
                            var packageJsonPath = ts.combinePaths(root, normalized, "package.json");
                            // `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
                            // See `createNotNeededPackageJSON` in the types-publisher` repo.
                            // eslint-disable-next-line no-null/no-null
                            var isNotNeededPackage = host.fileExists(packageJsonPath) && ts.readJson(packageJsonPath, host).typings === null;
                            if (!isNotNeededPackage) {
                                var baseFileName = ts.getBaseFileName(normalized);
                                // At this stage, skip results with leading dot.
                                if (baseFileName.charCodeAt(0) !== 46 /* dot */) {
                                    // Return just the type directive names
                                    result.push(baseFileName);
                                }
                            }
                        }
                    }
                }
            }
        }
        return result;
    }
    ts.getAutomaticTypeDirectiveNames = getAutomaticTypeDirectiveNames;
    function createModuleResolutionCache(currentDirectory, getCanonicalFileName, options) {
        return createModuleResolutionCacheWithMaps(createCacheWithRedirects(options), createCacheWithRedirects(options), currentDirectory, getCanonicalFileName);
    }
    ts.createModuleResolutionCache = createModuleResolutionCache;
    /*@internal*/
    function createCacheWithRedirects(options) {
        var ownMap = ts.createMap();
        var redirectsMap = ts.createMap();
        return {
            ownMap: ownMap,
            redirectsMap: redirectsMap,
            getOrCreateMapOfCacheRedirects: getOrCreateMapOfCacheRedirects,
            clear: clear,
            setOwnOptions: setOwnOptions,
            setOwnMap: setOwnMap
        };
        function setOwnOptions(newOptions) {
            options = newOptions;
        }
        function setOwnMap(newOwnMap) {
            ownMap = newOwnMap;
        }
        function getOrCreateMapOfCacheRedirects(redirectedReference) {
            if (!redirectedReference) {
                return ownMap;
            }
            var path = redirectedReference.sourceFile.path;
            var redirects = redirectsMap.get(path);
            if (!redirects) {
                // Reuse map if redirected reference map uses same resolution
                redirects = !options || ts.optionsHaveModuleResolutionChanges(options, redirectedReference.commandLine.options) ? ts.createMap() : ownMap;
                redirectsMap.set(path, redirects);
            }
            return redirects;
        }
        function clear() {
            ownMap.clear();
            redirectsMap.clear();
        }
    }
    ts.createCacheWithRedirects = createCacheWithRedirects;
    /*@internal*/
    function createModuleResolutionCacheWithMaps(directoryToModuleNameMap, moduleNameToDirectoryMap, currentDirectory, getCanonicalFileName) {
        return { getOrCreateCacheForDirectory: getOrCreateCacheForDirectory, getOrCreateCacheForModuleName: getOrCreateCacheForModuleName, directoryToModuleNameMap: directoryToModuleNameMap, moduleNameToDirectoryMap: moduleNameToDirectoryMap };
        function getOrCreateCacheForDirectory(directoryName, redirectedReference) {
            var path = ts.toPath(directoryName, currentDirectory, getCanonicalFileName);
            return getOrCreateCache(directoryToModuleNameMap, redirectedReference, path, ts.createMap);
        }
        function getOrCreateCacheForModuleName(nonRelativeModuleName, redirectedReference) {
            ts.Debug.assert(!ts.isExternalModuleNameRelative(nonRelativeModuleName));
            return getOrCreateCache(moduleNameToDirectoryMap, redirectedReference, nonRelativeModuleName, createPerModuleNameCache);
        }
        function getOrCreateCache(cacheWithRedirects, redirectedReference, key, create) {
            var cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
            var result = cache.get(key);
            if (!result) {
                result = create();
                cache.set(key, result);
            }
            return result;
        }
        function createPerModuleNameCache() {
            var directoryPathMap = ts.createMap();
            return { get: get, set: set };
            function get(directory) {
                return directoryPathMap.get(ts.toPath(directory, currentDirectory, getCanonicalFileName));
            }
            /**
             * At first this function add entry directory -> module resolution result to the table.
             * Then it computes the set of parent folders for 'directory' that should have the same module resolution result
             * and for every parent folder in set it adds entry: parent -> module resolution. .
             * Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts.
             * Set of parent folders that should have the same result will be:
             * [
             *     /a/b/c/d, /a/b/c, /a/b
             * ]
             * this means that request for module resolution from file in any of these folder will be immediately found in cache.
             */
            function set(directory, result) {
                var path = ts.toPath(directory, currentDirectory, getCanonicalFileName);
                // if entry is already in cache do nothing
                if (directoryPathMap.has(path)) {
                    return;
                }
                directoryPathMap.set(path, result);
                var resolvedFileName = result.resolvedModule &&
                    (result.resolvedModule.originalPath || result.resolvedModule.resolvedFileName);
                // find common prefix between directory and resolved file name
                // this common prefix should be the shortest path that has the same resolution
                // directory: /a/b/c/d/e
                // resolvedFileName: /a/b/foo.d.ts
                // commonPrefix: /a/b
                // for failed lookups cache the result for every directory up to root
                var commonPrefix = resolvedFileName && getCommonPrefix(path, resolvedFileName);
                var current = path;
                while (current !== commonPrefix) {
                    var parent = ts.getDirectoryPath(current);
                    if (parent === current || directoryPathMap.has(parent)) {
                        break;
                    }
                    directoryPathMap.set(parent, result);
                    current = parent;
                }
            }
            function getCommonPrefix(directory, resolution) {
                var resolutionDirectory = ts.toPath(ts.getDirectoryPath(resolution), currentDirectory, getCanonicalFileName);
                // find first position where directory and resolution differs
                var i = 0;
                var limit = Math.min(directory.length, resolutionDirectory.length);
                while (i < limit && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) {
                    i++;
                }
                if (i === directory.length && (resolutionDirectory.length === i || resolutionDirectory[i] === ts.directorySeparator)) {
                    return directory;
                }
                var rootLength = ts.getRootLength(directory);
                if (i < rootLength) {
                    return undefined;
                }
                var sep = directory.lastIndexOf(ts.directorySeparator, i - 1);
                if (sep === -1) {
                    return undefined;
                }
                return directory.substr(0, Math.max(sep, rootLength));
            }
        }
    }
    ts.createModuleResolutionCacheWithMaps = createModuleResolutionCacheWithMaps;
    function resolveModuleNameFromCache(moduleName, containingFile, cache) {
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
        return perFolderCache && perFolderCache.get(moduleName);
    }
    ts.resolveModuleNameFromCache = resolveModuleNameFromCache;
    function resolveModuleName(moduleName, containingFile, compilerOptions, host, cache, redirectedReference) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (redirectedReference) {
            compilerOptions = redirectedReference.commandLine.options;
        }
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
            if (redirectedReference) {
                trace(host, ts.Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
            }
        }
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference);
        var result = perFolderCache && perFolderCache.get(moduleName);
        if (result) {
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
            }
        }
        else {
            var moduleResolution = compilerOptions.moduleResolution;
            if (moduleResolution === undefined) {
                moduleResolution = ts.getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic;
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Module_resolution_kind_is_not_specified_using_0, ts.ModuleResolutionKind[moduleResolution]);
                }
            }
            else {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ts.ModuleResolutionKind[moduleResolution]);
                }
            }
            ts.perfLogger.logStartResolveModule(moduleName /* , containingFile, ModuleResolutionKind[moduleResolution]*/);
            switch (moduleResolution) {
                case ts.ModuleResolutionKind.NodeJs:
                    result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
                    break;
                case ts.ModuleResolutionKind.Classic:
                    result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
                    break;
                default:
                    return ts.Debug.fail("Unexpected moduleResolution: " + moduleResolution);
            }
            if (result && result.resolvedModule)
                ts.perfLogger.logInfoEvent("Module \"" + moduleName + "\" resolved to \"" + result.resolvedModule.resolvedFileName + "\"");
            ts.perfLogger.logStopResolveModule((result && result.resolvedModule) ? "" + result.resolvedModule.resolvedFileName : "null");
            if (perFolderCache) {
                perFolderCache.set(moduleName, result);
                if (!ts.isExternalModuleNameRelative(moduleName)) {
                    // put result in per-module name cache
                    cache.getOrCreateCacheForModuleName(moduleName, redirectedReference).set(containingDirectory, result);
                }
            }
        }
        if (traceEnabled) {
            if (result.resolvedModule) {
                if (result.resolvedModule.packageId) {
                    trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1_with_Package_ID_2, moduleName, result.resolvedModule.resolvedFileName, ts.packageIdToString(result.resolvedModule.packageId));
                }
                else {
                    trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName);
                }
            }
            else {
                trace(host, ts.Diagnostics.Module_name_0_was_not_resolved, moduleName);
            }
        }
        return result;
    }
    ts.resolveModuleName = resolveModuleName;
    /**
     * Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
     * mitigate differences between design time structure of the project and its runtime counterpart so the same import name
     * can be resolved successfully by TypeScript compiler and runtime module loader.
     * If these settings are set then loading procedure will try to use them to resolve module name and it can of failure it will
     * fallback to standard resolution routine.
     *
     * - baseUrl - this setting controls how non-relative module names are resolved. If this setting is specified then non-relative
     * names will be resolved relative to baseUrl: i.e. if baseUrl is '/a/b' then candidate location to resolve module name 'c/d' will
     * be '/a/b/c/d'
     * - paths - this setting can only be used when baseUrl is specified. allows to tune how non-relative module names
     * will be resolved based on the content of the module name.
     * Structure of 'paths' compiler options
     * 'paths': {
     *    pattern-1: [...substitutions],
     *    pattern-2: [...substitutions],
     *    ...
     *    pattern-n: [...substitutions]
     * }
     * Pattern here is a string that can contain zero or one '*' character. During module resolution module name will be matched against
     * all patterns in the list. Matching for patterns that don't contain '*' means that module name must be equal to pattern respecting the case.
     * If pattern contains '*' then to match pattern "<prefix>*<suffix>" module name must start with the <prefix> and end with <suffix>.
     * <MatchedStar> denotes part of the module name between <prefix> and <suffix>.
     * If module name can be matches with multiple patterns then pattern with the longest prefix will be picked.
     * After selecting pattern we'll use list of substitutions to get candidate locations of the module and the try to load module
     * from the candidate location.
     * Substitution is a string that can contain zero or one '*'. To get candidate location from substitution we'll pick every
     * substitution in the list and replace '*' with <MatchedStar> string. If candidate location is not rooted it
     * will be converted to absolute using baseUrl.
     * For example:
     * baseUrl: /a/b/c
     * "paths": {
     *     // match all module names
     *     "*": [
     *         "*",        // use matched name as is,
     *                     // <matched name> will be looked as /a/b/c/<matched name>
     *
     *         "folder1/*" // substitution will convert matched name to 'folder1/<matched name>',
     *                     // since it is not rooted then final candidate location will be /a/b/c/folder1/<matched name>
     *     ],
     *     // match module names that start with 'components/'
     *     "components/*": [ "/root/components/*" ] // substitution will convert /components/folder1/<matched name> to '/root/components/folder1/<matched name>',
     *                                              // it is rooted so it will be final candidate location
     * }
     *
     * 'rootDirs' allows the project to be spreaded across multiple locations and resolve modules with relative names as if
     * they were in the same location. For example lets say there are two files
     * '/local/src/content/file1.ts'
     * '/shared/components/contracts/src/content/protocols/file2.ts'
     * After bundling content of '/shared/components/contracts/src' will be merged with '/local/src' so
     * if file1 has the following import 'import {x} from "./protocols/file2"' it will be resolved successfully in runtime.
     * 'rootDirs' provides the way to tell compiler that in order to get the whole project it should behave as if content of all
     * root dirs were merged together.
     * I.e. for the example above 'rootDirs' will have two entries: [ '/local/src', '/shared/components/contracts/src' ].
     * Compiler will first convert './protocols/file2' into absolute path relative to the location of containing file:
     * '/local/src/content/protocols/file2' and try to load it - failure.
     * Then it will search 'rootDirs' looking for a longest matching prefix of this absolute path and if such prefix is found - absolute path will
     * be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining
     * entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
     */
    function tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state) {
        var resolved = tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state);
        if (resolved)
            return resolved.value;
        if (!ts.isExternalModuleNameRelative(moduleName)) {
            return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state);
        }
        else {
            return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, state);
        }
    }
    function tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state) {
        var _a = state.compilerOptions, baseUrl = _a.baseUrl, paths = _a.paths;
        if (baseUrl && paths && !ts.pathIsRelative(moduleName)) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
                trace(state.host, ts.Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
            }
            return tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
        }
    }
    function tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, state) {
        if (!state.compilerOptions.rootDirs) {
            return undefined;
        }
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, moduleName);
        }
        var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
        var matchedRootDir;
        var matchedNormalizedPrefix;
        for (var _i = 0, _a = state.compilerOptions.rootDirs; _i < _a.length; _i++) {
            var rootDir = _a[_i];
            // rootDirs are expected to be absolute
            // in case of tsconfig.json this will happen automatically - compiler will expand relative names
            // using location of tsconfig.json as base location
            var normalizedRoot = ts.normalizePath(rootDir);
            if (!ts.endsWith(normalizedRoot, ts.directorySeparator)) {
                normalizedRoot += ts.directorySeparator;
            }
            var isLongestMatchingPrefix = ts.startsWith(candidate, normalizedRoot) &&
                (matchedNormalizedPrefix === undefined || matchedNormalizedPrefix.length < normalizedRoot.length);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2, normalizedRoot, candidate, isLongestMatchingPrefix);
            }
            if (isLongestMatchingPrefix) {
                matchedNormalizedPrefix = normalizedRoot;
                matchedRootDir = rootDir;
            }
        }
        if (matchedNormalizedPrefix) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedNormalizedPrefix);
            }
            var suffix = candidate.substr(matchedNormalizedPrefix.length);
            // first - try to load from a initial location
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
            }
            var resolvedFileName = loader(extensions, candidate, !ts.directoryProbablyExists(containingDirectory, state.host), state);
            if (resolvedFileName) {
                return resolvedFileName;
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Trying_other_entries_in_rootDirs);
            }
            // then try to resolve using remaining entries in rootDirs
            for (var _b = 0, _c = state.compilerOptions.rootDirs; _b < _c.length; _b++) {
                var rootDir = _c[_b];
                if (rootDir === matchedRootDir) {
                    // skip the initially matched entry
                    continue;
                }
                var candidate_1 = ts.combinePaths(ts.normalizePath(rootDir), suffix);
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate_1);
                }
                var baseDirectory = ts.getDirectoryPath(candidate_1);
                var resolvedFileName_1 = loader(extensions, candidate_1, !ts.directoryProbablyExists(baseDirectory, state.host), state);
                if (resolvedFileName_1) {
                    return resolvedFileName_1;
                }
            }
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_resolution_using_rootDirs_has_failed);
            }
        }
        return undefined;
    }
    function tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state) {
        var baseUrl = state.compilerOptions.baseUrl;
        if (!baseUrl) {
            return undefined;
        }
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
        }
        var candidate = ts.normalizePath(ts.combinePaths(baseUrl, moduleName));
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate);
        }
        return loader(extensions, candidate, !ts.directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
    }
    /**
     * Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations.
     * No way to do this with `require()`: https://github.com/nodejs/node/issues/5963
     * Throws an error if the module can't be resolved.
     */
    /* @internal */
    function resolveJSModule(moduleName, initialDir, host) {
        var _a = tryResolveJSModuleWorker(moduleName, initialDir, host), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations;
        if (!resolvedModule) {
            throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", "));
        }
        return resolvedModule.resolvedFileName;
    }
    ts.resolveJSModule = resolveJSModule;
    /* @internal */
    function tryResolveJSModule(moduleName, initialDir, host) {
        var resolvedModule = tryResolveJSModuleWorker(moduleName, initialDir, host).resolvedModule;
        return resolvedModule && resolvedModule.resolvedFileName;
    }
    ts.tryResolveJSModule = tryResolveJSModule;
    var jsOnlyExtensions = [Extensions.JavaScript];
    var tsExtensions = [Extensions.TypeScript, Extensions.JavaScript];
    var tsPlusJsonExtensions = __spreadArrays(tsExtensions, [Extensions.Json]);
    var tsconfigExtensions = [Extensions.TSConfig];
    function tryResolveJSModuleWorker(moduleName, initialDir, host) {
        return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined);
    }
    function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, lookupConfig) {
        return nodeModuleNameResolverWorker(moduleName, ts.getDirectoryPath(containingFile), compilerOptions, host, cache, lookupConfig ? tsconfigExtensions : (compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions), redirectedReference);
    }
    ts.nodeModuleNameResolver = nodeModuleNameResolver;
    function nodeModuleNameResolverWorker(moduleName, containingDirectory, compilerOptions, host, cache, extensions, redirectedReference) {
        var _a, _b;
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var result = ts.forEach(extensions, function (ext) { return tryResolve(ext); });
        return createResolvedModuleWithFailedLookupLocations((_a = result === null || result === void 0 ? void 0 : result.value) === null || _a === void 0 ? void 0 : _a.resolved, (_b = result === null || result === void 0 ? void 0 : result.value) === null || _b === void 0 ? void 0 : _b.isExternalLibraryImport, failedLookupLocations, state.resultFromCache);
        function tryResolve(extensions) {
            var loader = function (extensions, candidate, onlyRecordFailures, state) { return nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true); };
            var resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state);
            if (resolved) {
                return toSearchResult({ resolved: resolved, isExternalLibraryImport: pathContainsNodeModules(resolved.path) });
            }
            if (!ts.isExternalModuleNameRelative(moduleName)) {
                if (traceEnabled) {
                    trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
                }
                var resolved_1 = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
                if (!resolved_1)
                    return undefined;
                var resolvedValue = resolved_1.value;
                if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
                    var path = realPath(resolvedValue.path, host, traceEnabled);
                    var originalPath = path === resolvedValue.path ? undefined : resolvedValue.path;
                    resolvedValue = __assign(__assign({}, resolvedValue), { path: path, originalPath: originalPath });
                }
                // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
                return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
            }
            else {
                var _a = ts.normalizePathAndParts(ts.combinePaths(containingDirectory, moduleName)), candidate = _a.path, parts = _a.parts;
                var resolved_2 = nodeLoadModuleByRelativeName(extensions, candidate, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
                // Treat explicit "node_modules" import as an external library import.
                return resolved_2 && toSearchResult({ resolved: resolved_2, isExternalLibraryImport: ts.contains(parts, "node_modules") });
            }
        }
    }
    function realPath(path, host, traceEnabled) {
        if (!host.realpath) {
            return path;
        }
        var real = ts.normalizePath(host.realpath(path));
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Resolving_real_path_for_0_result_1, path, real);
        }
        ts.Debug.assert(host.fileExists(real), path + " linked to nonexistent file " + real);
        return real;
    }
    function nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, considerPackageJson) {
        if (state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]);
        }
        if (!ts.hasTrailingDirectorySeparator(candidate)) {
            if (!onlyRecordFailures) {
                var parentOfCandidate = ts.getDirectoryPath(candidate);
                if (!ts.directoryProbablyExists(parentOfCandidate, state.host)) {
                    if (state.traceEnabled) {
                        trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parentOfCandidate);
                    }
                    onlyRecordFailures = true;
                }
            }
            var resolvedFromFile = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state);
            if (resolvedFromFile) {
                var packageDirectory = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile) : undefined;
                var packageInfo = packageDirectory ? getPackageJsonInfo(packageDirectory, /*onlyRecordFailures*/ false, state) : undefined;
                return withPackageId(packageInfo, resolvedFromFile);
            }
        }
        if (!onlyRecordFailures) {
            var candidateExists = ts.directoryProbablyExists(candidate, state.host);
            if (!candidateExists) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate);
                }
                onlyRecordFailures = true;
            }
        }
        return loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson);
    }
    /*@internal*/
    ts.nodeModulesPathPart = "/node_modules/";
    /*@internal*/
    function pathContainsNodeModules(path) {
        return ts.stringContains(path, ts.nodeModulesPathPart);
    }
    ts.pathContainsNodeModules = pathContainsNodeModules;
    /**
     * This will be called on the successfully resolved path from `loadModuleFromFile`.
     * (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.)
     *
     * packageDirectory is the directory of the package itself.
     *   For `blah/node_modules/foo/index.d.ts` this is packageDirectory: "foo"
     *   For `/node_modules/foo/bar.d.ts` this is packageDirectory: "foo"
     *   For `/node_modules/@types/foo/bar/index.d.ts` this is packageDirectory: "@types/foo"
     *   For `/node_modules/foo/bar/index.d.ts` this is packageDirectory: "foo"
     */
    function parseNodeModuleFromPath(resolved) {
        var path = ts.normalizePath(resolved.path);
        var idx = path.lastIndexOf(ts.nodeModulesPathPart);
        if (idx === -1) {
            return undefined;
        }
        var indexAfterNodeModules = idx + ts.nodeModulesPathPart.length;
        var indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules);
        if (path.charCodeAt(indexAfterNodeModules) === 64 /* at */) {
            indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName);
        }
        return path.slice(0, indexAfterPackageName);
    }
    function moveToNextDirectorySeparatorIfAvailable(path, prevSeparatorIndex) {
        var nextSeparatorIndex = path.indexOf(ts.directorySeparator, prevSeparatorIndex + 1);
        return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex;
    }
    function loadModuleFromFileNoPackageId(extensions, candidate, onlyRecordFailures, state) {
        return noPackageId(loadModuleFromFile(extensions, candidate, onlyRecordFailures, state));
    }
    /**
     * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
     * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
     */
    function loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) {
        if (extensions === Extensions.Json || extensions === Extensions.TSConfig) {
            var extensionLess = ts.tryRemoveExtension(candidate, ".json" /* Json */);
            return (extensionLess === undefined && extensions === Extensions.Json) ? undefined : tryAddingExtensions(extensionLess || candidate, extensions, onlyRecordFailures, state);
        }
        // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
        var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, onlyRecordFailures, state);
        if (resolvedByAddingExtension) {
            return resolvedByAddingExtension;
        }
        // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one;
        // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts"
        if (ts.hasJSFileExtension(candidate)) {
            var extensionless = ts.removeFileExtension(candidate);
            if (state.traceEnabled) {
                var extension = candidate.substring(extensionless.length);
                trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
            }
            return tryAddingExtensions(extensionless, extensions, onlyRecordFailures, state);
        }
    }
    /** Try to return an existing file that adds one of the `extensions` to `candidate`. */
    function tryAddingExtensions(candidate, extensions, onlyRecordFailures, state) {
        if (!onlyRecordFailures) {
            // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
            var directory = ts.getDirectoryPath(candidate);
            if (directory) {
                onlyRecordFailures = !ts.directoryProbablyExists(directory, state.host);
            }
        }
        switch (extensions) {
            case Extensions.DtsOnly:
                return tryExtension(".d.ts" /* Dts */);
            case Extensions.TypeScript:
                return tryExtension(".ts" /* Ts */) || tryExtension(".tsx" /* Tsx */) || tryExtension(".d.ts" /* Dts */);
            case Extensions.JavaScript:
                return tryExtension(".js" /* Js */) || tryExtension(".jsx" /* Jsx */);
            case Extensions.TSConfig:
            case Extensions.Json:
                return tryExtension(".json" /* Json */);
        }
        function tryExtension(ext) {
            var path = tryFile(candidate + ext, onlyRecordFailures, state);
            return path === undefined ? undefined : { path: path, ext: ext };
        }
    }
    /** Return the file if it exists. */
    function tryFile(fileName, onlyRecordFailures, state) {
        if (!onlyRecordFailures) {
            if (state.host.fileExists(fileName)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName);
                }
                return fileName;
            }
            else {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName);
                }
            }
        }
        state.failedLookupLocations.push(fileName);
        return undefined;
    }
    function loadNodeModuleFromDirectory(extensions, candidate, onlyRecordFailures, state, considerPackageJson) {
        if (considerPackageJson === void 0) { considerPackageJson = true; }
        var packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, onlyRecordFailures, state) : undefined;
        var packageJsonContent = packageInfo && packageInfo.packageJsonContent;
        var versionPaths = packageInfo && packageInfo.versionPaths;
        return withPackageId(packageInfo, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths));
    }
    function getPackageJsonInfo(packageDirectory, onlyRecordFailures, state) {
        var host = state.host, traceEnabled = state.traceEnabled;
        var directoryExists = !onlyRecordFailures && ts.directoryProbablyExists(packageDirectory, host);
        var packageJsonPath = ts.combinePaths(packageDirectory, "package.json");
        if (directoryExists && host.fileExists(packageJsonPath)) {
            var packageJsonContent = ts.readJson(packageJsonPath, host);
            if (traceEnabled) {
                trace(host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath);
            }
            var versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state);
            return { packageDirectory: packageDirectory, packageJsonContent: packageJsonContent, versionPaths: versionPaths };
        }
        else {
            if (directoryExists && traceEnabled) {
                trace(host, ts.Diagnostics.File_0_does_not_exist, packageJsonPath);
            }
            // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
            state.failedLookupLocations.push(packageJsonPath);
        }
    }
    function loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, jsonContent, versionPaths) {
        var packageFile;
        if (jsonContent) {
            switch (extensions) {
                case Extensions.JavaScript:
                case Extensions.Json:
                    packageFile = readPackageJsonMainField(jsonContent, candidate, state);
                    break;
                case Extensions.TypeScript:
                    // When resolving typescript modules, try resolving using main field as well
                    packageFile = readPackageJsonTypesFields(jsonContent, candidate, state) || readPackageJsonMainField(jsonContent, candidate, state);
                    break;
                case Extensions.DtsOnly:
                    packageFile = readPackageJsonTypesFields(jsonContent, candidate, state);
                    break;
                case Extensions.TSConfig:
                    packageFile = readPackageJsonTSConfigField(jsonContent, candidate, state);
                    break;
                default:
                    return ts.Debug.assertNever(extensions);
            }
        }
        var loader = function (extensions, candidate, onlyRecordFailures, state) {
            var fromFile = tryFile(candidate, onlyRecordFailures, state);
            if (fromFile) {
                var resolved = resolvedIfExtensionMatches(extensions, fromFile);
                if (resolved) {
                    return noPackageId(resolved);
                }
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
                }
            }
            // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
            var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions;
            // Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
            return nodeLoadModuleByRelativeName(nextExtensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ false);
        };
        var onlyRecordFailuresForPackageFile = packageFile ? !ts.directoryProbablyExists(ts.getDirectoryPath(packageFile), state.host) : undefined;
        var onlyRecordFailuresForIndex = onlyRecordFailures || !ts.directoryProbablyExists(candidate, state.host);
        var indexPath = ts.combinePaths(candidate, extensions === Extensions.TSConfig ? "tsconfig" : "index");
        if (versionPaths && (!packageFile || ts.containsPath(candidate, packageFile))) {
            var moduleName = ts.getRelativePathFromDirectory(candidate, packageFile || indexPath, /*ignoreCase*/ false);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, versionPaths.version, ts.version, moduleName);
            }
            var result = tryLoadModuleUsingPaths(extensions, moduleName, candidate, versionPaths.paths, loader, onlyRecordFailuresForPackageFile || onlyRecordFailuresForIndex, state);
            if (result) {
                return removeIgnoredPackageId(result.value);
            }
        }
        // It won't have a `packageId` set, because we disabled `considerPackageJson`.
        var packageFileResult = packageFile && removeIgnoredPackageId(loader(extensions, packageFile, onlyRecordFailuresForPackageFile, state));
        if (packageFileResult)
            return packageFileResult;
        return loadModuleFromFile(extensions, indexPath, onlyRecordFailuresForIndex, state);
    }
    /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
    function resolvedIfExtensionMatches(extensions, path) {
        var ext = ts.tryGetExtensionFromPath(path);
        return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined;
    }
    /** True if `extension` is one of the supported `extensions`. */
    function extensionIsOk(extensions, extension) {
        switch (extensions) {
            case Extensions.JavaScript:
                return extension === ".js" /* Js */ || extension === ".jsx" /* Jsx */;
            case Extensions.TSConfig:
            case Extensions.Json:
                return extension === ".json" /* Json */;
            case Extensions.TypeScript:
                return extension === ".ts" /* Ts */ || extension === ".tsx" /* Tsx */ || extension === ".d.ts" /* Dts */;
            case Extensions.DtsOnly:
                return extension === ".d.ts" /* Dts */;
        }
    }
    /* @internal */
    function parsePackageName(moduleName) {
        var idx = moduleName.indexOf(ts.directorySeparator);
        if (moduleName[0] === "@") {
            idx = moduleName.indexOf(ts.directorySeparator, idx + 1);
        }
        return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
    }
    ts.parsePackageName = parsePackageName;
    function loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, directory, state, cache, redirectedReference) {
        return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache, redirectedReference);
    }
    function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, directory, state) {
        // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
        return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined, /*redirectedReference*/ undefined);
    }
    function loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, typesScopeOnly, cache, redirectedReference) {
        var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
        return ts.forEachAncestorDirectory(ts.normalizeSlashes(directory), function (ancestorDirectory) {
            if (ts.getBaseFileName(ancestorDirectory) !== "node_modules") {
                var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state);
                if (resolutionFromCache) {
                    return resolutionFromCache;
                }
                return toSearchResult(loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, ancestorDirectory, state, typesScopeOnly));
            }
        });
    }
    function loadModuleFromImmediateNodeModulesDirectory(extensions, moduleName, directory, state, typesScopeOnly) {
        var nodeModulesFolder = ts.combinePaths(directory, "node_modules");
        var nodeModulesFolderExists = ts.directoryProbablyExists(nodeModulesFolder, state.host);
        if (!nodeModulesFolderExists && state.traceEnabled) {
            trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder);
        }
        var packageResult = typesScopeOnly ? undefined : loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, state);
        if (packageResult) {
            return packageResult;
        }
        if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
            var nodeModulesAtTypes_1 = ts.combinePaths(nodeModulesFolder, "@types");
            var nodeModulesAtTypesExists = nodeModulesFolderExists;
            if (nodeModulesFolderExists && !ts.directoryProbablyExists(nodeModulesAtTypes_1, state.host)) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesAtTypes_1);
                }
                nodeModulesAtTypesExists = false;
            }
            return loadModuleFromSpecificNodeModulesDirectory(Extensions.DtsOnly, mangleScopedPackageNameWithTrace(moduleName, state), nodeModulesAtTypes_1, nodeModulesAtTypesExists, state);
        }
    }
    function loadModuleFromSpecificNodeModulesDirectory(extensions, moduleName, nodeModulesDirectory, nodeModulesDirectoryExists, state) {
        var candidate = ts.normalizePath(ts.combinePaths(nodeModulesDirectory, moduleName));
        // First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
        var packageInfo = getPackageJsonInfo(candidate, !nodeModulesDirectoryExists, state);
        if (packageInfo) {
            var fromFile = loadModuleFromFile(extensions, candidate, !nodeModulesDirectoryExists, state);
            if (fromFile) {
                return noPackageId(fromFile);
            }
            var fromDirectory = loadNodeModuleFromDirectoryWorker(extensions, candidate, !nodeModulesDirectoryExists, state, packageInfo.packageJsonContent, packageInfo.versionPaths);
            return withPackageId(packageInfo, fromDirectory);
        }
        var loader = function (extensions, candidate, onlyRecordFailures, state) {
            var pathAndExtension = loadModuleFromFile(extensions, candidate, onlyRecordFailures, state) ||
                loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageInfo && packageInfo.packageJsonContent, packageInfo && packageInfo.versionPaths);
            return withPackageId(packageInfo, pathAndExtension);
        };
        var _a = parsePackageName(moduleName), packageName = _a.packageName, rest = _a.rest;
        if (rest !== "") { // If "rest" is empty, we just did this search above.
            var packageDirectory = ts.combinePaths(nodeModulesDirectory, packageName);
            // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings.
            packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state);
            if (packageInfo && packageInfo.versionPaths) {
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.versionPaths.version, ts.version, rest);
                }
                var packageDirectoryExists = nodeModulesDirectoryExists && ts.directoryProbablyExists(packageDirectory, state.host);
                var fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, packageInfo.versionPaths.paths, loader, !packageDirectoryExists, state);
                if (fromPaths) {
                    return fromPaths.value;
                }
            }
        }
        return loader(extensions, candidate, !nodeModulesDirectoryExists, state);
    }
    function tryLoadModuleUsingPaths(extensions, moduleName, baseDirectory, paths, loader, onlyRecordFailures, state) {
        var matchedPattern = ts.matchPatternOrExact(ts.getOwnKeys(paths), moduleName);
        if (matchedPattern) {
            var matchedStar_1 = ts.isString(matchedPattern) ? undefined : ts.matchedText(matchedPattern, moduleName);
            var matchedPatternText = ts.isString(matchedPattern) ? matchedPattern : ts.patternText(matchedPattern);
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText);
            }
            var resolved = ts.forEach(paths[matchedPatternText], function (subst) {
                var path = matchedStar_1 ? subst.replace("*", matchedStar_1) : subst;
                var candidate = ts.normalizePath(ts.combinePaths(baseDirectory, path));
                if (state.traceEnabled) {
                    trace(state.host, ts.Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
                }
                // A path mapping may have an extension, in contrast to an import, which should omit it.
                var extension = ts.tryGetExtensionFromPath(candidate);
                if (extension !== undefined) {
                    var path_1 = tryFile(candidate, onlyRecordFailures, state);
                    if (path_1 !== undefined) {
                        return noPackageId({ path: path_1, ext: extension });
                    }
                }
                return loader(extensions, candidate, onlyRecordFailures || !ts.directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state);
            });
            return { value: resolved };
        }
    }
    /** Double underscores are used in DefinitelyTyped to delimit scoped packages. */
    var mangledScopedPackageSeparator = "__";
    /** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
    function mangleScopedPackageNameWithTrace(packageName, state) {
        var mangled = mangleScopedPackageName(packageName);
        if (state.traceEnabled && mangled !== packageName) {
            trace(state.host, ts.Diagnostics.Scoped_package_detected_looking_in_0, mangled);
        }
        return mangled;
    }
    /* @internal */
    function getTypesPackageName(packageName) {
        return "@types/" + mangleScopedPackageName(packageName);
    }
    ts.getTypesPackageName = getTypesPackageName;
    /* @internal */
    function mangleScopedPackageName(packageName) {
        if (ts.startsWith(packageName, "@")) {
            var replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
            if (replaceSlash !== packageName) {
                return replaceSlash.slice(1); // Take off the "@"
            }
        }
        return packageName;
    }
    ts.mangleScopedPackageName = mangleScopedPackageName;
    /* @internal */
    function getPackageNameFromTypesPackageName(mangledName) {
        var withoutAtTypePrefix = ts.removePrefix(mangledName, "@types/");
        if (withoutAtTypePrefix !== mangledName) {
            return unmangleScopedPackageName(withoutAtTypePrefix);
        }
        return mangledName;
    }
    ts.getPackageNameFromTypesPackageName = getPackageNameFromTypesPackageName;
    /* @internal */
    function unmangleScopedPackageName(typesPackageName) {
        return ts.stringContains(typesPackageName, mangledScopedPackageSeparator) ?
            "@" + typesPackageName.replace(mangledScopedPackageSeparator, ts.directorySeparator) :
            typesPackageName;
    }
    ts.unmangleScopedPackageName = unmangleScopedPackageName;
    function tryFindNonRelativeModuleNameInCache(cache, moduleName, containingDirectory, state) {
        var result = cache && cache.get(containingDirectory);
        if (result) {
            if (state.traceEnabled) {
                trace(state.host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache_from_location_1, moduleName, containingDirectory);
            }
            state.resultFromCache = result;
            return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, originalPath: result.resolvedModule.originalPath || true, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } };
        }
    }
    function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var containingDirectory = ts.getDirectoryPath(containingFile);
        var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
        // No originalPath because classic resolution doesn't resolve realPath
        return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations, state.resultFromCache);
        function tryResolve(extensions) {
            var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, state);
            if (resolvedUsingSettings) {
                return { value: resolvedUsingSettings };
            }
            if (!ts.isExternalModuleNameRelative(moduleName)) {
                var perModuleNameCache_1 = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
                // Climb up parent directories looking for a module.
                var resolved_3 = ts.forEachAncestorDirectory(containingDirectory, function (directory) {
                    var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache_1, moduleName, directory, state);
                    if (resolutionFromCache) {
                        return resolutionFromCache;
                    }
                    var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName));
                    return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, /*onlyRecordFailures*/ false, state));
                });
                if (resolved_3) {
                    return resolved_3;
                }
                if (extensions === Extensions.TypeScript) {
                    // If we didn't find the file normally, look it up in @types.
                    return loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName, containingDirectory, state);
                }
            }
            else {
                var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName));
                return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, /*onlyRecordFailures*/ false, state));
            }
        }
    }
    ts.classicNameResolver = classicNameResolver;
    /**
     * A host may load a module from a global cache of typings.
     * This is the minumum code needed to expose that functionality; the rest is in the host.
     */
    /* @internal */
    function loadModuleFromGlobalCache(moduleName, projectName, compilerOptions, host, globalCache) {
        var traceEnabled = isTraceEnabled(compilerOptions, host);
        if (traceEnabled) {
            trace(host, ts.Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
        }
        var failedLookupLocations = [];
        var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled, failedLookupLocations: failedLookupLocations };
        var resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false);
        return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations, state.resultFromCache);
    }
    ts.loadModuleFromGlobalCache = loadModuleFromGlobalCache;
    /**
     * Wraps value to SearchResult.
     * @returns undefined if value is undefined or { value } otherwise
     */
    function toSearchResult(value) {
        return value !== undefined ? { value: value } : undefined;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var ModuleInstanceState;
    (function (ModuleInstanceState) {
        ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated";
        ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated";
        ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly";
    })(ModuleInstanceState = ts.ModuleInstanceState || (ts.ModuleInstanceState = {}));
    function getModuleInstanceState(node, visited) {
        if (node.body && !node.body.parent) {
            // getModuleInstanceStateForAliasTarget needs to walk up the parent chain, so parent pointers must be set on this tree already
            setParentPointers(node, node.body);
        }
        return node.body ? getModuleInstanceStateCached(node.body, visited) : 1 /* Instantiated */;
    }
    ts.getModuleInstanceState = getModuleInstanceState;
    function getModuleInstanceStateCached(node, visited) {
        if (visited === void 0) { visited = ts.createMap(); }
        var nodeId = "" + ts.getNodeId(node);
        if (visited.has(nodeId)) {
            return visited.get(nodeId) || 0 /* NonInstantiated */;
        }
        visited.set(nodeId, undefined);
        var result = getModuleInstanceStateWorker(node, visited);
        visited.set(nodeId, result);
        return result;
    }
    function getModuleInstanceStateWorker(node, visited) {
        // A module is uninstantiated if it contains only
        switch (node.kind) {
            // 1. interface declarations, type alias declarations
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
                return 0 /* NonInstantiated */;
            // 2. const enum declarations
            case 248 /* EnumDeclaration */:
                if (ts.isEnumConst(node)) {
                    return 2 /* ConstEnumOnly */;
                }
                break;
            // 3. non-exported import declarations
            case 254 /* ImportDeclaration */:
            case 253 /* ImportEqualsDeclaration */:
                if (!(ts.hasModifier(node, 1 /* Export */))) {
                    return 0 /* NonInstantiated */;
                }
                break;
            // 4. Export alias declarations pointing at only uninstantiated modules or things uninstantiated modules contain
            case 260 /* ExportDeclaration */:
                var exportDeclaration = node;
                if (!exportDeclaration.moduleSpecifier && exportDeclaration.exportClause && exportDeclaration.exportClause.kind === 261 /* NamedExports */) {
                    var state = 0 /* NonInstantiated */;
                    for (var _i = 0, _a = exportDeclaration.exportClause.elements; _i < _a.length; _i++) {
                        var specifier = _a[_i];
                        var specifierState = getModuleInstanceStateForAliasTarget(specifier, visited);
                        if (specifierState > state) {
                            state = specifierState;
                        }
                        if (state === 1 /* Instantiated */) {
                            return state;
                        }
                    }
                    return state;
                }
                break;
            // 5. other uninstantiated module declarations.
            case 250 /* ModuleBlock */: {
                var state_1 = 0 /* NonInstantiated */;
                ts.forEachChild(node, function (n) {
                    var childState = getModuleInstanceStateCached(n, visited);
                    switch (childState) {
                        case 0 /* NonInstantiated */:
                            // child is non-instantiated - continue searching
                            return;
                        case 2 /* ConstEnumOnly */:
                            // child is const enum only - record state and continue searching
                            state_1 = 2 /* ConstEnumOnly */;
                            return;
                        case 1 /* Instantiated */:
                            // child is instantiated - record state and stop
                            state_1 = 1 /* Instantiated */;
                            return true;
                        default:
                            ts.Debug.assertNever(childState);
                    }
                });
                return state_1;
            }
            case 249 /* ModuleDeclaration */:
                return getModuleInstanceState(node, visited);
            case 75 /* Identifier */:
                // Only jsdoc typedef definition can exist in jsdoc namespace, and it should
                // be considered the same as type alias
                if (node.isInJSDocNamespace) {
                    return 0 /* NonInstantiated */;
                }
        }
        return 1 /* Instantiated */;
    }
    function getModuleInstanceStateForAliasTarget(specifier, visited) {
        var name = specifier.propertyName || specifier.name;
        var p = specifier.parent;
        while (p) {
            if (ts.isBlock(p) || ts.isModuleBlock(p) || ts.isSourceFile(p)) {
                var statements = p.statements;
                var found = void 0;
                for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) {
                    var statement = statements_1[_i];
                    if (ts.nodeHasName(statement, name)) {
                        if (!statement.parent) {
                            setParentPointers(p, statement);
                        }
                        var state = getModuleInstanceStateCached(statement, visited);
                        if (found === undefined || state > found) {
                            found = state;
                        }
                        if (found === 1 /* Instantiated */) {
                            return found;
                        }
                    }
                }
                if (found !== undefined) {
                    return found;
                }
            }
            p = p.parent;
        }
        return 1 /* Instantiated */; // Couldn't locate, assume could refer to a value
    }
    var ContainerFlags;
    (function (ContainerFlags) {
        // The current node is not a container, and no container manipulation should happen before
        // recursing into it.
        ContainerFlags[ContainerFlags["None"] = 0] = "None";
        // The current node is a container.  It should be set as the current container (and block-
        // container) before recursing into it.  The current node does not have locals.  Examples:
        //
        //      Classes, ObjectLiterals, TypeLiterals, Interfaces...
        ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer";
        // The current node is a block-scoped-container.  It should be set as the current block-
        // container before recursing into it.  Examples:
        //
        //      Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements...
        ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer";
        // The current node is the container of a control flow path. The current control flow should
        // be saved and restored, and a new control flow initialized within the container.
        ContainerFlags[ContainerFlags["IsControlFlowContainer"] = 4] = "IsControlFlowContainer";
        ContainerFlags[ContainerFlags["IsFunctionLike"] = 8] = "IsFunctionLike";
        ContainerFlags[ContainerFlags["IsFunctionExpression"] = 16] = "IsFunctionExpression";
        ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals";
        ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface";
        ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod";
    })(ContainerFlags || (ContainerFlags = {}));
    function initFlowNode(node) {
        ts.Debug.attachFlowNodeDebugInfo(node);
        return node;
    }
    var binder = createBinder();
    function bindSourceFile(file, options) {
        ts.performance.mark("beforeBind");
        ts.perfLogger.logStartBindFile("" + file.fileName);
        binder(file, options);
        ts.perfLogger.logStopBindFile();
        ts.performance.mark("afterBind");
        ts.performance.measure("Bind", "beforeBind", "afterBind");
    }
    ts.bindSourceFile = bindSourceFile;
    function createBinder() {
        var file;
        var options;
        var languageVersion;
        var parent;
        var container;
        var thisParentContainer; // Container one level up
        var blockScopeContainer;
        var lastContainer;
        var delayedTypeAliases;
        var seenThisKeyword;
        // state used by control flow analysis
        var currentFlow;
        var currentBreakTarget;
        var currentContinueTarget;
        var currentReturnTarget;
        var currentTrueTarget;
        var currentFalseTarget;
        var currentExceptionTarget;
        var preSwitchCaseFlow;
        var activeLabelList;
        var hasExplicitReturn;
        // state used for emit helpers
        var emitFlags;
        // If this file is an external module, then it is automatically in strict-mode according to
        // ES6.  If it is not an external module, then we'll determine if it is in strict mode or
        // not depending on if we see "use strict" in certain places or if we hit a class/namespace
        // or if compiler options contain alwaysStrict.
        var inStrictMode;
        var symbolCount = 0;
        var Symbol;
        var classifiableNames;
        var unreachableFlow = { flags: 1 /* Unreachable */ };
        var reportedUnreachableFlow = { flags: 1 /* Unreachable */ };
        // state used to aggregate transform flags during bind.
        var subtreeTransformFlags = 0 /* None */;
        var skipTransformFlagAggregation;
        /**
         * Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file)
         * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node)
         * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations.
         */
        function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
            return ts.createDiagnosticForNodeInSourceFile(ts.getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2);
        }
        function bindSourceFile(f, opts) {
            file = f;
            options = opts;
            languageVersion = ts.getEmitScriptTarget(options);
            inStrictMode = bindInStrictMode(file, opts);
            classifiableNames = ts.createUnderscoreEscapedMap();
            symbolCount = 0;
            skipTransformFlagAggregation = file.isDeclarationFile;
            Symbol = ts.objectAllocator.getSymbolConstructor();
            // Attach debugging information if necessary
            ts.Debug.attachFlowNodeDebugInfo(unreachableFlow);
            ts.Debug.attachFlowNodeDebugInfo(reportedUnreachableFlow);
            if (!file.locals) {
                bind(file);
                file.symbolCount = symbolCount;
                file.classifiableNames = classifiableNames;
                delayedBindJSDocTypedefTag();
            }
            file = undefined;
            options = undefined;
            languageVersion = undefined;
            parent = undefined;
            container = undefined;
            thisParentContainer = undefined;
            blockScopeContainer = undefined;
            lastContainer = undefined;
            delayedTypeAliases = undefined;
            seenThisKeyword = false;
            currentFlow = undefined;
            currentBreakTarget = undefined;
            currentContinueTarget = undefined;
            currentReturnTarget = undefined;
            currentTrueTarget = undefined;
            currentFalseTarget = undefined;
            currentExceptionTarget = undefined;
            activeLabelList = undefined;
            hasExplicitReturn = false;
            emitFlags = 0 /* None */;
            subtreeTransformFlags = 0 /* None */;
        }
        return bindSourceFile;
        function bindInStrictMode(file, opts) {
            if (ts.getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) {
                // bind in strict mode source files with alwaysStrict option
                return true;
            }
            else {
                return !!file.externalModuleIndicator;
            }
        }
        function createSymbol(flags, name) {
            symbolCount++;
            return new Symbol(flags, name);
        }
        function addDeclarationToSymbol(symbol, node, symbolFlags) {
            symbol.flags |= symbolFlags;
            node.symbol = symbol;
            symbol.declarations = ts.appendIfUnique(symbol.declarations, node);
            if (symbolFlags & (32 /* Class */ | 384 /* Enum */ | 1536 /* Module */ | 3 /* Variable */) && !symbol.exports) {
                symbol.exports = ts.createSymbolTable();
            }
            if (symbolFlags & (32 /* Class */ | 64 /* Interface */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && !symbol.members) {
                symbol.members = ts.createSymbolTable();
            }
            // On merge of const enum module with class or function, reset const enum only flag (namespaces will already recalculate)
            if (symbol.constEnumOnlyModule && (symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */))) {
                symbol.constEnumOnlyModule = false;
            }
            if (symbolFlags & 111551 /* Value */) {
                ts.setValueDeclaration(symbol, node);
            }
        }
        // Should not be called on a declaration with a computed property name,
        // unless it is a well known Symbol.
        function getDeclarationName(node) {
            if (node.kind === 259 /* ExportAssignment */) {
                return node.isExportEquals ? "export=" /* ExportEquals */ : "default" /* Default */;
            }
            var name = ts.getNameOfDeclaration(node);
            if (name) {
                if (ts.isAmbientModule(node)) {
                    var moduleName = ts.getTextOfIdentifierOrLiteral(name);
                    return (ts.isGlobalScopeAugmentation(node) ? "__global" : "\"" + moduleName + "\"");
                }
                if (name.kind === 154 /* ComputedPropertyName */) {
                    var nameExpression = name.expression;
                    // treat computed property names where expression is string/numeric literal as just string/numeric literal
                    if (ts.isStringOrNumericLiteralLike(nameExpression)) {
                        return ts.escapeLeadingUnderscores(nameExpression.text);
                    }
                    if (ts.isSignedNumericLiteral(nameExpression)) {
                        return ts.tokenToString(nameExpression.operator) + nameExpression.operand.text;
                    }
                    ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression));
                    return ts.getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name));
                }
                if (ts.isWellKnownSymbolSyntactically(name)) {
                    return ts.getPropertyNameForKnownSymbolName(ts.idText(name.name));
                }
                if (ts.isPrivateIdentifier(name)) {
                    // containingClass exists because private names only allowed inside classes
                    var containingClass = ts.getContainingClass(node);
                    if (!containingClass) {
                        // we can get here in cases where there is already a parse error.
                        return undefined;
                    }
                    var containingClassSymbol = containingClass.symbol;
                    return ts.getSymbolNameForPrivateIdentifier(containingClassSymbol, name.escapedText);
                }
                return ts.isPropertyNameLiteral(name) ? ts.getEscapedTextOfIdentifierOrLiteral(name) : undefined;
            }
            switch (node.kind) {
                case 162 /* Constructor */:
                    return "__constructor" /* Constructor */;
                case 170 /* FunctionType */:
                case 165 /* CallSignature */:
                case 305 /* JSDocSignature */:
                    return "__call" /* Call */;
                case 171 /* ConstructorType */:
                case 166 /* ConstructSignature */:
                    return "__new" /* New */;
                case 167 /* IndexSignature */:
                    return "__index" /* Index */;
                case 260 /* ExportDeclaration */:
                    return "__export" /* ExportStar */;
                case 290 /* SourceFile */:
                    // json file should behave as
                    // module.exports = ...
                    return "export=" /* ExportEquals */;
                case 209 /* BinaryExpression */:
                    if (ts.getAssignmentDeclarationKind(node) === 2 /* ModuleExports */) {
                        // module.exports = ...
                        return "export=" /* ExportEquals */;
                    }
                    ts.Debug.fail("Unknown binary declaration kind");
                    break;
                case 300 /* JSDocFunctionType */:
                    return (ts.isJSDocConstructSignature(node) ? "__new" /* New */ : "__call" /* Call */);
                case 156 /* Parameter */:
                    // Parameters with names are handled at the top of this function.  Parameters
                    // without names can only come from JSDocFunctionTypes.
                    ts.Debug.assert(node.parent.kind === 300 /* JSDocFunctionType */, "Impossible parameter parent kind", function () { return "parent is: " + (ts.SyntaxKind ? ts.SyntaxKind[node.parent.kind] : node.parent.kind) + ", expected JSDocFunctionType"; });
                    var functionType = node.parent;
                    var index = functionType.parameters.indexOf(node);
                    return "arg" + index;
            }
        }
        function getDisplayName(node) {
            return ts.isNamedDeclaration(node) ? ts.declarationNameToString(node.name) : ts.unescapeLeadingUnderscores(ts.Debug.checkDefined(getDeclarationName(node)));
        }
        /**
         * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names.
         * @param symbolTable - The symbol table which node will be added to.
         * @param parent - node's parent declaration.
         * @param node - The declaration to be added to the symbol table
         * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
         * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
         */
        function declareSymbol(symbolTable, parent, node, includes, excludes, isReplaceableByMethod) {
            ts.Debug.assert(!ts.hasDynamicName(node));
            var isDefaultExport = ts.hasModifier(node, 512 /* Default */) || ts.isExportSpecifier(node) && node.name.escapedText === "default";
            // The exported symbol for an export default function/class node is always named "default"
            var name = isDefaultExport && parent ? "default" /* Default */ : getDeclarationName(node);
            var symbol;
            if (name === undefined) {
                symbol = createSymbol(0 /* None */, "__missing" /* Missing */);
            }
            else {
                // Check and see if the symbol table already has a symbol with this name.  If not,
                // create a new symbol with this name and add it to the table.  Note that we don't
                // give the new symbol any flags *yet*.  This ensures that it will not conflict
                // with the 'excludes' flags we pass in.
                //
                // If we do get an existing symbol, see if it conflicts with the new symbol we're
                // creating.  For example, a 'var' symbol and a 'class' symbol will conflict within
                // the same symbol table.  If we have a conflict, report the issue on each
                // declaration we have for this symbol, and then create a new symbol for this
                // declaration.
                //
                // Note that when properties declared in Javascript constructors
                // (marked by isReplaceableByMethod) conflict with another symbol, the property loses.
                // Always. This allows the common Javascript pattern of overwriting a prototype method
                // with an bound instance method of the same type: `this.method = this.method.bind(this)`
                //
                // If we created a new symbol, either because we didn't have a symbol with this name
                // in the symbol table, or we conflicted with an existing symbol, then just add this
                // node as the sole declaration of the new symbol.
                //
                // Otherwise, we'll be merging into a compatible existing symbol (for example when
                // you have multiple 'vars' with the same name in the same container).  In this case
                // just add this node into the declarations list of the symbol.
                symbol = symbolTable.get(name);
                if (includes & 2885600 /* Classifiable */) {
                    classifiableNames.set(name, true);
                }
                if (!symbol) {
                    symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
                    if (isReplaceableByMethod)
                        symbol.isReplaceableByMethod = true;
                }
                else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) {
                    // A symbol already exists, so don't add this as a declaration.
                    return symbol;
                }
                else if (symbol.flags & excludes) {
                    if (symbol.isReplaceableByMethod) {
                        // Javascript constructor-declared symbols can be discarded in favor of
                        // prototype symbols like methods.
                        symbolTable.set(name, symbol = createSymbol(0 /* None */, name));
                    }
                    else if (!(includes & 3 /* Variable */ && symbol.flags & 67108864 /* Assignment */)) {
                        // Assignment declarations are allowed to merge with variables, no matter what other flags they have.
                        if (ts.isNamedDeclaration(node)) {
                            node.name.parent = node;
                        }
                        // Report errors every position with duplicate declaration
                        // Report errors on previous encountered declarations
                        var message_1 = symbol.flags & 2 /* BlockScopedVariable */
                            ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
                            : ts.Diagnostics.Duplicate_identifier_0;
                        var messageNeedsName_1 = true;
                        if (symbol.flags & 384 /* Enum */ || includes & 384 /* Enum */) {
                            message_1 = ts.Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations;
                            messageNeedsName_1 = false;
                        }
                        var multipleDefaultExports_1 = false;
                        if (ts.length(symbol.declarations)) {
                            // If the current node is a default export of some sort, then check if
                            // there are any other default exports that we need to error on.
                            // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set.
                            if (isDefaultExport) {
                                message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                                messageNeedsName_1 = false;
                                multipleDefaultExports_1 = true;
                            }
                            else {
                                // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration.
                                // Error on multiple export default in the following case:
                                // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default
                                // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers)
                                if (symbol.declarations && symbol.declarations.length &&
                                    (node.kind === 259 /* ExportAssignment */ && !node.isExportEquals)) {
                                    message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports;
                                    messageNeedsName_1 = false;
                                    multipleDefaultExports_1 = true;
                                }
                            }
                        }
                        var relatedInformation_1 = [];
                        if (ts.isTypeAliasDeclaration(node) && ts.nodeIsMissing(node.type) && ts.hasModifier(node, 1 /* Export */) && symbol.flags & (2097152 /* Alias */ | 788968 /* Type */ | 1920 /* Namespace */)) {
                            // export type T; - may have meant export type { T }?
                            relatedInformation_1.push(createDiagnosticForNode(node, ts.Diagnostics.Did_you_mean_0, "export type { " + ts.unescapeLeadingUnderscores(node.name.escapedText) + " }"));
                        }
                        var declarationName_1 = ts.getNameOfDeclaration(node) || node;
                        ts.forEach(symbol.declarations, function (declaration, index) {
                            var decl = ts.getNameOfDeclaration(declaration) || declaration;
                            var diag = createDiagnosticForNode(decl, message_1, messageNeedsName_1 ? getDisplayName(declaration) : undefined);
                            file.bindDiagnostics.push(multipleDefaultExports_1 ? ts.addRelatedInfo(diag, createDiagnosticForNode(declarationName_1, index === 0 ? ts.Diagnostics.Another_export_default_is_here : ts.Diagnostics.and_here)) : diag);
                            if (multipleDefaultExports_1) {
                                relatedInformation_1.push(createDiagnosticForNode(decl, ts.Diagnostics.The_first_export_default_is_here));
                            }
                        });
                        var diag = createDiagnosticForNode(declarationName_1, message_1, messageNeedsName_1 ? getDisplayName(node) : undefined);
                        file.bindDiagnostics.push(ts.addRelatedInfo.apply(void 0, __spreadArrays([diag], relatedInformation_1)));
                        symbol = createSymbol(0 /* None */, name);
                    }
                }
            }
            addDeclarationToSymbol(symbol, node, includes);
            if (symbol.parent) {
                ts.Debug.assert(symbol.parent === parent, "Existing symbol parent should match new one");
            }
            else {
                symbol.parent = parent;
            }
            return symbol;
        }
        function declareModuleMember(node, symbolFlags, symbolExcludes) {
            var hasExportModifier = ts.getCombinedModifierFlags(node) & 1 /* Export */;
            if (symbolFlags & 2097152 /* Alias */) {
                if (node.kind === 263 /* ExportSpecifier */ || (node.kind === 253 /* ImportEqualsDeclaration */ && hasExportModifier)) {
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                }
                else {
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
                }
            }
            else {
                // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue flag,
                // and an associated export symbol with all the correct flags set on it. There are 2 main reasons:
                //
                //   1. We treat locals and exports of the same name as mutually exclusive within a container.
                //      That means the binder will issue a Duplicate Identifier error if you mix locals and exports
                //      with the same name in the same container.
                //      TODO: Make this a more specific error and decouple it from the exclusion logic.
                //   2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol,
                //      but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way
                //      when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope.
                // NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge
                //       during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
                //       and this case is specially handled. Module augmentations should only be merged with original module definition
                //       and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
                if (ts.isJSDocTypeAlias(node))
                    ts.Debug.assert(ts.isInJSFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file.
                if ((!ts.isAmbientModule(node) && (hasExportModifier || container.flags & 64 /* ExportContext */)) || ts.isJSDocTypeAlias(node)) {
                    if (!container.locals || (ts.hasModifier(node, 512 /* Default */) && !getDeclarationName(node))) {
                        return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default!
                    }
                    var exportKind = symbolFlags & 111551 /* Value */ ? 1048576 /* ExportValue */ : 0;
                    var local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
                    local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                    node.localSymbol = local;
                    return local;
                }
                else {
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
                }
            }
        }
        // All container nodes are kept on a linked list in declaration order. This list is used by
        // the getLocalNameOfContainer function in the type checker to validate that the local name
        // used for a container is unique.
        function bindContainer(node, containerFlags) {
            // Before we recurse into a node's children, we first save the existing parent, container
            // and block-container.  Then after we pop out of processing the children, we restore
            // these saved values.
            var saveContainer = container;
            var saveThisParentContainer = thisParentContainer;
            var savedBlockScopeContainer = blockScopeContainer;
            // Depending on what kind of node this is, we may have to adjust the current container
            // and block-container.   If the current node is a container, then it is automatically
            // considered the current block-container as well.  Also, for containers that we know
            // may contain locals, we eagerly initialize the .locals field. We do this because
            // it's highly likely that the .locals will be needed to place some child in (for example,
            // a parameter, or variable declaration).
            //
            // However, we do not proactively create the .locals for block-containers because it's
            // totally normal and common for block-containers to never actually have a block-scoped
            // variable in them.  We don't want to end up allocating an object for every 'block' we
            // run into when most of them won't be necessary.
            //
            // Finally, if this is a block-container, then we clear out any existing .locals object
            // it may contain within it.  This happens in incremental scenarios.  Because we can be
            // reusing a node from a previous compilation, that node may have had 'locals' created
            // for it.  We must clear this so we don't accidentally move any stale data forward from
            // a previous compilation.
            if (containerFlags & 1 /* IsContainer */) {
                if (node.kind !== 202 /* ArrowFunction */) {
                    thisParentContainer = container;
                }
                container = blockScopeContainer = node;
                if (containerFlags & 32 /* HasLocals */) {
                    container.locals = ts.createSymbolTable();
                }
                addToContainerChain(container);
            }
            else if (containerFlags & 2 /* IsBlockScopedContainer */) {
                blockScopeContainer = node;
                blockScopeContainer.locals = undefined;
            }
            if (containerFlags & 4 /* IsControlFlowContainer */) {
                var saveCurrentFlow = currentFlow;
                var saveBreakTarget = currentBreakTarget;
                var saveContinueTarget = currentContinueTarget;
                var saveReturnTarget = currentReturnTarget;
                var saveExceptionTarget = currentExceptionTarget;
                var saveActiveLabelList = activeLabelList;
                var saveHasExplicitReturn = hasExplicitReturn;
                var isIIFE = containerFlags & 16 /* IsFunctionExpression */ && !ts.hasModifier(node, 256 /* Async */) &&
                    !node.asteriskToken && !!ts.getImmediatelyInvokedFunctionExpression(node);
                // A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave
                // similarly to break statements that exit to a label just past the statement body.
                if (!isIIFE) {
                    currentFlow = initFlowNode({ flags: 2 /* Start */ });
                    if (containerFlags & (16 /* IsFunctionExpression */ | 128 /* IsObjectLiteralOrClassExpressionMethod */)) {
                        currentFlow.node = node;
                    }
                }
                // We create a return control flow graph for IIFEs and constructors. For constructors
                // we use the return control flow graph in strict property initialization checks.
                currentReturnTarget = isIIFE || node.kind === 162 /* Constructor */ ? createBranchLabel() : undefined;
                currentExceptionTarget = undefined;
                currentBreakTarget = undefined;
                currentContinueTarget = undefined;
                activeLabelList = undefined;
                hasExplicitReturn = false;
                bindChildren(node);
                // Reset all reachability check related flags on node (for incremental scenarios)
                node.flags &= ~2816 /* ReachabilityAndEmitFlags */;
                if (!(currentFlow.flags & 1 /* Unreachable */) && containerFlags & 8 /* IsFunctionLike */ && ts.nodeIsPresent(node.body)) {
                    node.flags |= 256 /* HasImplicitReturn */;
                    if (hasExplicitReturn)
                        node.flags |= 512 /* HasExplicitReturn */;
                    node.endFlowNode = currentFlow;
                }
                if (node.kind === 290 /* SourceFile */) {
                    node.flags |= emitFlags;
                }
                if (currentReturnTarget) {
                    addAntecedent(currentReturnTarget, currentFlow);
                    currentFlow = finishFlowLabel(currentReturnTarget);
                    if (node.kind === 162 /* Constructor */) {
                        node.returnFlowNode = currentFlow;
                    }
                }
                if (!isIIFE) {
                    currentFlow = saveCurrentFlow;
                }
                currentBreakTarget = saveBreakTarget;
                currentContinueTarget = saveContinueTarget;
                currentReturnTarget = saveReturnTarget;
                currentExceptionTarget = saveExceptionTarget;
                activeLabelList = saveActiveLabelList;
                hasExplicitReturn = saveHasExplicitReturn;
            }
            else if (containerFlags & 64 /* IsInterface */) {
                seenThisKeyword = false;
                bindChildren(node);
                node.flags = seenThisKeyword ? node.flags | 128 /* ContainsThis */ : node.flags & ~128 /* ContainsThis */;
            }
            else {
                bindChildren(node);
            }
            container = saveContainer;
            thisParentContainer = saveThisParentContainer;
            blockScopeContainer = savedBlockScopeContainer;
        }
        function bindChildren(node) {
            if (skipTransformFlagAggregation) {
                bindChildrenWorker(node);
            }
            else if (node.transformFlags & 536870912 /* HasComputedFlags */) {
                skipTransformFlagAggregation = true;
                bindChildrenWorker(node);
                skipTransformFlagAggregation = false;
                subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
            }
            else {
                var savedSubtreeTransformFlags = subtreeTransformFlags;
                subtreeTransformFlags = 0;
                bindChildrenWorker(node);
                subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags);
            }
        }
        function bindEachFunctionsFirst(nodes) {
            bindEach(nodes, function (n) { return n.kind === 244 /* FunctionDeclaration */ ? bind(n) : undefined; });
            bindEach(nodes, function (n) { return n.kind !== 244 /* FunctionDeclaration */ ? bind(n) : undefined; });
        }
        function bindEach(nodes, bindFunction) {
            if (bindFunction === void 0) { bindFunction = bind; }
            if (nodes === undefined) {
                return;
            }
            if (skipTransformFlagAggregation) {
                ts.forEach(nodes, bindFunction);
            }
            else {
                var savedSubtreeTransformFlags = subtreeTransformFlags;
                subtreeTransformFlags = 0 /* None */;
                var nodeArrayFlags = 0 /* None */;
                for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
                    var node = nodes_2[_i];
                    bindFunction(node);
                    nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
                }
                nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
                subtreeTransformFlags |= savedSubtreeTransformFlags;
            }
        }
        function bindEachChild(node) {
            ts.forEachChild(node, bind, bindEach);
        }
        function bindChildrenWorker(node) {
            if (checkUnreachable(node)) {
                bindEachChild(node);
                bindJSDoc(node);
                return;
            }
            if (node.kind >= 225 /* FirstStatement */ && node.kind <= 241 /* LastStatement */ && !options.allowUnreachableCode) {
                node.flowNode = currentFlow;
            }
            switch (node.kind) {
                case 229 /* WhileStatement */:
                    bindWhileStatement(node);
                    break;
                case 228 /* DoStatement */:
                    bindDoStatement(node);
                    break;
                case 230 /* ForStatement */:
                    bindForStatement(node);
                    break;
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                    bindForInOrForOfStatement(node);
                    break;
                case 227 /* IfStatement */:
                    bindIfStatement(node);
                    break;
                case 235 /* ReturnStatement */:
                case 239 /* ThrowStatement */:
                    bindReturnOrThrow(node);
                    break;
                case 234 /* BreakStatement */:
                case 233 /* ContinueStatement */:
                    bindBreakOrContinueStatement(node);
                    break;
                case 240 /* TryStatement */:
                    bindTryStatement(node);
                    break;
                case 237 /* SwitchStatement */:
                    bindSwitchStatement(node);
                    break;
                case 251 /* CaseBlock */:
                    bindCaseBlock(node);
                    break;
                case 277 /* CaseClause */:
                    bindCaseClause(node);
                    break;
                case 226 /* ExpressionStatement */:
                    bindExpressionStatement(node);
                    break;
                case 238 /* LabeledStatement */:
                    bindLabeledStatement(node);
                    break;
                case 207 /* PrefixUnaryExpression */:
                    bindPrefixUnaryExpressionFlow(node);
                    break;
                case 208 /* PostfixUnaryExpression */:
                    bindPostfixUnaryExpressionFlow(node);
                    break;
                case 209 /* BinaryExpression */:
                    bindBinaryExpressionFlow(node);
                    break;
                case 203 /* DeleteExpression */:
                    bindDeleteExpressionFlow(node);
                    break;
                case 210 /* ConditionalExpression */:
                    bindConditionalExpressionFlow(node);
                    break;
                case 242 /* VariableDeclaration */:
                    bindVariableDeclarationFlow(node);
                    break;
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    bindAccessExpressionFlow(node);
                    break;
                case 196 /* CallExpression */:
                    bindCallExpressionFlow(node);
                    break;
                case 218 /* NonNullExpression */:
                    bindNonNullExpressionFlow(node);
                    break;
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 316 /* JSDocEnumTag */:
                    bindJSDocTypeAlias(node);
                    break;
                // In source files and blocks, bind functions first to match hoisting that occurs at runtime
                case 290 /* SourceFile */: {
                    bindEachFunctionsFirst(node.statements);
                    bind(node.endOfFileToken);
                    break;
                }
                case 223 /* Block */:
                case 250 /* ModuleBlock */:
                    bindEachFunctionsFirst(node.statements);
                    break;
                default:
                    bindEachChild(node);
                    break;
            }
            bindJSDoc(node);
        }
        function isNarrowingExpression(expr) {
            switch (expr.kind) {
                case 75 /* Identifier */:
                case 104 /* ThisKeyword */:
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    return containsNarrowableReference(expr);
                case 196 /* CallExpression */:
                    return hasNarrowableArgument(expr);
                case 200 /* ParenthesizedExpression */:
                    return isNarrowingExpression(expr.expression);
                case 209 /* BinaryExpression */:
                    return isNarrowingBinaryExpression(expr);
                case 207 /* PrefixUnaryExpression */:
                    return expr.operator === 53 /* ExclamationToken */ && isNarrowingExpression(expr.operand);
                case 204 /* TypeOfExpression */:
                    return isNarrowingExpression(expr.expression);
            }
            return false;
        }
        function isNarrowableReference(expr) {
            return expr.kind === 75 /* Identifier */ || expr.kind === 104 /* ThisKeyword */ || expr.kind === 102 /* SuperKeyword */ ||
                (ts.isPropertyAccessExpression(expr) || ts.isNonNullExpression(expr) || ts.isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) ||
                ts.isElementAccessExpression(expr) && ts.isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression);
        }
        function containsNarrowableReference(expr) {
            return isNarrowableReference(expr) || ts.isOptionalChain(expr) && containsNarrowableReference(expr.expression);
        }
        function hasNarrowableArgument(expr) {
            if (expr.arguments) {
                for (var _i = 0, _a = expr.arguments; _i < _a.length; _i++) {
                    var argument = _a[_i];
                    if (containsNarrowableReference(argument)) {
                        return true;
                    }
                }
            }
            if (expr.expression.kind === 194 /* PropertyAccessExpression */ &&
                containsNarrowableReference(expr.expression.expression)) {
                return true;
            }
            return false;
        }
        function isNarrowingTypeofOperands(expr1, expr2) {
            return ts.isTypeOfExpression(expr1) && isNarrowableOperand(expr1.expression) && ts.isStringLiteralLike(expr2);
        }
        function isNarrowableInOperands(left, right) {
            return ts.isStringLiteralLike(left) && isNarrowingExpression(right);
        }
        function isNarrowingBinaryExpression(expr) {
            switch (expr.operatorToken.kind) {
                case 62 /* EqualsToken */:
                    return containsNarrowableReference(expr.left);
                case 34 /* EqualsEqualsToken */:
                case 35 /* ExclamationEqualsToken */:
                case 36 /* EqualsEqualsEqualsToken */:
                case 37 /* ExclamationEqualsEqualsToken */:
                    return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) ||
                        isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
                case 98 /* InstanceOfKeyword */:
                    return isNarrowableOperand(expr.left);
                case 97 /* InKeyword */:
                    return isNarrowableInOperands(expr.left, expr.right);
                case 27 /* CommaToken */:
                    return isNarrowingExpression(expr.right);
            }
            return false;
        }
        function isNarrowableOperand(expr) {
            switch (expr.kind) {
                case 200 /* ParenthesizedExpression */:
                    return isNarrowableOperand(expr.expression);
                case 209 /* BinaryExpression */:
                    switch (expr.operatorToken.kind) {
                        case 62 /* EqualsToken */:
                            return isNarrowableOperand(expr.left);
                        case 27 /* CommaToken */:
                            return isNarrowableOperand(expr.right);
                    }
            }
            return containsNarrowableReference(expr);
        }
        function createBranchLabel() {
            return initFlowNode({ flags: 4 /* BranchLabel */, antecedents: undefined });
        }
        function createLoopLabel() {
            return initFlowNode({ flags: 8 /* LoopLabel */, antecedents: undefined });
        }
        function createReduceLabel(target, antecedents, antecedent) {
            return initFlowNode({ flags: 1024 /* ReduceLabel */, target: target, antecedents: antecedents, antecedent: antecedent });
        }
        function setFlowNodeReferenced(flow) {
            // On first reference we set the Referenced flag, thereafter we set the Shared flag
            flow.flags |= flow.flags & 2048 /* Referenced */ ? 4096 /* Shared */ : 2048 /* Referenced */;
        }
        function addAntecedent(label, antecedent) {
            if (!(antecedent.flags & 1 /* Unreachable */) && !ts.contains(label.antecedents, antecedent)) {
                (label.antecedents || (label.antecedents = [])).push(antecedent);
                setFlowNodeReferenced(antecedent);
            }
        }
        function createFlowCondition(flags, antecedent, expression) {
            if (antecedent.flags & 1 /* Unreachable */) {
                return antecedent;
            }
            if (!expression) {
                return flags & 32 /* TrueCondition */ ? antecedent : unreachableFlow;
            }
            if ((expression.kind === 106 /* TrueKeyword */ && flags & 64 /* FalseCondition */ ||
                expression.kind === 91 /* FalseKeyword */ && flags & 32 /* TrueCondition */) &&
                !ts.isExpressionOfOptionalChainRoot(expression) && !ts.isNullishCoalesce(expression.parent)) {
                return unreachableFlow;
            }
            if (!isNarrowingExpression(expression)) {
                return antecedent;
            }
            setFlowNodeReferenced(antecedent);
            return initFlowNode({ flags: flags, antecedent: antecedent, node: expression });
        }
        function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) {
            setFlowNodeReferenced(antecedent);
            return initFlowNode({ flags: 128 /* SwitchClause */, antecedent: antecedent, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd });
        }
        function createFlowMutation(flags, antecedent, node) {
            setFlowNodeReferenced(antecedent);
            var result = initFlowNode({ flags: flags, antecedent: antecedent, node: node });
            if (currentExceptionTarget) {
                addAntecedent(currentExceptionTarget, result);
            }
            return result;
        }
        function createFlowCall(antecedent, node) {
            setFlowNodeReferenced(antecedent);
            return initFlowNode({ flags: 512 /* Call */, antecedent: antecedent, node: node });
        }
        function finishFlowLabel(flow) {
            var antecedents = flow.antecedents;
            if (!antecedents) {
                return unreachableFlow;
            }
            if (antecedents.length === 1) {
                return antecedents[0];
            }
            return flow;
        }
        function isStatementCondition(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 227 /* IfStatement */:
                case 229 /* WhileStatement */:
                case 228 /* DoStatement */:
                    return parent.expression === node;
                case 230 /* ForStatement */:
                case 210 /* ConditionalExpression */:
                    return parent.condition === node;
            }
            return false;
        }
        function isLogicalExpression(node) {
            while (true) {
                if (node.kind === 200 /* ParenthesizedExpression */) {
                    node = node.expression;
                }
                else if (node.kind === 207 /* PrefixUnaryExpression */ && node.operator === 53 /* ExclamationToken */) {
                    node = node.operand;
                }
                else {
                    return node.kind === 209 /* BinaryExpression */ && (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */ ||
                        node.operatorToken.kind === 56 /* BarBarToken */ ||
                        node.operatorToken.kind === 60 /* QuestionQuestionToken */);
                }
            }
        }
        function isTopLevelLogicalExpression(node) {
            while (ts.isParenthesizedExpression(node.parent) ||
                ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === 53 /* ExclamationToken */) {
                node = node.parent;
            }
            return !isStatementCondition(node) &&
                !isLogicalExpression(node.parent) &&
                !(ts.isOptionalChain(node.parent) && node.parent.expression === node);
        }
        function doWithConditionalBranches(action, value, trueTarget, falseTarget) {
            var savedTrueTarget = currentTrueTarget;
            var savedFalseTarget = currentFalseTarget;
            currentTrueTarget = trueTarget;
            currentFalseTarget = falseTarget;
            action(value);
            currentTrueTarget = savedTrueTarget;
            currentFalseTarget = savedFalseTarget;
        }
        function bindCondition(node, trueTarget, falseTarget) {
            doWithConditionalBranches(bind, node, trueTarget, falseTarget);
            if (!node || !isLogicalExpression(node) && !(ts.isOptionalChain(node) && ts.isOutermostOptionalChain(node))) {
                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
            }
        }
        function bindIterativeStatement(node, breakTarget, continueTarget) {
            var saveBreakTarget = currentBreakTarget;
            var saveContinueTarget = currentContinueTarget;
            currentBreakTarget = breakTarget;
            currentContinueTarget = continueTarget;
            bind(node);
            currentBreakTarget = saveBreakTarget;
            currentContinueTarget = saveContinueTarget;
        }
        function setContinueTarget(node, target) {
            var label = activeLabelList;
            while (label && node.parent.kind === 238 /* LabeledStatement */) {
                label.continueTarget = target;
                label = label.next;
                node = node.parent;
            }
            return target;
        }
        function bindWhileStatement(node) {
            var preWhileLabel = setContinueTarget(node, createLoopLabel());
            var preBodyLabel = createBranchLabel();
            var postWhileLabel = createBranchLabel();
            addAntecedent(preWhileLabel, currentFlow);
            currentFlow = preWhileLabel;
            bindCondition(node.expression, preBodyLabel, postWhileLabel);
            currentFlow = finishFlowLabel(preBodyLabel);
            bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel);
            addAntecedent(preWhileLabel, currentFlow);
            currentFlow = finishFlowLabel(postWhileLabel);
        }
        function bindDoStatement(node) {
            var preDoLabel = createLoopLabel();
            var preConditionLabel = setContinueTarget(node, createBranchLabel());
            var postDoLabel = createBranchLabel();
            addAntecedent(preDoLabel, currentFlow);
            currentFlow = preDoLabel;
            bindIterativeStatement(node.statement, postDoLabel, preConditionLabel);
            addAntecedent(preConditionLabel, currentFlow);
            currentFlow = finishFlowLabel(preConditionLabel);
            bindCondition(node.expression, preDoLabel, postDoLabel);
            currentFlow = finishFlowLabel(postDoLabel);
        }
        function bindForStatement(node) {
            var preLoopLabel = setContinueTarget(node, createLoopLabel());
            var preBodyLabel = createBranchLabel();
            var postLoopLabel = createBranchLabel();
            bind(node.initializer);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = preLoopLabel;
            bindCondition(node.condition, preBodyLabel, postLoopLabel);
            currentFlow = finishFlowLabel(preBodyLabel);
            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
            bind(node.incrementor);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = finishFlowLabel(postLoopLabel);
        }
        function bindForInOrForOfStatement(node) {
            var preLoopLabel = setContinueTarget(node, createLoopLabel());
            var postLoopLabel = createBranchLabel();
            bind(node.expression);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = preLoopLabel;
            if (node.kind === 232 /* ForOfStatement */) {
                bind(node.awaitModifier);
            }
            addAntecedent(postLoopLabel, currentFlow);
            bind(node.initializer);
            if (node.initializer.kind !== 243 /* VariableDeclarationList */) {
                bindAssignmentTargetFlow(node.initializer);
            }
            bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel);
            addAntecedent(preLoopLabel, currentFlow);
            currentFlow = finishFlowLabel(postLoopLabel);
        }
        function bindIfStatement(node) {
            var thenLabel = createBranchLabel();
            var elseLabel = createBranchLabel();
            var postIfLabel = createBranchLabel();
            bindCondition(node.expression, thenLabel, elseLabel);
            currentFlow = finishFlowLabel(thenLabel);
            bind(node.thenStatement);
            addAntecedent(postIfLabel, currentFlow);
            currentFlow = finishFlowLabel(elseLabel);
            bind(node.elseStatement);
            addAntecedent(postIfLabel, currentFlow);
            currentFlow = finishFlowLabel(postIfLabel);
        }
        function bindReturnOrThrow(node) {
            bind(node.expression);
            if (node.kind === 235 /* ReturnStatement */) {
                hasExplicitReturn = true;
                if (currentReturnTarget) {
                    addAntecedent(currentReturnTarget, currentFlow);
                }
            }
            currentFlow = unreachableFlow;
        }
        function findActiveLabel(name) {
            for (var label = activeLabelList; label; label = label.next) {
                if (label.name === name) {
                    return label;
                }
            }
            return undefined;
        }
        function bindBreakOrContinueFlow(node, breakTarget, continueTarget) {
            var flowLabel = node.kind === 234 /* BreakStatement */ ? breakTarget : continueTarget;
            if (flowLabel) {
                addAntecedent(flowLabel, currentFlow);
                currentFlow = unreachableFlow;
            }
        }
        function bindBreakOrContinueStatement(node) {
            bind(node.label);
            if (node.label) {
                var activeLabel = findActiveLabel(node.label.escapedText);
                if (activeLabel) {
                    activeLabel.referenced = true;
                    bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
                }
            }
            else {
                bindBreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget);
            }
        }
        function bindTryStatement(node) {
            // We conservatively assume that *any* code in the try block can cause an exception, but we only need
            // to track code that causes mutations (because only mutations widen the possible control flow type of
            // a variable). The exceptionLabel is the target label for control flows that result from exceptions.
            // We add all mutation flow nodes as antecedents of this label such that we can analyze them as possible
            // antecedents of the start of catch or finally blocks. Furthermore, we add the current control flow to
            // represent exceptions that occur before any mutations.
            var saveReturnTarget = currentReturnTarget;
            var saveExceptionTarget = currentExceptionTarget;
            var normalExitLabel = createBranchLabel();
            var returnLabel = createBranchLabel();
            var exceptionLabel = createBranchLabel();
            if (node.finallyBlock) {
                currentReturnTarget = returnLabel;
            }
            addAntecedent(exceptionLabel, currentFlow);
            currentExceptionTarget = exceptionLabel;
            bind(node.tryBlock);
            addAntecedent(normalExitLabel, currentFlow);
            if (node.catchClause) {
                // Start of catch clause is the target of exceptions from try block.
                currentFlow = finishFlowLabel(exceptionLabel);
                // The currentExceptionTarget now represents control flows from exceptions in the catch clause.
                // Effectively, in a try-catch-finally, if an exception occurs in the try block, the catch block
                // acts like a second try block.
                exceptionLabel = createBranchLabel();
                addAntecedent(exceptionLabel, currentFlow);
                currentExceptionTarget = exceptionLabel;
                bind(node.catchClause);
                addAntecedent(normalExitLabel, currentFlow);
            }
            currentReturnTarget = saveReturnTarget;
            currentExceptionTarget = saveExceptionTarget;
            if (node.finallyBlock) {
                // Possible ways control can reach the finally block:
                // 1) Normal completion of try block of a try-finally or try-catch-finally
                // 2) Normal completion of catch block (following exception in try block) of a try-catch-finally
                // 3) Return in try or catch block of a try-finally or try-catch-finally
                // 4) Exception in try block of a try-finally
                // 5) Exception in catch block of a try-catch-finally
                // When analyzing a control flow graph that starts inside a finally block we want to consider all
                // five possibilities above. However, when analyzing a control flow graph that starts outside (past)
                // the finally block, we only want to consider the first two (if we're past a finally block then it
                // must have completed normally). Likewise, when analyzing a control flow graph from return statements
                // in try or catch blocks in an IIFE, we only want to consider the third. To make this possible, we
                // inject a ReduceLabel node into the control flow graph. This node contains an alternate reduced
                // set of antecedents for the pre-finally label. As control flow analysis passes by a ReduceLabel
                // node, the pre-finally label is temporarily switched to the reduced antecedent set.
                var finallyLabel = createBranchLabel();
                finallyLabel.antecedents = ts.concatenate(ts.concatenate(normalExitLabel.antecedents, exceptionLabel.antecedents), returnLabel.antecedents);
                currentFlow = finallyLabel;
                bind(node.finallyBlock);
                if (currentFlow.flags & 1 /* Unreachable */) {
                    // If the end of the finally block is unreachable, the end of the entire try statement is unreachable.
                    currentFlow = unreachableFlow;
                }
                else {
                    // If we have an IIFE return target and return statements in the try or catch blocks, add a control
                    // flow that goes back through the finally block and back through only the return statements.
                    if (currentReturnTarget && returnLabel.antecedents) {
                        addAntecedent(currentReturnTarget, createReduceLabel(finallyLabel, returnLabel.antecedents, currentFlow));
                    }
                    // If the end of the finally block is reachable, but the end of the try and catch blocks are not,
                    // convert the current flow to unreachable. For example, 'try { return 1; } finally { ... }' should
                    // result in an unreachable current control flow.
                    currentFlow = normalExitLabel.antecedents ? createReduceLabel(finallyLabel, normalExitLabel.antecedents, currentFlow) : unreachableFlow;
                }
            }
            else {
                currentFlow = finishFlowLabel(normalExitLabel);
            }
        }
        function bindSwitchStatement(node) {
            var postSwitchLabel = createBranchLabel();
            bind(node.expression);
            var saveBreakTarget = currentBreakTarget;
            var savePreSwitchCaseFlow = preSwitchCaseFlow;
            currentBreakTarget = postSwitchLabel;
            preSwitchCaseFlow = currentFlow;
            bind(node.caseBlock);
            addAntecedent(postSwitchLabel, currentFlow);
            var hasDefault = ts.forEach(node.caseBlock.clauses, function (c) { return c.kind === 278 /* DefaultClause */; });
            // We mark a switch statement as possibly exhaustive if it has no default clause and if all
            // case clauses have unreachable end points (e.g. they all return). Note, we no longer need
            // this property in control flow analysis, it's there only for backwards compatibility.
            node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents;
            if (!hasDefault) {
                addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0));
            }
            currentBreakTarget = saveBreakTarget;
            preSwitchCaseFlow = savePreSwitchCaseFlow;
            currentFlow = finishFlowLabel(postSwitchLabel);
        }
        function bindCaseBlock(node) {
            var savedSubtreeTransformFlags = subtreeTransformFlags;
            subtreeTransformFlags = 0;
            var clauses = node.clauses;
            var isNarrowingSwitch = isNarrowingExpression(node.parent.expression);
            var fallthroughFlow = unreachableFlow;
            for (var i = 0; i < clauses.length; i++) {
                var clauseStart = i;
                while (!clauses[i].statements.length && i + 1 < clauses.length) {
                    bind(clauses[i]);
                    i++;
                }
                var preCaseLabel = createBranchLabel();
                addAntecedent(preCaseLabel, isNarrowingSwitch ? createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1) : preSwitchCaseFlow);
                addAntecedent(preCaseLabel, fallthroughFlow);
                currentFlow = finishFlowLabel(preCaseLabel);
                var clause = clauses[i];
                bind(clause);
                fallthroughFlow = currentFlow;
                if (!(currentFlow.flags & 1 /* Unreachable */) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) {
                    clause.fallthroughFlowNode = currentFlow;
                }
            }
            clauses.transformFlags = subtreeTransformFlags | 536870912 /* HasComputedFlags */;
            subtreeTransformFlags |= savedSubtreeTransformFlags;
        }
        function bindCaseClause(node) {
            var saveCurrentFlow = currentFlow;
            currentFlow = preSwitchCaseFlow;
            bind(node.expression);
            currentFlow = saveCurrentFlow;
            bindEach(node.statements);
        }
        function bindExpressionStatement(node) {
            bind(node.expression);
            // A top level call expression with a dotted function name and at least one argument
            // is potentially an assertion and is therefore included in the control flow.
            if (node.expression.kind === 196 /* CallExpression */) {
                var call = node.expression;
                if (ts.isDottedName(call.expression)) {
                    currentFlow = createFlowCall(currentFlow, call);
                }
            }
        }
        function bindLabeledStatement(node) {
            var postStatementLabel = createBranchLabel();
            activeLabelList = {
                next: activeLabelList,
                name: node.label.escapedText,
                breakTarget: postStatementLabel,
                continueTarget: undefined,
                referenced: false
            };
            bind(node.label);
            bind(node.statement);
            if (!activeLabelList.referenced && !options.allowUnusedLabels) {
                errorOrSuggestionOnNode(ts.unusedLabelIsError(options), node.label, ts.Diagnostics.Unused_label);
            }
            activeLabelList = activeLabelList.next;
            addAntecedent(postStatementLabel, currentFlow);
            currentFlow = finishFlowLabel(postStatementLabel);
        }
        function bindDestructuringTargetFlow(node) {
            if (node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 62 /* EqualsToken */) {
                bindAssignmentTargetFlow(node.left);
            }
            else {
                bindAssignmentTargetFlow(node);
            }
        }
        function bindAssignmentTargetFlow(node) {
            if (isNarrowableReference(node)) {
                currentFlow = createFlowMutation(16 /* Assignment */, currentFlow, node);
            }
            else if (node.kind === 192 /* ArrayLiteralExpression */) {
                for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                    var e = _a[_i];
                    if (e.kind === 213 /* SpreadElement */) {
                        bindAssignmentTargetFlow(e.expression);
                    }
                    else {
                        bindDestructuringTargetFlow(e);
                    }
                }
            }
            else if (node.kind === 193 /* ObjectLiteralExpression */) {
                for (var _b = 0, _c = node.properties; _b < _c.length; _b++) {
                    var p = _c[_b];
                    if (p.kind === 281 /* PropertyAssignment */) {
                        bindDestructuringTargetFlow(p.initializer);
                    }
                    else if (p.kind === 282 /* ShorthandPropertyAssignment */) {
                        bindAssignmentTargetFlow(p.name);
                    }
                    else if (p.kind === 283 /* SpreadAssignment */) {
                        bindAssignmentTargetFlow(p.expression);
                    }
                }
            }
        }
        function bindLogicalExpression(node, trueTarget, falseTarget) {
            var preRightLabel = createBranchLabel();
            if (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */) {
                bindCondition(node.left, preRightLabel, falseTarget);
            }
            else {
                bindCondition(node.left, trueTarget, preRightLabel);
            }
            currentFlow = finishFlowLabel(preRightLabel);
            bind(node.operatorToken);
            bindCondition(node.right, trueTarget, falseTarget);
        }
        function bindPrefixUnaryExpressionFlow(node) {
            if (node.operator === 53 /* ExclamationToken */) {
                var saveTrueTarget = currentTrueTarget;
                currentTrueTarget = currentFalseTarget;
                currentFalseTarget = saveTrueTarget;
                bindEachChild(node);
                currentFalseTarget = currentTrueTarget;
                currentTrueTarget = saveTrueTarget;
            }
            else {
                bindEachChild(node);
                if (node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */) {
                    bindAssignmentTargetFlow(node.operand);
                }
            }
        }
        function bindPostfixUnaryExpressionFlow(node) {
            bindEachChild(node);
            if (node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */) {
                bindAssignmentTargetFlow(node.operand);
            }
        }
        var BindBinaryExpressionFlowState;
        (function (BindBinaryExpressionFlowState) {
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["BindThenBindChildren"] = 0] = "BindThenBindChildren";
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["MaybeBindLeft"] = 1] = "MaybeBindLeft";
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["BindToken"] = 2] = "BindToken";
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["BindRight"] = 3] = "BindRight";
            BindBinaryExpressionFlowState[BindBinaryExpressionFlowState["FinishBind"] = 4] = "FinishBind";
        })(BindBinaryExpressionFlowState || (BindBinaryExpressionFlowState = {}));
        function bindBinaryExpressionFlow(node) {
            var workStacks = {
                expr: [node],
                state: [1 /* MaybeBindLeft */],
                inStrictMode: [undefined],
                parent: [undefined],
                subtreeFlags: [undefined]
            };
            var stackIndex = 0;
            while (stackIndex >= 0) {
                node = workStacks.expr[stackIndex];
                switch (workStacks.state[stackIndex]) {
                    case 0 /* BindThenBindChildren */: {
                        // This state is used only when recuring, to emulate the work that `bind` does before
                        // reaching `bindChildren`. A normal call to `bindBinaryExpressionFlow` will already have done this work.
                        node.parent = parent;
                        var saveInStrictMode = inStrictMode;
                        bindWorker(node);
                        var saveParent = parent;
                        parent = node;
                        var subtreeFlagsState = void 0;
                        // While this next part does the work of `bindChildren` before it descends into `bindChildrenWorker`
                        // and uses `subtreeFlagsState` to queue up the work that needs to be done once the node is bound.
                        if (skipTransformFlagAggregation) {
                            // do nothing extra
                        }
                        else if (node.transformFlags & 536870912 /* HasComputedFlags */) {
                            skipTransformFlagAggregation = true;
                            subtreeFlagsState = -1;
                        }
                        else {
                            var savedSubtreeTransformFlags = subtreeTransformFlags;
                            subtreeTransformFlags = 0;
                            subtreeFlagsState = savedSubtreeTransformFlags;
                        }
                        advanceState(1 /* MaybeBindLeft */, saveInStrictMode, saveParent, subtreeFlagsState);
                        break;
                    }
                    case 1 /* MaybeBindLeft */: {
                        var operator = node.operatorToken.kind;
                        // TODO: bindLogicalExpression is recursive - if we want to handle deeply nested `&&` expressions
                        // we'll need to handle the `bindLogicalExpression` scenarios in this state machine, too
                        // For now, though, since the common cases are chained `+`, leaving it recursive is fine
                        if (operator === 55 /* AmpersandAmpersandToken */ || operator === 56 /* BarBarToken */ || operator === 60 /* QuestionQuestionToken */) {
                            if (isTopLevelLogicalExpression(node)) {
                                var postExpressionLabel = createBranchLabel();
                                bindLogicalExpression(node, postExpressionLabel, postExpressionLabel);
                                currentFlow = finishFlowLabel(postExpressionLabel);
                            }
                            else {
                                bindLogicalExpression(node, currentTrueTarget, currentFalseTarget);
                            }
                            completeNode();
                        }
                        else {
                            advanceState(2 /* BindToken */);
                            maybeBind(node.left);
                        }
                        break;
                    }
                    case 2 /* BindToken */: {
                        advanceState(3 /* BindRight */);
                        maybeBind(node.operatorToken);
                        break;
                    }
                    case 3 /* BindRight */: {
                        advanceState(4 /* FinishBind */);
                        maybeBind(node.right);
                        break;
                    }
                    case 4 /* FinishBind */: {
                        var operator = node.operatorToken.kind;
                        if (ts.isAssignmentOperator(operator) && !ts.isAssignmentTarget(node)) {
                            bindAssignmentTargetFlow(node.left);
                            if (operator === 62 /* EqualsToken */ && node.left.kind === 195 /* ElementAccessExpression */) {
                                var elementAccess = node.left;
                                if (isNarrowableOperand(elementAccess.expression)) {
                                    currentFlow = createFlowMutation(256 /* ArrayMutation */, currentFlow, node);
                                }
                            }
                        }
                        completeNode();
                        break;
                    }
                    default: return ts.Debug.fail("Invalid state " + workStacks.state[stackIndex] + " for bindBinaryExpressionFlow");
                }
            }
            /**
             * Note that `advanceState` sets the _current_ head state, and that `maybeBind` potentially pushes on a new
             * head state; so `advanceState` must be called before any `maybeBind` during a state's execution.
             */
            function advanceState(state, isInStrictMode, parent, subtreeFlags) {
                workStacks.state[stackIndex] = state;
                if (isInStrictMode !== undefined) {
                    workStacks.inStrictMode[stackIndex] = isInStrictMode;
                }
                if (parent !== undefined) {
                    workStacks.parent[stackIndex] = parent;
                }
                if (subtreeFlags !== undefined) {
                    workStacks.subtreeFlags[stackIndex] = subtreeFlags;
                }
            }
            function completeNode() {
                if (workStacks.inStrictMode[stackIndex] !== undefined) {
                    if (workStacks.subtreeFlags[stackIndex] === -1) {
                        skipTransformFlagAggregation = false;
                        subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
                    }
                    else if (workStacks.subtreeFlags[stackIndex] !== undefined) {
                        subtreeTransformFlags = workStacks.subtreeFlags[stackIndex] | computeTransformFlagsForNode(node, subtreeTransformFlags);
                    }
                    inStrictMode = workStacks.inStrictMode[stackIndex];
                    parent = workStacks.parent[stackIndex];
                }
                stackIndex--;
            }
            /**
             * If `node` is a BinaryExpression, adds it to the local work stack, otherwise recursively binds it
             */
            function maybeBind(node) {
                if (node && ts.isBinaryExpression(node)) {
                    stackIndex++;
                    workStacks.expr[stackIndex] = node;
                    workStacks.state[stackIndex] = 0 /* BindThenBindChildren */;
                    workStacks.inStrictMode[stackIndex] = undefined;
                    workStacks.parent[stackIndex] = undefined;
                    workStacks.subtreeFlags[stackIndex] = undefined;
                }
                else {
                    bind(node);
                }
            }
        }
        function bindDeleteExpressionFlow(node) {
            bindEachChild(node);
            if (node.expression.kind === 194 /* PropertyAccessExpression */) {
                bindAssignmentTargetFlow(node.expression);
            }
        }
        function bindConditionalExpressionFlow(node) {
            var trueLabel = createBranchLabel();
            var falseLabel = createBranchLabel();
            var postExpressionLabel = createBranchLabel();
            bindCondition(node.condition, trueLabel, falseLabel);
            currentFlow = finishFlowLabel(trueLabel);
            bind(node.questionToken);
            bind(node.whenTrue);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(falseLabel);
            bind(node.colonToken);
            bind(node.whenFalse);
            addAntecedent(postExpressionLabel, currentFlow);
            currentFlow = finishFlowLabel(postExpressionLabel);
        }
        function bindInitializedVariableFlow(node) {
            var name = !ts.isOmittedExpression(node) ? node.name : undefined;
            if (ts.isBindingPattern(name)) {
                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                    var child = _a[_i];
                    bindInitializedVariableFlow(child);
                }
            }
            else {
                currentFlow = createFlowMutation(16 /* Assignment */, currentFlow, node);
            }
        }
        function bindVariableDeclarationFlow(node) {
            bindEachChild(node);
            if (node.initializer || ts.isForInOrOfStatement(node.parent.parent)) {
                bindInitializedVariableFlow(node);
            }
        }
        function bindJSDocTypeAlias(node) {
            node.tagName.parent = node;
            if (node.kind !== 316 /* JSDocEnumTag */ && node.fullName) {
                setParentPointers(node, node.fullName);
            }
        }
        function bindJSDocClassTag(node) {
            bindEachChild(node);
            var host = ts.getHostSignatureFromJSDoc(node);
            if (host && host.kind !== 161 /* MethodDeclaration */) {
                addDeclarationToSymbol(host.symbol, host, 32 /* Class */);
            }
        }
        function bindOptionalExpression(node, trueTarget, falseTarget) {
            doWithConditionalBranches(bind, node, trueTarget, falseTarget);
            if (!ts.isOptionalChain(node) || ts.isOutermostOptionalChain(node)) {
                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
            }
        }
        function bindOptionalChainRest(node) {
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                    bind(node.questionDotToken);
                    bind(node.name);
                    break;
                case 195 /* ElementAccessExpression */:
                    bind(node.questionDotToken);
                    bind(node.argumentExpression);
                    break;
                case 196 /* CallExpression */:
                    bind(node.questionDotToken);
                    bindEach(node.typeArguments);
                    bindEach(node.arguments);
                    break;
            }
        }
        function bindOptionalChain(node, trueTarget, falseTarget) {
            // For an optional chain, we emulate the behavior of a logical expression:
            //
            // a?.b         -> a && a.b
            // a?.b.c       -> a && a.b.c
            // a?.b?.c      -> a && a.b && a.b.c
            // a?.[x = 1]   -> a && a[x = 1]
            //
            // To do this we descend through the chain until we reach the root of a chain (the expression with a `?.`)
            // and build it's CFA graph as if it were the first condition (`a && ...`). Then we bind the rest
            // of the node as part of the "true" branch, and continue to do so as we ascend back up to the outermost
            // chain node. We then treat the entire node as the right side of the expression.
            var preChainLabel = ts.isOptionalChainRoot(node) ? createBranchLabel() : undefined;
            bindOptionalExpression(node.expression, preChainLabel || trueTarget, falseTarget);
            if (preChainLabel) {
                currentFlow = finishFlowLabel(preChainLabel);
            }
            doWithConditionalBranches(bindOptionalChainRest, node, trueTarget, falseTarget);
            if (ts.isOutermostOptionalChain(node)) {
                addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node));
                addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node));
            }
        }
        function bindOptionalChainFlow(node) {
            if (isTopLevelLogicalExpression(node)) {
                var postExpressionLabel = createBranchLabel();
                bindOptionalChain(node, postExpressionLabel, postExpressionLabel);
                currentFlow = finishFlowLabel(postExpressionLabel);
            }
            else {
                bindOptionalChain(node, currentTrueTarget, currentFalseTarget);
            }
        }
        function bindNonNullExpressionFlow(node) {
            if (ts.isOptionalChain(node)) {
                bindOptionalChainFlow(node);
            }
            else {
                bindEachChild(node);
            }
        }
        function bindAccessExpressionFlow(node) {
            if (ts.isOptionalChain(node)) {
                bindOptionalChainFlow(node);
            }
            else {
                bindEachChild(node);
            }
        }
        function bindCallExpressionFlow(node) {
            if (ts.isOptionalChain(node)) {
                bindOptionalChainFlow(node);
            }
            else {
                // If the target of the call expression is a function expression or arrow function we have
                // an immediately invoked function expression (IIFE). Initialize the flowNode property to
                // the current control flow (which includes evaluation of the IIFE arguments).
                var expr = ts.skipParentheses(node.expression);
                if (expr.kind === 201 /* FunctionExpression */ || expr.kind === 202 /* ArrowFunction */) {
                    bindEach(node.typeArguments);
                    bindEach(node.arguments);
                    bind(node.expression);
                }
                else {
                    bindEachChild(node);
                }
            }
            if (node.expression.kind === 194 /* PropertyAccessExpression */) {
                var propertyAccess = node.expression;
                if (ts.isIdentifier(propertyAccess.name) && isNarrowableOperand(propertyAccess.expression) && ts.isPushOrUnshiftIdentifier(propertyAccess.name)) {
                    currentFlow = createFlowMutation(256 /* ArrayMutation */, currentFlow, node);
                }
            }
        }
        function getContainerFlags(node) {
            switch (node.kind) {
                case 214 /* ClassExpression */:
                case 245 /* ClassDeclaration */:
                case 248 /* EnumDeclaration */:
                case 193 /* ObjectLiteralExpression */:
                case 173 /* TypeLiteral */:
                case 304 /* JSDocTypeLiteral */:
                case 274 /* JsxAttributes */:
                    return 1 /* IsContainer */;
                case 246 /* InterfaceDeclaration */:
                    return 1 /* IsContainer */ | 64 /* IsInterface */;
                case 249 /* ModuleDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 186 /* MappedType */:
                    return 1 /* IsContainer */ | 32 /* HasLocals */;
                case 290 /* SourceFile */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */;
                case 161 /* MethodDeclaration */:
                    if (ts.isObjectLiteralOrClassExpressionMethod(node)) {
                        return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 128 /* IsObjectLiteralOrClassExpressionMethod */;
                    }
                // falls through
                case 162 /* Constructor */:
                case 244 /* FunctionDeclaration */:
                case 160 /* MethodSignature */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 165 /* CallSignature */:
                case 305 /* JSDocSignature */:
                case 300 /* JSDocFunctionType */:
                case 170 /* FunctionType */:
                case 166 /* ConstructSignature */:
                case 167 /* IndexSignature */:
                case 171 /* ConstructorType */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */;
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 16 /* IsFunctionExpression */;
                case 250 /* ModuleBlock */:
                    return 4 /* IsControlFlowContainer */;
                case 159 /* PropertyDeclaration */:
                    return node.initializer ? 4 /* IsControlFlowContainer */ : 0;
                case 280 /* CatchClause */:
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                case 251 /* CaseBlock */:
                    return 2 /* IsBlockScopedContainer */;
                case 223 /* Block */:
                    // do not treat blocks directly inside a function as a block-scoped-container.
                    // Locals that reside in this block should go to the function locals. Otherwise 'x'
                    // would not appear to be a redeclaration of a block scoped local in the following
                    // example:
                    //
                    //      function foo() {
                    //          var x;
                    //          let x;
                    //      }
                    //
                    // If we placed 'var x' into the function locals and 'let x' into the locals of
                    // the block, then there would be no collision.
                    //
                    // By not creating a new block-scoped-container here, we ensure that both 'var x'
                    // and 'let x' go into the Function-container's locals, and we do get a collision
                    // conflict.
                    return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */;
            }
            return 0 /* None */;
        }
        function addToContainerChain(next) {
            if (lastContainer) {
                lastContainer.nextContainer = next;
            }
            lastContainer = next;
        }
        function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) {
            switch (container.kind) {
                // Modules, source files, and classes need specialized handling for how their
                // members are declared (for example, a member of a class will go into a specific
                // symbol table depending on if it is static or not). We defer to specialized
                // handlers to take care of declaring these child members.
                case 249 /* ModuleDeclaration */:
                    return declareModuleMember(node, symbolFlags, symbolExcludes);
                case 290 /* SourceFile */:
                    return declareSourceFileMember(node, symbolFlags, symbolExcludes);
                case 214 /* ClassExpression */:
                case 245 /* ClassDeclaration */:
                    return declareClassMember(node, symbolFlags, symbolExcludes);
                case 248 /* EnumDeclaration */:
                    return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
                case 173 /* TypeLiteral */:
                case 304 /* JSDocTypeLiteral */:
                case 193 /* ObjectLiteralExpression */:
                case 246 /* InterfaceDeclaration */:
                case 274 /* JsxAttributes */:
                    // Interface/Object-types always have their children added to the 'members' of
                    // their container. They are only accessible through an instance of their
                    // container, and are never in scope otherwise (even inside the body of the
                    // object / type / interface declaring them). An exception is type parameters,
                    // which are in scope without qualification (similar to 'locals').
                    return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 305 /* JSDocSignature */:
                case 167 /* IndexSignature */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 162 /* Constructor */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 300 /* JSDocFunctionType */:
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 247 /* TypeAliasDeclaration */:
                case 186 /* MappedType */:
                    // All the children of these container types are never visible through another
                    // symbol (i.e. through another symbol's 'exports' or 'members').  Instead,
                    // they're only accessed 'lexically' (i.e. from code that exists underneath
                    // their container in the tree). To accomplish this, we simply add their declared
                    // symbol to the 'locals' of the container.  These symbols can then be found as
                    // the type checker walks up the containers, checking them for matching names.
                    return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
            }
        }
        function declareClassMember(node, symbolFlags, symbolExcludes) {
            return ts.hasModifier(node, 32 /* Static */)
                ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes)
                : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes);
        }
        function declareSourceFileMember(node, symbolFlags, symbolExcludes) {
            return ts.isExternalModule(file)
                ? declareModuleMember(node, symbolFlags, symbolExcludes)
                : declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
        }
        function hasExportDeclarations(node) {
            var body = ts.isSourceFile(node) ? node : ts.tryCast(node.body, ts.isModuleBlock);
            return !!body && body.statements.some(function (s) { return ts.isExportDeclaration(s) || ts.isExportAssignment(s); });
        }
        function setExportContextFlag(node) {
            // A declaration source file or ambient module declaration that contains no export declarations (but possibly regular
            // declarations with export modifiers) is an export context in which declarations are implicitly exported.
            if (node.flags & 8388608 /* Ambient */ && !hasExportDeclarations(node)) {
                node.flags |= 64 /* ExportContext */;
            }
            else {
                node.flags &= ~64 /* ExportContext */;
            }
        }
        function bindModuleDeclaration(node) {
            setExportContextFlag(node);
            if (ts.isAmbientModule(node)) {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    errorOnFirstToken(node, ts.Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible);
                }
                if (ts.isModuleAugmentationExternal(node)) {
                    declareModuleSymbol(node);
                }
                else {
                    var pattern = void 0;
                    if (node.name.kind === 10 /* StringLiteral */) {
                        var text = node.name.text;
                        if (ts.hasZeroOrOneAsteriskCharacter(text)) {
                            pattern = ts.tryParsePattern(text);
                        }
                        else {
                            errorOnFirstToken(node.name, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text);
                        }
                    }
                    var symbol = declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 110735 /* ValueModuleExcludes */);
                    file.patternAmbientModules = ts.append(file.patternAmbientModules, pattern && { pattern: pattern, symbol: symbol });
                }
            }
            else {
                var state = declareModuleSymbol(node);
                if (state !== 0 /* NonInstantiated */) {
                    var symbol = node.symbol;
                    // if module was already merged with some function, class or non-const enum, treat it as non-const-enum-only
                    symbol.constEnumOnlyModule = (!(symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */)))
                        // Current must be `const enum` only
                        && state === 2 /* ConstEnumOnly */
                        // Can't have been set to 'false' in a previous merged symbol. ('undefined' OK)
                        && symbol.constEnumOnlyModule !== false;
                }
            }
        }
        function declareModuleSymbol(node) {
            var state = getModuleInstanceState(node);
            var instantiated = state !== 0 /* NonInstantiated */;
            declareSymbolAndAddToSymbolTable(node, instantiated ? 512 /* ValueModule */ : 1024 /* NamespaceModule */, instantiated ? 110735 /* ValueModuleExcludes */ : 0 /* NamespaceModuleExcludes */);
            return state;
        }
        function bindFunctionOrConstructorType(node) {
            // For a given function symbol "<...>(...) => T" we want to generate a symbol identical
            // to the one we would get for: { <...>(...): T }
            //
            // We do that by making an anonymous type literal symbol, and then setting the function
            // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
            // from an actual type literal symbol you would have gotten had you used the long form.
            var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node)); // TODO: GH#18217
            addDeclarationToSymbol(symbol, node, 131072 /* Signature */);
            var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
            addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */);
            typeLiteralSymbol.members = ts.createSymbolTable();
            typeLiteralSymbol.members.set(symbol.escapedName, symbol);
        }
        function bindObjectLiteralExpression(node) {
            var ElementKind;
            (function (ElementKind) {
                ElementKind[ElementKind["Property"] = 1] = "Property";
                ElementKind[ElementKind["Accessor"] = 2] = "Accessor";
            })(ElementKind || (ElementKind = {}));
            if (inStrictMode && !ts.isAssignmentTarget(node)) {
                var seen = ts.createUnderscoreEscapedMap();
                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (prop.kind === 283 /* SpreadAssignment */ || prop.name.kind !== 75 /* Identifier */) {
                        continue;
                    }
                    var identifier = prop.name;
                    // ECMA-262 11.1.5 Object Initializer
                    // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
                    // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
                    // IsDataDescriptor(propId.descriptor) is true.
                    //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
                    //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
                    //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
                    // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
                    var currentKind = prop.kind === 281 /* PropertyAssignment */ || prop.kind === 282 /* ShorthandPropertyAssignment */ || prop.kind === 161 /* MethodDeclaration */
                        ? 1 /* Property */
                        : 2 /* Accessor */;
                    var existingKind = seen.get(identifier.escapedText);
                    if (!existingKind) {
                        seen.set(identifier.escapedText, currentKind);
                        continue;
                    }
                    if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) {
                        var span = ts.getErrorSpanForNode(file, identifier);
                        file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode));
                    }
                }
            }
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object" /* Object */);
        }
        function bindJsxAttributes(node) {
            return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__jsxAttributes" /* JSXAttributes */);
        }
        function bindJsxAttribute(node, symbolFlags, symbolExcludes) {
            return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        function bindAnonymousDeclaration(node, symbolFlags, name) {
            var symbol = createSymbol(symbolFlags, name);
            if (symbolFlags & (8 /* EnumMember */ | 106500 /* ClassMember */)) {
                symbol.parent = container.symbol;
            }
            addDeclarationToSymbol(symbol, node, symbolFlags);
            return symbol;
        }
        function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) {
            switch (blockScopeContainer.kind) {
                case 249 /* ModuleDeclaration */:
                    declareModuleMember(node, symbolFlags, symbolExcludes);
                    break;
                case 290 /* SourceFile */:
                    if (ts.isExternalOrCommonJsModule(container)) {
                        declareModuleMember(node, symbolFlags, symbolExcludes);
                        break;
                    }
                // falls through
                default:
                    if (!blockScopeContainer.locals) {
                        blockScopeContainer.locals = ts.createSymbolTable();
                        addToContainerChain(blockScopeContainer);
                    }
                    declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
            }
        }
        function delayedBindJSDocTypedefTag() {
            if (!delayedTypeAliases) {
                return;
            }
            var saveContainer = container;
            var saveLastContainer = lastContainer;
            var saveBlockScopeContainer = blockScopeContainer;
            var saveParent = parent;
            var saveCurrentFlow = currentFlow;
            for (var _i = 0, delayedTypeAliases_1 = delayedTypeAliases; _i < delayedTypeAliases_1.length; _i++) {
                var typeAlias = delayedTypeAliases_1[_i];
                var host = ts.getJSDocHost(typeAlias);
                container = ts.findAncestor(host.parent, function (n) { return !!(getContainerFlags(n) & 1 /* IsContainer */); }) || file;
                blockScopeContainer = ts.getEnclosingBlockScopeContainer(host) || file;
                currentFlow = initFlowNode({ flags: 2 /* Start */ });
                parent = typeAlias;
                bind(typeAlias.typeExpression);
                var declName = ts.getNameOfDeclaration(typeAlias);
                if ((ts.isJSDocEnumTag(typeAlias) || !typeAlias.fullName) && declName && ts.isPropertyAccessEntityNameExpression(declName.parent)) {
                    // typedef anchored to an A.B.C assignment - we need to bind into B's namespace under name C
                    var isTopLevel = isTopLevelNamespaceAssignment(declName.parent);
                    if (isTopLevel) {
                        bindPotentiallyMissingNamespaces(file.symbol, declName.parent, isTopLevel, !!ts.findAncestor(declName, function (d) { return ts.isPropertyAccessExpression(d) && d.name.escapedText === "prototype"; }), /*containerIsClass*/ false);
                        var oldContainer = container;
                        switch (ts.getAssignmentDeclarationPropertyAccessKind(declName.parent)) {
                            case 1 /* ExportsProperty */:
                            case 2 /* ModuleExports */:
                                if (!ts.isExternalOrCommonJsModule(file)) {
                                    container = undefined;
                                }
                                else {
                                    container = file;
                                }
                                break;
                            case 4 /* ThisProperty */:
                                container = declName.parent.expression;
                                break;
                            case 3 /* PrototypeProperty */:
                                container = declName.parent.expression.name;
                                break;
                            case 5 /* Property */:
                                container = isExportsOrModuleExportsOrAlias(file, declName.parent.expression) ? file
                                    : ts.isPropertyAccessExpression(declName.parent.expression) ? declName.parent.expression.name
                                        : declName.parent.expression;
                                break;
                            case 0 /* None */:
                                return ts.Debug.fail("Shouldn't have detected typedef or enum on non-assignment declaration");
                        }
                        if (container) {
                            declareModuleMember(typeAlias, 524288 /* TypeAlias */, 788968 /* TypeAliasExcludes */);
                        }
                        container = oldContainer;
                    }
                }
                else if (ts.isJSDocEnumTag(typeAlias) || !typeAlias.fullName || typeAlias.fullName.kind === 75 /* Identifier */) {
                    parent = typeAlias.parent;
                    bindBlockScopedDeclaration(typeAlias, 524288 /* TypeAlias */, 788968 /* TypeAliasExcludes */);
                }
                else {
                    bind(typeAlias.fullName);
                }
            }
            container = saveContainer;
            lastContainer = saveLastContainer;
            blockScopeContainer = saveBlockScopeContainer;
            parent = saveParent;
            currentFlow = saveCurrentFlow;
        }
        // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized
        // check for reserved words used as identifiers in strict mode code.
        function checkStrictModeIdentifier(node) {
            if (inStrictMode &&
                node.originalKeywordKind >= 113 /* FirstFutureReservedWord */ &&
                node.originalKeywordKind <= 121 /* LastFutureReservedWord */ &&
                !ts.isIdentifierName(node) &&
                !(node.flags & 8388608 /* Ambient */) &&
                !(node.flags & 4194304 /* JSDoc */)) {
                // Report error only if there are no parse errors in file
                if (!file.parseDiagnostics.length) {
                    file.bindDiagnostics.push(createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node)));
                }
            }
        }
        function getStrictModeIdentifierMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
        }
        // The binder visits every node, so this is a good place to check for
        // the reserved private name (there is only one)
        function checkPrivateIdentifier(node) {
            if (node.escapedText === "#constructor") {
                // Report error only if there are no parse errors in file
                if (!file.parseDiagnostics.length) {
                    file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.constructor_is_a_reserved_word, ts.declarationNameToString(node)));
                }
            }
        }
        function checkStrictModeBinaryExpression(node) {
            if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) {
                // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
                // Assignment operator(11.13) or of a PostfixExpression(11.3)
                checkStrictModeEvalOrArguments(node, node.left);
            }
        }
        function checkStrictModeCatchClause(node) {
            // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the
            // Catch production is eval or arguments
            if (inStrictMode && node.variableDeclaration) {
                checkStrictModeEvalOrArguments(node, node.variableDeclaration.name);
            }
        }
        function checkStrictModeDeleteExpression(node) {
            // Grammar checking
            if (inStrictMode && node.expression.kind === 75 /* Identifier */) {
                // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
                // UnaryExpression is a direct reference to a variable, function argument, or function name
                var span = ts.getErrorSpanForNode(file, node.expression);
                file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode));
            }
        }
        function isEvalOrArgumentsIdentifier(node) {
            return ts.isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments");
        }
        function checkStrictModeEvalOrArguments(contextNode, name) {
            if (name && name.kind === 75 /* Identifier */) {
                var identifier = name;
                if (isEvalOrArgumentsIdentifier(identifier)) {
                    // We check first if the name is inside class declaration or class expression; if so give explicit message
                    // otherwise report generic error message.
                    var span = ts.getErrorSpanForNode(file, name);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, getStrictModeEvalOrArgumentsMessage(contextNode), ts.idText(identifier)));
                }
            }
        }
        function getStrictModeEvalOrArgumentsMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Invalid_use_of_0_in_strict_mode;
        }
        function checkStrictModeFunctionName(node) {
            if (inStrictMode) {
                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1))
                checkStrictModeEvalOrArguments(node, node.name);
            }
        }
        function getStrictModeBlockScopeFunctionDeclarationMessage(node) {
            // Provide specialized messages to help the user understand why we think they're in
            // strict mode.
            if (ts.getContainingClass(node)) {
                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode;
            }
            if (file.externalModuleIndicator) {
                return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode;
            }
            return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5;
        }
        function checkStrictModeFunctionDeclaration(node) {
            if (languageVersion < 2 /* ES2015 */) {
                // Report error if function is not top level function declaration
                if (blockScopeContainer.kind !== 290 /* SourceFile */ &&
                    blockScopeContainer.kind !== 249 /* ModuleDeclaration */ &&
                    !ts.isFunctionLike(blockScopeContainer)) {
                    // We check first if the name is inside class declaration or class expression; if so give explicit message
                    // otherwise report generic error message.
                    var errorSpan = ts.getErrorSpanForNode(file, node);
                    file.bindDiagnostics.push(ts.createFileDiagnostic(file, errorSpan.start, errorSpan.length, getStrictModeBlockScopeFunctionDeclarationMessage(node)));
                }
            }
        }
        function checkStrictModeNumericLiteral(node) {
            if (inStrictMode && node.numericLiteralFlags & 32 /* Octal */) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode));
            }
        }
        function checkStrictModePostfixUnaryExpression(node) {
            // Grammar checking
            // The identifier eval or arguments may not appear as the LeftHandSideExpression of an
            // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
            // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator.
            if (inStrictMode) {
                checkStrictModeEvalOrArguments(node, node.operand);
            }
        }
        function checkStrictModePrefixUnaryExpression(node) {
            // Grammar checking
            if (inStrictMode) {
                if (node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */) {
                    checkStrictModeEvalOrArguments(node, node.operand);
                }
            }
        }
        function checkStrictModeWithStatement(node) {
            // Grammar checking for withStatement
            if (inStrictMode) {
                errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode);
            }
        }
        function checkStrictModeLabeledStatement(node) {
            // Grammar checking for labeledStatement
            if (inStrictMode && options.target >= 2 /* ES2015 */) {
                if (ts.isDeclarationStatement(node.statement) || ts.isVariableStatement(node.statement)) {
                    errorOnFirstToken(node.label, ts.Diagnostics.A_label_is_not_allowed_here);
                }
            }
        }
        function errorOnFirstToken(node, message, arg0, arg1, arg2) {
            var span = ts.getSpanOfTokenAtPosition(file, node.pos);
            file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
        }
        function errorOrSuggestionOnNode(isError, node, message) {
            errorOrSuggestionOnRange(isError, node, node, message);
        }
        function errorOrSuggestionOnRange(isError, startNode, endNode, message) {
            addErrorOrSuggestionDiagnostic(isError, { pos: ts.getTokenPosOfNode(startNode, file), end: endNode.end }, message);
        }
        function addErrorOrSuggestionDiagnostic(isError, range, message) {
            var diag = ts.createFileDiagnostic(file, range.pos, range.end - range.pos, message);
            if (isError) {
                file.bindDiagnostics.push(diag);
            }
            else {
                file.bindSuggestionDiagnostics = ts.append(file.bindSuggestionDiagnostics, __assign(__assign({}, diag), { category: ts.DiagnosticCategory.Suggestion }));
            }
        }
        function bind(node) {
            if (!node) {
                return;
            }
            node.parent = parent;
            var saveInStrictMode = inStrictMode;
            // Even though in the AST the jsdoc @typedef node belongs to the current node,
            // its symbol might be in the same scope with the current node's symbol. Consider:
            //
            //     /** @typedef {string | number} MyType */
            //     function foo();
            //
            // Here the current node is "foo", which is a container, but the scope of "MyType" should
            // not be inside "foo". Therefore we always bind @typedef before bind the parent node,
            // and skip binding this tag later when binding all the other jsdoc tags.
            // First we bind declaration nodes to a symbol if possible. We'll both create a symbol
            // and then potentially add the symbol to an appropriate symbol table. Possible
            // destination symbol tables are:
            //
            //  1) The 'exports' table of the current container's symbol.
            //  2) The 'members' table of the current container's symbol.
            //  3) The 'locals' table of the current container.
            //
            // However, not all symbols will end up in any of these tables. 'Anonymous' symbols
            // (like TypeLiterals for example) will not be put in any table.
            bindWorker(node);
            // Then we recurse into the children of the node to bind them as well. For certain
            // symbols we do specialized work when we recurse. For example, we'll keep track of
            // the current 'container' node when it changes. This helps us know which symbol table
            // a local should go into for example. Since terminal nodes are known not to have
            // children, as an optimization we don't process those.
            if (node.kind > 152 /* LastToken */) {
                var saveParent = parent;
                parent = node;
                var containerFlags = getContainerFlags(node);
                if (containerFlags === 0 /* None */) {
                    bindChildren(node);
                }
                else {
                    bindContainer(node, containerFlags);
                }
                parent = saveParent;
            }
            else if (!skipTransformFlagAggregation && (node.transformFlags & 536870912 /* HasComputedFlags */) === 0) {
                subtreeTransformFlags |= computeTransformFlagsForNode(node, 0);
                var saveParent = parent;
                if (node.kind === 1 /* EndOfFileToken */)
                    parent = node;
                bindJSDoc(node);
                parent = saveParent;
            }
            inStrictMode = saveInStrictMode;
        }
        function bindJSDoc(node) {
            if (ts.hasJSDocNodes(node)) {
                if (ts.isInJSFile(node)) {
                    for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) {
                        var j = _a[_i];
                        bind(j);
                    }
                }
                else {
                    for (var _b = 0, _c = node.jsDoc; _b < _c.length; _b++) {
                        var j = _c[_b];
                        setParentPointers(node, j);
                    }
                }
            }
        }
        function updateStrictModeStatementList(statements) {
            if (!inStrictMode) {
                for (var _i = 0, statements_2 = statements; _i < statements_2.length; _i++) {
                    var statement = statements_2[_i];
                    if (!ts.isPrologueDirective(statement)) {
                        return;
                    }
                    if (isUseStrictPrologueDirective(statement)) {
                        inStrictMode = true;
                        return;
                    }
                }
            }
        }
        /// Should be called only on prologue directives (isPrologueDirective(node) should be true)
        function isUseStrictPrologueDirective(node) {
            var nodeText = ts.getSourceTextOfNodeFromSourceFile(file, node.expression);
            // Note: the node text must be exactly "use strict" or 'use strict'.  It is not ok for the
            // string to contain unicode escapes (as per ES5).
            return nodeText === '"use strict"' || nodeText === "'use strict'";
        }
        function bindWorker(node) {
            switch (node.kind) {
                /* Strict mode checks */
                case 75 /* Identifier */:
                    // for typedef type names with namespaces, bind the new jsdoc type symbol here
                    // because it requires all containing namespaces to be in effect, namely the
                    // current "blockScopeContainer" needs to be set to its immediate namespace parent.
                    if (node.isInJSDocNamespace) {
                        var parentNode = node.parent;
                        while (parentNode && !ts.isJSDocTypeAlias(parentNode)) {
                            parentNode = parentNode.parent;
                        }
                        bindBlockScopedDeclaration(parentNode, 524288 /* TypeAlias */, 788968 /* TypeAliasExcludes */);
                        break;
                    }
                // falls through
                case 104 /* ThisKeyword */:
                    if (currentFlow && (ts.isExpression(node) || parent.kind === 282 /* ShorthandPropertyAssignment */)) {
                        node.flowNode = currentFlow;
                    }
                    return checkStrictModeIdentifier(node);
                case 76 /* PrivateIdentifier */:
                    return checkPrivateIdentifier(node);
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    var expr = node;
                    if (currentFlow && isNarrowableReference(expr)) {
                        expr.flowNode = currentFlow;
                    }
                    if (ts.isSpecialPropertyDeclaration(expr)) {
                        bindSpecialPropertyDeclaration(expr);
                    }
                    if (ts.isInJSFile(expr) &&
                        file.commonJsModuleIndicator &&
                        ts.isModuleExportsAccessExpression(expr) &&
                        !lookupSymbolForNameWorker(blockScopeContainer, "module")) {
                        declareSymbol(file.locals, /*parent*/ undefined, expr.expression, 1 /* FunctionScopedVariable */ | 134217728 /* ModuleExports */, 111550 /* FunctionScopedVariableExcludes */);
                    }
                    break;
                case 209 /* BinaryExpression */:
                    var specialKind = ts.getAssignmentDeclarationKind(node);
                    switch (specialKind) {
                        case 1 /* ExportsProperty */:
                            bindExportsPropertyAssignment(node);
                            break;
                        case 2 /* ModuleExports */:
                            bindModuleExportsAssignment(node);
                            break;
                        case 3 /* PrototypeProperty */:
                            bindPrototypePropertyAssignment(node.left, node);
                            break;
                        case 6 /* Prototype */:
                            bindPrototypeAssignment(node);
                            break;
                        case 4 /* ThisProperty */:
                            bindThisPropertyAssignment(node);
                            break;
                        case 5 /* Property */:
                            bindSpecialPropertyAssignment(node);
                            break;
                        case 0 /* None */:
                            // Nothing to do
                            break;
                        default:
                            ts.Debug.fail("Unknown binary expression special property assignment kind");
                    }
                    return checkStrictModeBinaryExpression(node);
                case 280 /* CatchClause */:
                    return checkStrictModeCatchClause(node);
                case 203 /* DeleteExpression */:
                    return checkStrictModeDeleteExpression(node);
                case 8 /* NumericLiteral */:
                    return checkStrictModeNumericLiteral(node);
                case 208 /* PostfixUnaryExpression */:
                    return checkStrictModePostfixUnaryExpression(node);
                case 207 /* PrefixUnaryExpression */:
                    return checkStrictModePrefixUnaryExpression(node);
                case 236 /* WithStatement */:
                    return checkStrictModeWithStatement(node);
                case 238 /* LabeledStatement */:
                    return checkStrictModeLabeledStatement(node);
                case 183 /* ThisType */:
                    seenThisKeyword = true;
                    return;
                case 168 /* TypePredicate */:
                    break; // Binding the children will handle everything
                case 155 /* TypeParameter */:
                    return bindTypeParameter(node);
                case 156 /* Parameter */:
                    return bindParameter(node);
                case 242 /* VariableDeclaration */:
                    return bindVariableDeclarationOrBindingElement(node);
                case 191 /* BindingElement */:
                    node.flowNode = currentFlow;
                    return bindVariableDeclarationOrBindingElement(node);
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    return bindPropertyWorker(node);
                case 281 /* PropertyAssignment */:
                case 282 /* ShorthandPropertyAssignment */:
                    return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */);
                case 284 /* EnumMember */:
                    return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 900095 /* EnumMemberExcludes */);
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 167 /* IndexSignature */:
                    return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */);
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    // If this is an ObjectLiteralExpression method, then it sits in the same space
                    // as other properties in the object literal.  So we use SymbolFlags.PropertyExcludes
                    // so that it will conflict with any other object literal members with the same
                    // name.
                    return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 103359 /* MethodExcludes */);
                case 244 /* FunctionDeclaration */:
                    return bindFunctionDeclaration(node);
                case 162 /* Constructor */:
                    return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */);
                case 163 /* GetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 46015 /* GetAccessorExcludes */);
                case 164 /* SetAccessor */:
                    return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 78783 /* SetAccessorExcludes */);
                case 170 /* FunctionType */:
                case 300 /* JSDocFunctionType */:
                case 305 /* JSDocSignature */:
                case 171 /* ConstructorType */:
                    return bindFunctionOrConstructorType(node);
                case 173 /* TypeLiteral */:
                case 304 /* JSDocTypeLiteral */:
                case 186 /* MappedType */:
                    return bindAnonymousTypeWorker(node);
                case 310 /* JSDocClassTag */:
                    return bindJSDocClassTag(node);
                case 193 /* ObjectLiteralExpression */:
                    return bindObjectLiteralExpression(node);
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return bindFunctionExpression(node);
                case 196 /* CallExpression */:
                    var assignmentKind = ts.getAssignmentDeclarationKind(node);
                    switch (assignmentKind) {
                        case 7 /* ObjectDefinePropertyValue */:
                            return bindObjectDefinePropertyAssignment(node);
                        case 8 /* ObjectDefinePropertyExports */:
                            return bindObjectDefinePropertyExport(node);
                        case 9 /* ObjectDefinePrototypeProperty */:
                            return bindObjectDefinePrototypeProperty(node);
                        case 0 /* None */:
                            break; // Nothing to do
                        default:
                            return ts.Debug.fail("Unknown call expression assignment declaration kind");
                    }
                    if (ts.isInJSFile(node)) {
                        bindCallExpression(node);
                    }
                    break;
                // Members of classes, interfaces, and modules
                case 214 /* ClassExpression */:
                case 245 /* ClassDeclaration */:
                    // All classes are automatically in strict mode in ES6.
                    inStrictMode = true;
                    return bindClassLikeDeclaration(node);
                case 246 /* InterfaceDeclaration */:
                    return bindBlockScopedDeclaration(node, 64 /* Interface */, 788872 /* InterfaceExcludes */);
                case 247 /* TypeAliasDeclaration */:
                    return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 788968 /* TypeAliasExcludes */);
                case 248 /* EnumDeclaration */:
                    return bindEnumDeclaration(node);
                case 249 /* ModuleDeclaration */:
                    return bindModuleDeclaration(node);
                // Jsx-attributes
                case 274 /* JsxAttributes */:
                    return bindJsxAttributes(node);
                case 273 /* JsxAttribute */:
                    return bindJsxAttribute(node, 4 /* Property */, 0 /* PropertyExcludes */);
                // Imports and exports
                case 253 /* ImportEqualsDeclaration */:
                case 256 /* NamespaceImport */:
                case 258 /* ImportSpecifier */:
                case 263 /* ExportSpecifier */:
                    return declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
                case 252 /* NamespaceExportDeclaration */:
                    return bindNamespaceExportDeclaration(node);
                case 255 /* ImportClause */:
                    return bindImportClause(node);
                case 260 /* ExportDeclaration */:
                    return bindExportDeclaration(node);
                case 259 /* ExportAssignment */:
                    return bindExportAssignment(node);
                case 290 /* SourceFile */:
                    updateStrictModeStatementList(node.statements);
                    return bindSourceFileIfExternalModule();
                case 223 /* Block */:
                    if (!ts.isFunctionLike(node.parent)) {
                        return;
                    }
                // falls through
                case 250 /* ModuleBlock */:
                    return updateStrictModeStatementList(node.statements);
                case 317 /* JSDocParameterTag */:
                    if (node.parent.kind === 305 /* JSDocSignature */) {
                        return bindParameter(node);
                    }
                    if (node.parent.kind !== 304 /* JSDocTypeLiteral */) {
                        break;
                    }
                // falls through
                case 323 /* JSDocPropertyTag */:
                    var propTag = node;
                    var flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === 299 /* JSDocOptionalType */ ?
                        4 /* Property */ | 16777216 /* Optional */ :
                        4 /* Property */;
                    return declareSymbolAndAddToSymbolTable(propTag, flags, 0 /* PropertyExcludes */);
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 316 /* JSDocEnumTag */:
                    return (delayedTypeAliases || (delayedTypeAliases = [])).push(node);
            }
        }
        function bindPropertyWorker(node) {
            return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
        }
        function bindAnonymousTypeWorker(node) {
            return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type" /* Type */);
        }
        function bindSourceFileIfExternalModule() {
            setExportContextFlag(file);
            if (ts.isExternalModule(file)) {
                bindSourceFileAsExternalModule();
            }
            else if (ts.isJsonSourceFile(file)) {
                bindSourceFileAsExternalModule();
                // Create symbol equivalent for the module.exports = {}
                var originalSymbol = file.symbol;
                declareSymbol(file.symbol.exports, file.symbol, file, 4 /* Property */, 67108863 /* All */);
                file.symbol = originalSymbol;
            }
        }
        function bindSourceFileAsExternalModule() {
            bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\"");
        }
        function bindExportAssignment(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export assignment in some sort of block construct
                bindAnonymousDeclaration(node, 2097152 /* Alias */, getDeclarationName(node));
            }
            else {
                var flags = ts.exportAssignmentIsAlias(node)
                    // An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression;
                    ? 2097152 /* Alias */
                    // An export default clause with any other expression exports a value
                    : 4 /* Property */;
                // If there is an `export default x;` alias declaration, can't `export default` anything else.
                // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.)
                var symbol = declareSymbol(container.symbol.exports, container.symbol, node, flags, 67108863 /* All */);
                if (node.isExportEquals) {
                    // Will be an error later, since the module already has other exports. Just make sure this has a valueDeclaration set.
                    ts.setValueDeclaration(symbol, node);
                }
            }
        }
        function bindNamespaceExportDeclaration(node) {
            if (node.modifiers && node.modifiers.length) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here));
            }
            var diag = !ts.isSourceFile(node.parent) ? ts.Diagnostics.Global_module_exports_may_only_appear_at_top_level
                : !ts.isExternalModule(node.parent) ? ts.Diagnostics.Global_module_exports_may_only_appear_in_module_files
                    : !node.parent.isDeclarationFile ? ts.Diagnostics.Global_module_exports_may_only_appear_in_declaration_files
                        : undefined;
            if (diag) {
                file.bindDiagnostics.push(createDiagnosticForNode(node, diag));
            }
            else {
                file.symbol.globalExports = file.symbol.globalExports || ts.createSymbolTable();
                declareSymbol(file.symbol.globalExports, file.symbol, node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function bindExportDeclaration(node) {
            if (!container.symbol || !container.symbol.exports) {
                // Export * in some sort of block construct
                bindAnonymousDeclaration(node, 8388608 /* ExportStar */, getDeclarationName(node));
            }
            else if (!node.exportClause) {
                // All export * declarations are collected in an __export symbol
                declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* ExportStar */, 0 /* None */);
            }
            else if (ts.isNamespaceExport(node.exportClause)) {
                // declareSymbol walks up parents to find name text, parent _must_ be set
                // but won't be set by the normal binder walk until `bindChildren` later on.
                node.exportClause.parent = node;
                declareSymbol(container.symbol.exports, container.symbol, node.exportClause, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function bindImportClause(node) {
            if (node.name) {
                declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */);
            }
        }
        function setCommonJsModuleIndicator(node) {
            if (file.externalModuleIndicator) {
                return false;
            }
            if (!file.commonJsModuleIndicator) {
                file.commonJsModuleIndicator = node;
                bindSourceFileAsExternalModule();
            }
            return true;
        }
        function bindObjectDefinePropertyExport(node) {
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var symbol = forEachIdentifierInEntityName(node.arguments[0], /*parent*/ undefined, function (id, symbol) {
                if (symbol) {
                    addDeclarationToSymbol(symbol, id, 1536 /* Module */ | 67108864 /* Assignment */);
                }
                return symbol;
            });
            if (symbol) {
                var flags = 4 /* Property */ | 1048576 /* ExportValue */;
                declareSymbol(symbol.exports, symbol, node, flags, 0 /* None */);
            }
        }
        function bindExportsPropertyAssignment(node) {
            // When we create a property via 'exports.foo = bar', the 'exports.foo' property access
            // expression is the declaration
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var symbol = forEachIdentifierInEntityName(node.left.expression, /*parent*/ undefined, function (id, symbol) {
                if (symbol) {
                    addDeclarationToSymbol(symbol, id, 1536 /* Module */ | 67108864 /* Assignment */);
                }
                return symbol;
            });
            if (symbol) {
                var flags = ts.isClassExpression(node.right) ?
                    4 /* Property */ | 1048576 /* ExportValue */ | 32 /* Class */ :
                    4 /* Property */ | 1048576 /* ExportValue */;
                declareSymbol(symbol.exports, symbol, node.left, flags, 0 /* None */);
            }
        }
        function bindModuleExportsAssignment(node) {
            // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
            // is still pointing to 'module.exports'.
            // We do not want to consider this as 'export=' since a module can have only one of these.
            // Similarly we do not want to treat 'module.exports = exports' as an 'export='.
            if (!setCommonJsModuleIndicator(node)) {
                return;
            }
            var assignedExpression = ts.getRightMostAssignedExpression(node.right);
            if (ts.isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) {
                return;
            }
            // 'module.exports = expr' assignment
            var flags = ts.exportAssignmentIsAlias(node)
                ? 2097152 /* Alias */
                : 4 /* Property */ | 1048576 /* ExportValue */ | 512 /* ValueModule */;
            var symbol = declareSymbol(file.symbol.exports, file.symbol, node, flags | 67108864 /* Assignment */, 0 /* None */);
            ts.setValueDeclaration(symbol, node);
        }
        function bindThisPropertyAssignment(node) {
            ts.Debug.assert(ts.isInJSFile(node));
            // private identifiers *must* be declared (even in JS files)
            var hasPrivateIdentifier = (ts.isBinaryExpression(node) && ts.isPropertyAccessExpression(node.left) && ts.isPrivateIdentifier(node.left.name))
                || (ts.isPropertyAccessExpression(node) && ts.isPrivateIdentifier(node.name));
            if (hasPrivateIdentifier) {
                return;
            }
            var thisContainer = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            switch (thisContainer.kind) {
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                    var constructorSymbol = thisContainer.symbol;
                    // For `f.prototype.m = function() { this.x = 0; }`, `this.x = 0` should modify `f`'s members, not the function expression.
                    if (ts.isBinaryExpression(thisContainer.parent) && thisContainer.parent.operatorToken.kind === 62 /* EqualsToken */) {
                        var l = thisContainer.parent.left;
                        if (ts.isBindableStaticAccessExpression(l) && ts.isPrototypeAccess(l.expression)) {
                            constructorSymbol = lookupSymbolForPropertyAccess(l.expression.expression, thisParentContainer);
                        }
                    }
                    if (constructorSymbol && constructorSymbol.valueDeclaration) {
                        // Declare a 'member' if the container is an ES5 class or ES6 constructor
                        constructorSymbol.members = constructorSymbol.members || ts.createSymbolTable();
                        // It's acceptable for multiple 'this' assignments of the same identifier to occur
                        if (ts.hasDynamicName(node)) {
                            bindDynamicallyNamedThisPropertyAssignment(node, constructorSymbol);
                        }
                        else {
                            declareSymbol(constructorSymbol.members, constructorSymbol, node, 4 /* Property */ | 67108864 /* Assignment */, 0 /* PropertyExcludes */ & ~4 /* Property */);
                        }
                        addDeclarationToSymbol(constructorSymbol, constructorSymbol.valueDeclaration, 32 /* Class */);
                    }
                    break;
                case 162 /* Constructor */:
                case 159 /* PropertyDeclaration */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    // this.foo assignment in a JavaScript class
                    // Bind this property to the containing class
                    var containingClass = thisContainer.parent;
                    var symbolTable = ts.hasModifier(thisContainer, 32 /* Static */) ? containingClass.symbol.exports : containingClass.symbol.members;
                    if (ts.hasDynamicName(node)) {
                        bindDynamicallyNamedThisPropertyAssignment(node, containingClass.symbol);
                    }
                    else {
                        declareSymbol(symbolTable, containingClass.symbol, node, 4 /* Property */ | 67108864 /* Assignment */, 0 /* None */, /*isReplaceableByMethod*/ true);
                    }
                    break;
                case 290 /* SourceFile */:
                    // this.property = assignment in a source file -- declare symbol in exports for a module, in locals for a script
                    if (ts.hasDynamicName(node)) {
                        break;
                    }
                    else if (thisContainer.commonJsModuleIndicator) {
                        declareSymbol(thisContainer.symbol.exports, thisContainer.symbol, node, 4 /* Property */ | 1048576 /* ExportValue */, 0 /* None */);
                    }
                    else {
                        declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 111550 /* FunctionScopedVariableExcludes */);
                    }
                    break;
                default:
                    ts.Debug.failBadSyntaxKind(thisContainer);
            }
        }
        function bindDynamicallyNamedThisPropertyAssignment(node, symbol) {
            bindAnonymousDeclaration(node, 4 /* Property */, "__computed" /* Computed */);
            addLateBoundAssignmentDeclarationToSymbol(node, symbol);
        }
        function addLateBoundAssignmentDeclarationToSymbol(node, symbol) {
            if (symbol) {
                var members = symbol.assignmentDeclarationMembers || (symbol.assignmentDeclarationMembers = ts.createMap());
                members.set("" + ts.getNodeId(node), node);
            }
        }
        function bindSpecialPropertyDeclaration(node) {
            if (node.expression.kind === 104 /* ThisKeyword */) {
                bindThisPropertyAssignment(node);
            }
            else if (ts.isBindableStaticAccessExpression(node) && node.parent.parent.kind === 290 /* SourceFile */) {
                if (ts.isPrototypeAccess(node.expression)) {
                    bindPrototypePropertyAssignment(node, node.parent);
                }
                else {
                    bindStaticPropertyAssignment(node);
                }
            }
        }
        /** For `x.prototype = { p, ... }`, declare members p,... if `x` is function/class/{}, or not declared. */
        function bindPrototypeAssignment(node) {
            node.left.parent = node;
            node.right.parent = node;
            bindPropertyAssignment(node.left.expression, node.left, /*isPrototypeProperty*/ false, /*containerIsClass*/ true);
        }
        function bindObjectDefinePrototypeProperty(node) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0].expression);
            if (namespaceSymbol && namespaceSymbol.valueDeclaration) {
                // Ensure the namespace symbol becomes class-like
                addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, 32 /* Class */);
            }
            bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ true);
        }
        /**
         * For `x.prototype.y = z`, declare a member `y` on `x` if `x` is a function or class, or not declared.
         * Note that jsdoc preceding an ExpressionStatement like `x.prototype.y;` is also treated as a declaration.
         */
        function bindPrototypePropertyAssignment(lhs, parent) {
            // Look up the function in the local scope, since prototype assignments should
            // follow the function declaration
            var classPrototype = lhs.expression;
            var constructorFunction = classPrototype.expression;
            // Fix up parent pointers since we're going to use these nodes before we bind into them
            lhs.parent = parent;
            constructorFunction.parent = classPrototype;
            classPrototype.parent = lhs;
            bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true, /*containerIsClass*/ true);
        }
        function bindObjectDefinePropertyAssignment(node) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0]);
            var isToplevel = node.parent.parent.kind === 290 /* SourceFile */;
            namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, node.arguments[0], isToplevel, /*isPrototypeProperty*/ false, /*containerIsClass*/ false);
            bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ false);
        }
        function bindSpecialPropertyAssignment(node) {
            // Class declarations in Typescript do not allow property declarations
            var parentSymbol = lookupSymbolForPropertyAccess(node.left.expression);
            if (!ts.isInJSFile(node) && !ts.isFunctionSymbol(parentSymbol)) {
                return;
            }
            // Fix up parent pointers since we're going to use these nodes before we bind into them
            node.left.parent = node;
            node.right.parent = node;
            if (ts.isIdentifier(node.left.expression) && container === file && isExportsOrModuleExportsOrAlias(file, node.left.expression)) {
                // This can be an alias for the 'exports' or 'module.exports' names, e.g.
                //    var util = module.exports;
                //    util.property = function ...
                bindExportsPropertyAssignment(node);
            }
            else if (ts.hasDynamicName(node)) {
                bindAnonymousDeclaration(node, 4 /* Property */ | 67108864 /* Assignment */, "__computed" /* Computed */);
                var sym = bindPotentiallyMissingNamespaces(parentSymbol, node.left.expression, isTopLevelNamespaceAssignment(node.left), /*isPrototype*/ false, /*containerIsClass*/ false);
                addLateBoundAssignmentDeclarationToSymbol(node, sym);
            }
            else {
                bindStaticPropertyAssignment(ts.cast(node.left, ts.isBindableStaticNameExpression));
            }
        }
        /**
         * For nodes like `x.y = z`, declare a member 'y' on 'x' if x is a function (or IIFE) or class or {}, or not declared.
         * Also works for expression statements preceded by JSDoc, like / ** @type number * / x.y;
         */
        function bindStaticPropertyAssignment(node) {
            ts.Debug.assert(!ts.isIdentifier(node));
            node.expression.parent = node;
            bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false, /*containerIsClass*/ false);
        }
        function bindPotentiallyMissingNamespaces(namespaceSymbol, entityName, isToplevel, isPrototypeProperty, containerIsClass) {
            if (isToplevel && !isPrototypeProperty) {
                // make symbols or add declarations for intermediate containers
                var flags_1 = 1536 /* Module */ | 67108864 /* Assignment */;
                var excludeFlags_1 = 110735 /* ValueModuleExcludes */ & ~67108864 /* Assignment */;
                namespaceSymbol = forEachIdentifierInEntityName(entityName, namespaceSymbol, function (id, symbol, parent) {
                    if (symbol) {
                        addDeclarationToSymbol(symbol, id, flags_1);
                        return symbol;
                    }
                    else {
                        var table = parent ? parent.exports :
                            file.jsGlobalAugmentations || (file.jsGlobalAugmentations = ts.createSymbolTable());
                        return declareSymbol(table, parent, id, flags_1, excludeFlags_1);
                    }
                });
            }
            if (containerIsClass && namespaceSymbol && namespaceSymbol.valueDeclaration) {
                addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, 32 /* Class */);
            }
            return namespaceSymbol;
        }
        function bindPotentiallyNewExpandoMemberToNamespace(declaration, namespaceSymbol, isPrototypeProperty) {
            if (!namespaceSymbol || !isExpandoSymbol(namespaceSymbol)) {
                return;
            }
            // Set up the members collection if it doesn't exist already
            var symbolTable = isPrototypeProperty ?
                (namespaceSymbol.members || (namespaceSymbol.members = ts.createSymbolTable())) :
                (namespaceSymbol.exports || (namespaceSymbol.exports = ts.createSymbolTable()));
            var includes = 0 /* None */;
            var excludes = 0 /* None */;
            // Method-like
            if (ts.isFunctionLikeDeclaration(ts.getAssignedExpandoInitializer(declaration))) {
                includes = 8192 /* Method */;
                excludes = 103359 /* MethodExcludes */;
            }
            // Maybe accessor-like
            else if (ts.isCallExpression(declaration) && ts.isBindableObjectDefinePropertyCall(declaration)) {
                if (ts.some(declaration.arguments[2].properties, function (p) {
                    var id = ts.getNameOfDeclaration(p);
                    return !!id && ts.isIdentifier(id) && ts.idText(id) === "set";
                })) {
                    // We mix in `SymbolFLags.Property` so in the checker `getTypeOfVariableParameterOrProperty` is used for this
                    // symbol, instead of `getTypeOfAccessor` (which will assert as there is no real accessor declaration)
                    includes |= 65536 /* SetAccessor */ | 4 /* Property */;
                    excludes |= 78783 /* SetAccessorExcludes */;
                }
                if (ts.some(declaration.arguments[2].properties, function (p) {
                    var id = ts.getNameOfDeclaration(p);
                    return !!id && ts.isIdentifier(id) && ts.idText(id) === "get";
                })) {
                    includes |= 32768 /* GetAccessor */ | 4 /* Property */;
                    excludes |= 46015 /* GetAccessorExcludes */;
                }
            }
            if (includes === 0 /* None */) {
                includes = 4 /* Property */;
                excludes = 0 /* PropertyExcludes */;
            }
            declareSymbol(symbolTable, namespaceSymbol, declaration, includes | 67108864 /* Assignment */, excludes & ~67108864 /* Assignment */);
        }
        function isTopLevelNamespaceAssignment(propertyAccess) {
            return ts.isBinaryExpression(propertyAccess.parent)
                ? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === 290 /* SourceFile */
                : propertyAccess.parent.parent.kind === 290 /* SourceFile */;
        }
        function bindPropertyAssignment(name, propertyAccess, isPrototypeProperty, containerIsClass) {
            var namespaceSymbol = lookupSymbolForPropertyAccess(name);
            var isToplevel = isTopLevelNamespaceAssignment(propertyAccess);
            namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty, containerIsClass);
            bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty);
        }
        /**
         * Javascript expando values are:
         * - Functions
         * - classes
         * - namespaces
         * - variables initialized with function expressions
         * -                       with class expressions
         * -                       with empty object literals
         * -                       with non-empty object literals if assigned to the prototype property
         */
        function isExpandoSymbol(symbol) {
            if (symbol.flags & (16 /* Function */ | 32 /* Class */ | 1024 /* NamespaceModule */)) {
                return true;
            }
            var node = symbol.valueDeclaration;
            if (node && ts.isCallExpression(node)) {
                return !!ts.getAssignedExpandoInitializer(node);
            }
            var init = !node ? undefined :
                ts.isVariableDeclaration(node) ? node.initializer :
                    ts.isBinaryExpression(node) ? node.right :
                        ts.isPropertyAccessExpression(node) && ts.isBinaryExpression(node.parent) ? node.parent.right :
                            undefined;
            init = init && ts.getRightMostAssignedExpression(init);
            if (init) {
                var isPrototypeAssignment = ts.isPrototypeAccess(ts.isVariableDeclaration(node) ? node.name : ts.isBinaryExpression(node) ? node.left : node);
                return !!ts.getExpandoInitializer(ts.isBinaryExpression(init) && (init.operatorToken.kind === 56 /* BarBarToken */ || init.operatorToken.kind === 60 /* QuestionQuestionToken */) ? init.right : init, isPrototypeAssignment);
            }
            return false;
        }
        function getParentOfBinaryExpression(expr) {
            while (ts.isBinaryExpression(expr.parent)) {
                expr = expr.parent;
            }
            return expr.parent;
        }
        function lookupSymbolForPropertyAccess(node, lookupContainer) {
            if (lookupContainer === void 0) { lookupContainer = container; }
            if (ts.isIdentifier(node)) {
                return lookupSymbolForNameWorker(lookupContainer, node.escapedText);
            }
            else {
                var symbol = lookupSymbolForPropertyAccess(node.expression);
                return symbol && symbol.exports && symbol.exports.get(ts.getElementOrPropertyAccessName(node));
            }
        }
        function forEachIdentifierInEntityName(e, parent, action) {
            if (isExportsOrModuleExportsOrAlias(file, e)) {
                return file.symbol;
            }
            else if (ts.isIdentifier(e)) {
                return action(e, lookupSymbolForPropertyAccess(e), parent);
            }
            else {
                var s = forEachIdentifierInEntityName(e.expression, parent, action);
                var name = ts.getNameOrArgument(e);
                // unreachable
                if (ts.isPrivateIdentifier(name)) {
                    ts.Debug.fail("unexpected PrivateIdentifier");
                }
                return action(name, s && s.exports && s.exports.get(ts.getElementOrPropertyAccessName(e)), s);
            }
        }
        function bindCallExpression(node) {
            // We're only inspecting call expressions to detect CommonJS modules, so we can skip
            // this check if we've already seen the module indicator
            if (!file.commonJsModuleIndicator && ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ false)) {
                setCommonJsModuleIndicator(node);
            }
        }
        function bindClassLikeDeclaration(node) {
            if (node.kind === 245 /* ClassDeclaration */) {
                bindBlockScopedDeclaration(node, 32 /* Class */, 899503 /* ClassExcludes */);
            }
            else {
                var bindingName = node.name ? node.name.escapedText : "__class" /* Class */;
                bindAnonymousDeclaration(node, 32 /* Class */, bindingName);
                // Add name of class expression into the map for semantic classifier
                if (node.name) {
                    classifiableNames.set(node.name.escapedText, true);
                }
            }
            var symbol = node.symbol;
            // TypeScript 1.0 spec (April 2014): 8.4
            // Every class automatically contains a static property member named 'prototype', the
            // type of which is an instantiation of the class type with type Any supplied as a type
            // argument for each type parameter. It is an error to explicitly declare a static
            // property member with the name 'prototype'.
            //
            // Note: we check for this here because this class may be merging into a module.  The
            // module might have an exported variable called 'prototype'.  We can't allow that as
            // that would clash with the built-in 'prototype' for the class.
            var prototypeSymbol = createSymbol(4 /* Property */ | 4194304 /* Prototype */, "prototype");
            var symbolExport = symbol.exports.get(prototypeSymbol.escapedName);
            if (symbolExport) {
                if (node.name) {
                    node.name.parent = node;
                }
                file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(prototypeSymbol)));
            }
            symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol);
            prototypeSymbol.parent = symbol;
        }
        function bindEnumDeclaration(node) {
            return ts.isEnumConst(node)
                ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */)
                : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */);
        }
        function bindVariableDeclarationOrBindingElement(node) {
            if (inStrictMode) {
                checkStrictModeEvalOrArguments(node, node.name);
            }
            if (!ts.isBindingPattern(node.name)) {
                if (ts.isBlockOrCatchScoped(node)) {
                    bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 111551 /* BlockScopedVariableExcludes */);
                }
                else if (ts.isParameterDeclaration(node)) {
                    // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration
                    // because its parent chain has already been set up, since parents are set before descending into children.
                    //
                    // If node is a binding element in parameter declaration, we need to use ParameterExcludes.
                    // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration
                    // For example:
                    //      function foo([a,a]) {} // Duplicate Identifier error
                    //      function bar(a,a) {}   // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter
                    //                             // which correctly set excluded symbols
                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 111551 /* ParameterExcludes */);
                }
                else {
                    declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 111550 /* FunctionScopedVariableExcludes */);
                }
            }
        }
        function bindParameter(node) {
            if (node.kind === 317 /* JSDocParameterTag */ && container.kind !== 305 /* JSDocSignature */) {
                return;
            }
            if (inStrictMode && !(node.flags & 8388608 /* Ambient */)) {
                // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a
                // strict mode FunctionLikeDeclaration or FunctionExpression(13.1)
                checkStrictModeEvalOrArguments(node, node.name);
            }
            if (ts.isBindingPattern(node.name)) {
                bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, "__" + node.parent.parameters.indexOf(node));
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 111551 /* ParameterExcludes */);
            }
            // If this is a property-parameter, then also declare the property symbol into the
            // containing class.
            if (ts.isParameterPropertyDeclaration(node, node.parent)) {
                var classDeclaration = node.parent.parent;
                declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */);
            }
        }
        function bindFunctionDeclaration(node) {
            if (!file.isDeclarationFile && !(node.flags & 8388608 /* Ambient */)) {
                if (ts.isAsyncFunction(node)) {
                    emitFlags |= 2048 /* HasAsyncFunctions */;
                }
            }
            checkStrictModeFunctionName(node);
            if (inStrictMode) {
                checkStrictModeFunctionDeclaration(node);
                bindBlockScopedDeclaration(node, 16 /* Function */, 110991 /* FunctionExcludes */);
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 110991 /* FunctionExcludes */);
            }
        }
        function bindFunctionExpression(node) {
            if (!file.isDeclarationFile && !(node.flags & 8388608 /* Ambient */)) {
                if (ts.isAsyncFunction(node)) {
                    emitFlags |= 2048 /* HasAsyncFunctions */;
                }
            }
            if (currentFlow) {
                node.flowNode = currentFlow;
            }
            checkStrictModeFunctionName(node);
            var bindingName = node.name ? node.name.escapedText : "__function" /* Function */;
            return bindAnonymousDeclaration(node, 16 /* Function */, bindingName);
        }
        function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) {
            if (!file.isDeclarationFile && !(node.flags & 8388608 /* Ambient */) && ts.isAsyncFunction(node)) {
                emitFlags |= 2048 /* HasAsyncFunctions */;
            }
            if (currentFlow && ts.isObjectLiteralOrClassExpressionMethod(node)) {
                node.flowNode = currentFlow;
            }
            return ts.hasDynamicName(node)
                ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */)
                : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
        }
        function getInferTypeContainer(node) {
            var extendsType = ts.findAncestor(node, function (n) { return n.parent && ts.isConditionalTypeNode(n.parent) && n.parent.extendsType === n; });
            return extendsType && extendsType.parent;
        }
        function bindTypeParameter(node) {
            if (ts.isJSDocTemplateTag(node.parent)) {
                var container_1 = ts.find(node.parent.parent.tags, ts.isJSDocTypeAlias) || ts.getHostSignatureFromJSDoc(node.parent); // TODO: GH#18217
                if (container_1) {
                    if (!container_1.locals) {
                        container_1.locals = ts.createSymbolTable();
                    }
                    declareSymbol(container_1.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 526824 /* TypeParameterExcludes */);
                }
                else {
                    declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 526824 /* TypeParameterExcludes */);
                }
            }
            else if (node.parent.kind === 181 /* InferType */) {
                var container_2 = getInferTypeContainer(node.parent);
                if (container_2) {
                    if (!container_2.locals) {
                        container_2.locals = ts.createSymbolTable();
                    }
                    declareSymbol(container_2.locals, /*parent*/ undefined, node, 262144 /* TypeParameter */, 526824 /* TypeParameterExcludes */);
                }
                else {
                    bindAnonymousDeclaration(node, 262144 /* TypeParameter */, getDeclarationName(node)); // TODO: GH#18217
                }
            }
            else {
                declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 526824 /* TypeParameterExcludes */);
            }
        }
        // reachability checks
        function shouldReportErrorOnModuleDeclaration(node) {
            var instanceState = getModuleInstanceState(node);
            return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && !!options.preserveConstEnums);
        }
        function checkUnreachable(node) {
            if (!(currentFlow.flags & 1 /* Unreachable */)) {
                return false;
            }
            if (currentFlow === unreachableFlow) {
                var reportError = 
                // report error on all statements except empty ones
                (ts.isStatementButNotDeclaration(node) && node.kind !== 224 /* EmptyStatement */) ||
                    // report error on class declarations
                    node.kind === 245 /* ClassDeclaration */ ||
                    // report error on instantiated modules or const-enums only modules if preserveConstEnums is set
                    (node.kind === 249 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node));
                if (reportError) {
                    currentFlow = reportedUnreachableFlow;
                    if (!options.allowUnreachableCode) {
                        // unreachable code is reported if
                        // - user has explicitly asked about it AND
                        // - statement is in not ambient context (statements in ambient context is already an error
                        //   so we should not report extras) AND
                        //   - node is not variable statement OR
                        //   - node is block scoped variable statement OR
                        //   - node is not block scoped variable statement and at least one variable declaration has initializer
                        //   Rationale: we don't want to report errors on non-initialized var's since they are hoisted
                        //   On the other side we do want to report errors on non-initialized 'lets' because of TDZ
                        var isError_1 = ts.unreachableCodeIsError(options) &&
                            !(node.flags & 8388608 /* Ambient */) &&
                            (!ts.isVariableStatement(node) ||
                                !!(ts.getCombinedNodeFlags(node.declarationList) & 3 /* BlockScoped */) ||
                                node.declarationList.declarations.some(function (d) { return !!d.initializer; }));
                        eachUnreachableRange(node, function (start, end) { return errorOrSuggestionOnRange(isError_1, start, end, ts.Diagnostics.Unreachable_code_detected); });
                    }
                }
            }
            return true;
        }
    }
    function eachUnreachableRange(node, cb) {
        if (ts.isStatement(node) && isExecutableStatement(node) && ts.isBlock(node.parent)) {
            var statements = node.parent.statements;
            var slice_1 = ts.sliceAfter(statements, node);
            ts.getRangesWhere(slice_1, isExecutableStatement, function (start, afterEnd) { return cb(slice_1[start], slice_1[afterEnd - 1]); });
        }
        else {
            cb(node, node);
        }
    }
    // As opposed to a pure declaration like an `interface`
    function isExecutableStatement(s) {
        // Don't remove statements that can validly be used before they appear.
        return !ts.isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !ts.isEnumDeclaration(s) &&
            // `var x;` may declare a variable used above
            !(ts.isVariableStatement(s) && !(ts.getCombinedNodeFlags(s) & (1 /* Let */ | 2 /* Const */)) && s.declarationList.declarations.some(function (d) { return !d.initializer; }));
    }
    function isPurelyTypeDeclaration(s) {
        switch (s.kind) {
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
                return true;
            case 249 /* ModuleDeclaration */:
                return getModuleInstanceState(s) !== 1 /* Instantiated */;
            case 248 /* EnumDeclaration */:
                return ts.hasModifier(s, 2048 /* Const */);
            default:
                return false;
        }
    }
    function isExportsOrModuleExportsOrAlias(sourceFile, node) {
        var i = 0;
        var q = [node];
        while (q.length && i < 100) {
            i++;
            node = q.shift();
            if (ts.isExportsIdentifier(node) || ts.isModuleExportsAccessExpression(node)) {
                return true;
            }
            else if (ts.isIdentifier(node)) {
                var symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText);
                if (!!symbol && !!symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) && !!symbol.valueDeclaration.initializer) {
                    var init = symbol.valueDeclaration.initializer;
                    q.push(init);
                    if (ts.isAssignmentExpression(init, /*excludeCompoundAssignment*/ true)) {
                        q.push(init.left);
                        q.push(init.right);
                    }
                }
            }
        }
        return false;
    }
    ts.isExportsOrModuleExportsOrAlias = isExportsOrModuleExportsOrAlias;
    function lookupSymbolForNameWorker(container, name) {
        var local = container.locals && container.locals.get(name);
        if (local) {
            return local.exportSymbol || local;
        }
        if (ts.isSourceFile(container) && container.jsGlobalAugmentations && container.jsGlobalAugmentations.has(name)) {
            return container.jsGlobalAugmentations.get(name);
        }
        return container.symbol && container.symbol.exports && container.symbol.exports.get(name);
    }
    /**
     * Computes the transform flags for a node, given the transform flags of its subtree
     *
     * @param node The node to analyze
     * @param subtreeFlags Transform flags computed for this node's subtree
     */
    function computeTransformFlagsForNode(node, subtreeFlags) {
        var kind = node.kind;
        switch (kind) {
            case 196 /* CallExpression */:
                return computeCallExpression(node, subtreeFlags);
            case 197 /* NewExpression */:
                return computeNewExpression(node, subtreeFlags);
            case 249 /* ModuleDeclaration */:
                return computeModuleDeclaration(node, subtreeFlags);
            case 200 /* ParenthesizedExpression */:
                return computeParenthesizedExpression(node, subtreeFlags);
            case 209 /* BinaryExpression */:
                return computeBinaryExpression(node, subtreeFlags);
            case 226 /* ExpressionStatement */:
                return computeExpressionStatement(node, subtreeFlags);
            case 156 /* Parameter */:
                return computeParameter(node, subtreeFlags);
            case 202 /* ArrowFunction */:
                return computeArrowFunction(node, subtreeFlags);
            case 201 /* FunctionExpression */:
                return computeFunctionExpression(node, subtreeFlags);
            case 244 /* FunctionDeclaration */:
                return computeFunctionDeclaration(node, subtreeFlags);
            case 242 /* VariableDeclaration */:
                return computeVariableDeclaration(node, subtreeFlags);
            case 243 /* VariableDeclarationList */:
                return computeVariableDeclarationList(node, subtreeFlags);
            case 225 /* VariableStatement */:
                return computeVariableStatement(node, subtreeFlags);
            case 238 /* LabeledStatement */:
                return computeLabeledStatement(node, subtreeFlags);
            case 245 /* ClassDeclaration */:
                return computeClassDeclaration(node, subtreeFlags);
            case 214 /* ClassExpression */:
                return computeClassExpression(node, subtreeFlags);
            case 279 /* HeritageClause */:
                return computeHeritageClause(node, subtreeFlags);
            case 280 /* CatchClause */:
                return computeCatchClause(node, subtreeFlags);
            case 216 /* ExpressionWithTypeArguments */:
                return computeExpressionWithTypeArguments(node, subtreeFlags);
            case 162 /* Constructor */:
                return computeConstructor(node, subtreeFlags);
            case 159 /* PropertyDeclaration */:
                return computePropertyDeclaration(node, subtreeFlags);
            case 161 /* MethodDeclaration */:
                return computeMethod(node, subtreeFlags);
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
                return computeAccessor(node, subtreeFlags);
            case 253 /* ImportEqualsDeclaration */:
                return computeImportEquals(node, subtreeFlags);
            case 194 /* PropertyAccessExpression */:
                return computePropertyAccess(node, subtreeFlags);
            case 195 /* ElementAccessExpression */:
                return computeElementAccess(node, subtreeFlags);
            case 267 /* JsxSelfClosingElement */:
            case 268 /* JsxOpeningElement */:
                return computeJsxOpeningLikeElement(node, subtreeFlags);
            default:
                return computeOther(node, kind, subtreeFlags);
        }
    }
    ts.computeTransformFlagsForNode = computeTransformFlagsForNode;
    function computeCallExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var callee = ts.skipOuterExpressions(node.expression);
        var expression = node.expression;
        if (node.flags & 32 /* OptionalChain */) {
            transformFlags |= 8 /* ContainsES2020 */;
        }
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        if (subtreeFlags & 8192 /* ContainsRestOrSpread */ || ts.isSuperOrSuperProperty(callee)) {
            // If the this node contains a SpreadExpression, or is a super call, then it is an ES6
            // node.
            transformFlags |= 256 /* AssertES2015 */;
            if (ts.isSuperProperty(callee)) {
                transformFlags |= 4096 /* ContainsLexicalThis */;
            }
        }
        if (expression.kind === 96 /* ImportKeyword */) {
            transformFlags |= 2097152 /* ContainsDynamicImport */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536879104 /* ArrayLiteralOrCallOrNewExcludes */;
    }
    function computeNewExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        if (subtreeFlags & 8192 /* ContainsRestOrSpread */) {
            // If the this node contains a SpreadElementExpression then it is an ES6
            // node.
            transformFlags |= 256 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536879104 /* ArrayLiteralOrCallOrNewExcludes */;
    }
    function computeJsxOpeningLikeElement(node, subtreeFlags) {
        var transformFlags = subtreeFlags | 2 /* AssertJsx */;
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeBinaryExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var operatorTokenKind = node.operatorToken.kind;
        var leftKind = node.left.kind;
        if (operatorTokenKind === 60 /* QuestionQuestionToken */) {
            transformFlags |= 8 /* AssertES2020 */;
        }
        else if (operatorTokenKind === 62 /* EqualsToken */ && leftKind === 193 /* ObjectLiteralExpression */) {
            // Destructuring object assignments with are ES2015 syntax
            // and possibly ES2018 if they contain rest
            transformFlags |= 32 /* AssertES2018 */ | 256 /* AssertES2015 */ | 1024 /* AssertDestructuringAssignment */;
        }
        else if (operatorTokenKind === 62 /* EqualsToken */ && leftKind === 192 /* ArrayLiteralExpression */) {
            // Destructuring assignments are ES2015 syntax.
            transformFlags |= 256 /* AssertES2015 */ | 1024 /* AssertDestructuringAssignment */;
        }
        else if (operatorTokenKind === 42 /* AsteriskAsteriskToken */
            || operatorTokenKind === 66 /* AsteriskAsteriskEqualsToken */) {
            // Exponentiation is ES2016 syntax.
            transformFlags |= 128 /* AssertES2016 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeParameter(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var name = node.name;
        var initializer = node.initializer;
        var dotDotDotToken = node.dotDotDotToken;
        // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript
        // syntax.
        if (node.questionToken
            || node.type
            || (subtreeFlags & 2048 /* ContainsTypeScriptClassSyntax */ && ts.some(node.decorators))
            || ts.isThisIdentifier(name)) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // If a parameter has an accessibility modifier, then it is TypeScript syntax.
        if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
            transformFlags |= 1 /* AssertTypeScript */ | 2048 /* ContainsTypeScriptClassSyntax */;
        }
        // parameters with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        // If a parameter has an initializer, a binding pattern or a dotDotDot token, then
        // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel.
        if (subtreeFlags & 131072 /* ContainsBindingPattern */ || initializer || dotDotDotToken) {
            transformFlags |= 256 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* ParameterExcludes */;
    }
    function computeParenthesizedExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        var expression = node.expression;
        var expressionKind = expression.kind;
        // If the node is synthesized, it means the emitter put the parentheses there,
        // not the user. If we didn't want them, the emitter would not have put them
        // there.
        if (expressionKind === 217 /* AsExpression */
            || expressionKind === 199 /* TypeAssertionExpression */) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* OuterExpressionExcludes */;
    }
    function computeClassDeclaration(node, subtreeFlags) {
        var transformFlags;
        if (ts.hasModifier(node, 2 /* Ambient */)) {
            // An ambient declaration is TypeScript syntax.
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            // A ClassDeclaration is ES6 syntax.
            transformFlags = subtreeFlags | 256 /* AssertES2015 */;
            // A class with a parameter property assignment or decorator is TypeScript syntax.
            // An exported declaration may be TypeScript syntax, but is handled by the visitor
            // for a namespace declaration.
            if ((subtreeFlags & 2048 /* ContainsTypeScriptClassSyntax */)
                || node.typeParameters) {
                transformFlags |= 1 /* AssertTypeScript */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536905728 /* ClassExcludes */;
    }
    function computeClassExpression(node, subtreeFlags) {
        // A ClassExpression is ES6 syntax.
        var transformFlags = subtreeFlags | 256 /* AssertES2015 */;
        // A class with a parameter property assignment or decorator is TypeScript syntax.
        if (subtreeFlags & 2048 /* ContainsTypeScriptClassSyntax */
            || node.typeParameters) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536905728 /* ClassExcludes */;
    }
    function computeHeritageClause(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        switch (node.token) {
            case 90 /* ExtendsKeyword */:
                // An `extends` HeritageClause is ES6 syntax.
                transformFlags |= 256 /* AssertES2015 */;
                break;
            case 113 /* ImplementsKeyword */:
                // An `implements` HeritageClause is TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                break;
            default:
                ts.Debug.fail("Unexpected token for heritage clause");
                break;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeCatchClause(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (!node.variableDeclaration) {
            transformFlags |= 16 /* AssertES2019 */;
        }
        else if (ts.isBindingPattern(node.variableDeclaration.name)) {
            transformFlags |= 256 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536887296 /* CatchClauseExcludes */;
    }
    function computeExpressionWithTypeArguments(node, subtreeFlags) {
        // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
        // extends clause of a class.
        var transformFlags = subtreeFlags | 256 /* AssertES2015 */;
        // If an ExpressionWithTypeArguments contains type arguments, then it
        // is TypeScript syntax.
        if (node.typeArguments) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeConstructor(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // TypeScript-specific modifiers and overloads are TypeScript syntax
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || !node.body) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~538923008 /* ConstructorExcludes */;
    }
    function computeMethod(node, subtreeFlags) {
        // A MethodDeclaration is ES6 syntax.
        var transformFlags = subtreeFlags | 256 /* AssertES2015 */;
        // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and
        // overloads are TypeScript syntax.
        if (node.decorators
            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type
            || !node.body
            || node.questionToken) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        // An async method declaration is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= node.asteriskToken ? 32 /* AssertES2018 */ : 64 /* AssertES2017 */;
        }
        if (node.asteriskToken) {
            transformFlags |= 512 /* AssertGenerator */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~538923008 /* MethodOrAccessorExcludes */);
    }
    function computeAccessor(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // Decorators, TypeScript-specific modifiers, type annotations, and overloads are
        // TypeScript syntax.
        if (node.decorators
            || ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.type
            || !node.body) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // function declarations with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~538923008 /* MethodOrAccessorExcludes */);
    }
    function computePropertyDeclaration(node, subtreeFlags) {
        var transformFlags = subtreeFlags | 4194304 /* ContainsClassFields */;
        // Decorators, TypeScript-specific modifiers, and type annotations are TypeScript syntax.
        if (ts.some(node.decorators) || ts.hasModifier(node, 2270 /* TypeScriptModifier */) || node.type || node.questionToken || node.exclamationToken) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // Hoisted variables related to class properties should live within the TypeScript class wrapper.
        if (ts.isComputedPropertyName(node.name) || (ts.hasStaticModifier(node) && node.initializer)) {
            transformFlags |= 2048 /* ContainsTypeScriptClassSyntax */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return propagatePropertyNameFlags(node.name, transformFlags & ~536875008 /* PropertyExcludes */);
    }
    function computeFunctionDeclaration(node, subtreeFlags) {
        var transformFlags;
        var modifierFlags = ts.getModifierFlags(node);
        var body = node.body;
        if (!body || (modifierFlags & 2 /* Ambient */)) {
            // An ambient declaration is TypeScript syntax.
            // A FunctionDeclaration without a body is an overload and is TypeScript syntax.
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            transformFlags = subtreeFlags | 1048576 /* ContainsHoistedDeclarationOrCompletion */;
            // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
            // syntax.
            if (modifierFlags & 2270 /* TypeScriptModifier */
                || node.typeParameters
                || node.type) {
                transformFlags |= 1 /* AssertTypeScript */;
            }
            // An async function declaration is ES2017 syntax.
            if (modifierFlags & 256 /* Async */) {
                transformFlags |= node.asteriskToken ? 32 /* AssertES2018 */ : 64 /* AssertES2017 */;
            }
            // function declarations with object rest destructuring are ES2018 syntax
            if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
                transformFlags |= 32 /* AssertES2018 */;
            }
            // If a FunctionDeclaration is generator function and is the body of a
            // transformed async function, then this node can be transformed to a
            // down-level generator.
            // Currently we do not support transforming any other generator functions
            // down level.
            if (node.asteriskToken) {
                transformFlags |= 512 /* AssertGenerator */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~538925056 /* FunctionExcludes */;
    }
    function computeFunctionExpression(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
        // syntax.
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // An async function expression is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= node.asteriskToken ? 32 /* AssertES2018 */ : 64 /* AssertES2017 */;
        }
        // function expressions with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        // If a FunctionExpression is generator function and is the body of a
        // transformed async function, then this node can be transformed to a
        // down-level generator.
        if (node.asteriskToken) {
            transformFlags |= 512 /* AssertGenerator */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~538925056 /* FunctionExcludes */;
    }
    function computeArrowFunction(node, subtreeFlags) {
        // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction.
        var transformFlags = subtreeFlags | 256 /* AssertES2015 */;
        // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
        // syntax.
        if (ts.hasModifier(node, 2270 /* TypeScriptModifier */)
            || node.typeParameters
            || node.type) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        // An async arrow function is ES2017 syntax.
        if (ts.hasModifier(node, 256 /* Async */)) {
            transformFlags |= 64 /* AssertES2017 */;
        }
        // arrow functions with object rest destructuring are ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~538920960 /* ArrowFunctionExcludes */;
    }
    function computePropertyAccess(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (node.flags & 32 /* OptionalChain */) {
            transformFlags |= 8 /* ContainsES2020 */;
        }
        // If a PropertyAccessExpression starts with a super keyword, then it is
        // ES6 syntax, and requires a lexical `this` binding.
        if (node.expression.kind === 102 /* SuperKeyword */) {
            // super inside of an async function requires hoisting the super access (ES2017).
            // same for super inside of an async generator, which is ES2018.
            transformFlags |= 64 /* ContainsES2017 */ | 32 /* ContainsES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* PropertyAccessExcludes */;
    }
    function computeElementAccess(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        if (node.flags & 32 /* OptionalChain */) {
            transformFlags |= 8 /* ContainsES2020 */;
        }
        // If an ElementAccessExpression starts with a super keyword, then it is
        // ES6 syntax, and requires a lexical `this` binding.
        if (node.expression.kind === 102 /* SuperKeyword */) {
            // super inside of an async function requires hoisting the super access (ES2017).
            // same for super inside of an async generator, which is ES2018.
            transformFlags |= 64 /* ContainsES2017 */ | 32 /* ContainsES2018 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* PropertyAccessExcludes */;
    }
    function computeVariableDeclaration(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        transformFlags |= 256 /* AssertES2015 */ | 131072 /* ContainsBindingPattern */; // TODO(rbuckton): Why are these set unconditionally?
        // A VariableDeclaration containing ObjectRest is ES2018 syntax
        if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
            transformFlags |= 32 /* AssertES2018 */;
        }
        // Type annotations are TypeScript syntax.
        if (node.type || node.exclamationToken) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeVariableStatement(node, subtreeFlags) {
        var transformFlags;
        var declarationListTransformFlags = node.declarationList.transformFlags;
        // An ambient declaration is TypeScript syntax.
        if (ts.hasModifier(node, 2 /* Ambient */)) {
            transformFlags = 1 /* AssertTypeScript */;
        }
        else {
            transformFlags = subtreeFlags;
            if (declarationListTransformFlags & 131072 /* ContainsBindingPattern */) {
                transformFlags |= 256 /* AssertES2015 */;
            }
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeLabeledStatement(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // A labeled statement containing a block scoped binding *may* need to be transformed from ES6.
        if (subtreeFlags & 65536 /* ContainsBlockScopedBinding */
            && ts.isIterationStatement(node, /*lookInLabeledStatements*/ true)) {
            transformFlags |= 256 /* AssertES2015 */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeImportEquals(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        // An ImportEqualsDeclaration with a namespace reference is TypeScript.
        if (!ts.isExternalModuleImportEqualsDeclaration(node)) {
            transformFlags |= 1 /* AssertTypeScript */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeExpressionStatement(node, subtreeFlags) {
        var transformFlags = subtreeFlags;
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~536870912 /* NodeExcludes */;
    }
    function computeModuleDeclaration(node, subtreeFlags) {
        var transformFlags = 1 /* AssertTypeScript */;
        var modifierFlags = ts.getModifierFlags(node);
        if ((modifierFlags & 2 /* Ambient */) === 0) {
            transformFlags |= subtreeFlags;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537991168 /* ModuleExcludes */;
    }
    function computeVariableDeclarationList(node, subtreeFlags) {
        var transformFlags = subtreeFlags | 1048576 /* ContainsHoistedDeclarationOrCompletion */;
        if (subtreeFlags & 131072 /* ContainsBindingPattern */) {
            transformFlags |= 256 /* AssertES2015 */;
        }
        // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax.
        if (node.flags & 3 /* BlockScoped */) {
            transformFlags |= 256 /* AssertES2015 */ | 65536 /* ContainsBlockScopedBinding */;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~537018368 /* VariableDeclarationListExcludes */;
    }
    function computeOther(node, kind, subtreeFlags) {
        // Mark transformations needed for each node
        var transformFlags = subtreeFlags;
        var excludeFlags = 536870912 /* NodeExcludes */;
        switch (kind) {
            case 126 /* AsyncKeyword */:
                // async is ES2017 syntax, but may be ES2018 syntax (for async generators)
                transformFlags |= 32 /* AssertES2018 */ | 64 /* AssertES2017 */;
                break;
            case 206 /* AwaitExpression */:
                // await is ES2017 syntax, but may be ES2018 syntax (for async generators)
                transformFlags |= 32 /* AssertES2018 */ | 64 /* AssertES2017 */ | 524288 /* ContainsAwait */;
                break;
            case 199 /* TypeAssertionExpression */:
            case 217 /* AsExpression */:
            case 326 /* PartiallyEmittedExpression */:
                // These nodes are TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                excludeFlags = 536870912 /* OuterExpressionExcludes */;
                break;
            case 119 /* PublicKeyword */:
            case 117 /* PrivateKeyword */:
            case 118 /* ProtectedKeyword */:
            case 122 /* AbstractKeyword */:
            case 130 /* DeclareKeyword */:
            case 81 /* ConstKeyword */:
            case 248 /* EnumDeclaration */:
            case 284 /* EnumMember */:
            case 218 /* NonNullExpression */:
            case 138 /* ReadonlyKeyword */:
                // These nodes are TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */;
                break;
            case 266 /* JsxElement */:
            case 11 /* JsxText */:
            case 269 /* JsxClosingElement */:
            case 270 /* JsxFragment */:
            case 271 /* JsxOpeningFragment */:
            case 272 /* JsxClosingFragment */:
            case 273 /* JsxAttribute */:
            case 274 /* JsxAttributes */:
            case 275 /* JsxSpreadAttribute */:
            case 276 /* JsxExpression */:
                // These nodes are Jsx syntax.
                transformFlags |= 2 /* AssertJsx */;
                break;
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 15 /* TemplateHead */:
            case 16 /* TemplateMiddle */:
            case 17 /* TemplateTail */:
                if (node.templateFlags) {
                    transformFlags |= 32 /* AssertES2018 */;
                    break;
                }
            // falls through
            case 198 /* TaggedTemplateExpression */:
                if (ts.hasInvalidEscape(node.template)) {
                    transformFlags |= 32 /* AssertES2018 */;
                    break;
                }
            // falls through
            case 211 /* TemplateExpression */:
            case 282 /* ShorthandPropertyAssignment */:
            case 120 /* StaticKeyword */:
            case 219 /* MetaProperty */:
                // These nodes are ES6 syntax.
                transformFlags |= 256 /* AssertES2015 */;
                break;
            case 10 /* StringLiteral */:
                if (node.hasExtendedUnicodeEscape) {
                    transformFlags |= 256 /* AssertES2015 */;
                }
                break;
            case 8 /* NumericLiteral */:
                if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) {
                    transformFlags |= 256 /* AssertES2015 */;
                }
                break;
            case 9 /* BigIntLiteral */:
                transformFlags |= 4 /* AssertESNext */;
                break;
            case 232 /* ForOfStatement */:
                // This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
                if (node.awaitModifier) {
                    transformFlags |= 32 /* AssertES2018 */;
                }
                transformFlags |= 256 /* AssertES2015 */;
                break;
            case 212 /* YieldExpression */:
                // This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async
                // generator).
                transformFlags |= 32 /* AssertES2018 */ | 256 /* AssertES2015 */ | 262144 /* ContainsYield */;
                break;
            case 125 /* AnyKeyword */:
            case 140 /* NumberKeyword */:
            case 151 /* BigIntKeyword */:
            case 137 /* NeverKeyword */:
            case 141 /* ObjectKeyword */:
            case 143 /* StringKeyword */:
            case 128 /* BooleanKeyword */:
            case 144 /* SymbolKeyword */:
            case 110 /* VoidKeyword */:
            case 155 /* TypeParameter */:
            case 158 /* PropertySignature */:
            case 160 /* MethodSignature */:
            case 165 /* CallSignature */:
            case 166 /* ConstructSignature */:
            case 167 /* IndexSignature */:
            case 168 /* TypePredicate */:
            case 169 /* TypeReference */:
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
            case 172 /* TypeQuery */:
            case 173 /* TypeLiteral */:
            case 174 /* ArrayType */:
            case 175 /* TupleType */:
            case 176 /* OptionalType */:
            case 177 /* RestType */:
            case 178 /* UnionType */:
            case 179 /* IntersectionType */:
            case 180 /* ConditionalType */:
            case 181 /* InferType */:
            case 182 /* ParenthesizedType */:
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 183 /* ThisType */:
            case 184 /* TypeOperator */:
            case 185 /* IndexedAccessType */:
            case 186 /* MappedType */:
            case 187 /* LiteralType */:
            case 252 /* NamespaceExportDeclaration */:
                // Types and signatures are TypeScript syntax, and exclude all other facts.
                transformFlags = 1 /* AssertTypeScript */;
                excludeFlags = -2 /* TypeExcludes */;
                break;
            case 154 /* ComputedPropertyName */:
                // Even though computed property names are ES6, we don't treat them as such.
                // This is so that they can flow through PropertyName transforms unaffected.
                // Instead, we mark the container as ES6, so that it can properly handle the transform.
                transformFlags |= 32768 /* ContainsComputedPropertyName */;
                break;
            case 213 /* SpreadElement */:
                transformFlags |= 256 /* AssertES2015 */ | 8192 /* ContainsRestOrSpread */;
                break;
            case 283 /* SpreadAssignment */:
                transformFlags |= 32 /* AssertES2018 */ | 16384 /* ContainsObjectRestOrSpread */;
                break;
            case 102 /* SuperKeyword */:
                // This node is ES6 syntax.
                transformFlags |= 256 /* AssertES2015 */;
                excludeFlags = 536870912 /* OuterExpressionExcludes */; // must be set to persist `Super`
                break;
            case 104 /* ThisKeyword */:
                // Mark this node and its ancestors as containing a lexical `this` keyword.
                transformFlags |= 4096 /* ContainsLexicalThis */;
                break;
            case 189 /* ObjectBindingPattern */:
                transformFlags |= 256 /* AssertES2015 */ | 131072 /* ContainsBindingPattern */;
                if (subtreeFlags & 8192 /* ContainsRestOrSpread */) {
                    transformFlags |= 32 /* AssertES2018 */ | 16384 /* ContainsObjectRestOrSpread */;
                }
                excludeFlags = 536879104 /* BindingPatternExcludes */;
                break;
            case 190 /* ArrayBindingPattern */:
                transformFlags |= 256 /* AssertES2015 */ | 131072 /* ContainsBindingPattern */;
                excludeFlags = 536879104 /* BindingPatternExcludes */;
                break;
            case 191 /* BindingElement */:
                transformFlags |= 256 /* AssertES2015 */;
                if (node.dotDotDotToken) {
                    transformFlags |= 8192 /* ContainsRestOrSpread */;
                }
                break;
            case 157 /* Decorator */:
                // This node is TypeScript syntax, and marks its container as also being TypeScript syntax.
                transformFlags |= 1 /* AssertTypeScript */ | 2048 /* ContainsTypeScriptClassSyntax */;
                break;
            case 193 /* ObjectLiteralExpression */:
                excludeFlags = 536922112 /* ObjectLiteralExcludes */;
                if (subtreeFlags & 32768 /* ContainsComputedPropertyName */) {
                    // If an ObjectLiteralExpression contains a ComputedPropertyName, then it
                    // is an ES6 node.
                    transformFlags |= 256 /* AssertES2015 */;
                }
                if (subtreeFlags & 16384 /* ContainsObjectRestOrSpread */) {
                    // If an ObjectLiteralExpression contains a spread element, then it
                    // is an ES2018 node.
                    transformFlags |= 32 /* AssertES2018 */;
                }
                break;
            case 192 /* ArrayLiteralExpression */:
                excludeFlags = 536879104 /* ArrayLiteralOrCallOrNewExcludes */;
                break;
            case 228 /* DoStatement */:
            case 229 /* WhileStatement */:
            case 230 /* ForStatement */:
            case 231 /* ForInStatement */:
                // A loop containing a block scoped binding *may* need to be transformed from ES6.
                if (subtreeFlags & 65536 /* ContainsBlockScopedBinding */) {
                    transformFlags |= 256 /* AssertES2015 */;
                }
                break;
            case 290 /* SourceFile */:
                break;
            case 262 /* NamespaceExport */:
                transformFlags |= 4 /* AssertESNext */;
                break;
            case 235 /* ReturnStatement */:
                // Return statements may require an `await` in ES2018.
                transformFlags |= 1048576 /* ContainsHoistedDeclarationOrCompletion */ | 32 /* AssertES2018 */;
                break;
            case 233 /* ContinueStatement */:
            case 234 /* BreakStatement */:
                transformFlags |= 1048576 /* ContainsHoistedDeclarationOrCompletion */;
                break;
            case 76 /* PrivateIdentifier */:
                transformFlags |= 4194304 /* ContainsClassFields */;
                break;
        }
        node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */;
        return transformFlags & ~excludeFlags;
    }
    function propagatePropertyNameFlags(node, transformFlags) {
        return transformFlags | (node.transformFlags & 4096 /* PropertyNamePropagatingFlags */);
    }
    /**
     * Gets the transform flags to exclude when unioning the transform flags of a subtree.
     *
     * NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`.
     *       For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
     *       than calling this function.
     */
    function getTransformFlagsSubtreeExclusions(kind) {
        if (kind >= 168 /* FirstTypeNode */ && kind <= 188 /* LastTypeNode */) {
            return -2 /* TypeExcludes */;
        }
        switch (kind) {
            case 196 /* CallExpression */:
            case 197 /* NewExpression */:
            case 192 /* ArrayLiteralExpression */:
                return 536879104 /* ArrayLiteralOrCallOrNewExcludes */;
            case 249 /* ModuleDeclaration */:
                return 537991168 /* ModuleExcludes */;
            case 156 /* Parameter */:
                return 536870912 /* ParameterExcludes */;
            case 202 /* ArrowFunction */:
                return 538920960 /* ArrowFunctionExcludes */;
            case 201 /* FunctionExpression */:
            case 244 /* FunctionDeclaration */:
                return 538925056 /* FunctionExcludes */;
            case 243 /* VariableDeclarationList */:
                return 537018368 /* VariableDeclarationListExcludes */;
            case 245 /* ClassDeclaration */:
            case 214 /* ClassExpression */:
                return 536905728 /* ClassExcludes */;
            case 162 /* Constructor */:
                return 538923008 /* ConstructorExcludes */;
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
                return 538923008 /* MethodOrAccessorExcludes */;
            case 125 /* AnyKeyword */:
            case 140 /* NumberKeyword */:
            case 151 /* BigIntKeyword */:
            case 137 /* NeverKeyword */:
            case 143 /* StringKeyword */:
            case 141 /* ObjectKeyword */:
            case 128 /* BooleanKeyword */:
            case 144 /* SymbolKeyword */:
            case 110 /* VoidKeyword */:
            case 155 /* TypeParameter */:
            case 158 /* PropertySignature */:
            case 160 /* MethodSignature */:
            case 165 /* CallSignature */:
            case 166 /* ConstructSignature */:
            case 167 /* IndexSignature */:
            case 246 /* InterfaceDeclaration */:
            case 247 /* TypeAliasDeclaration */:
                return -2 /* TypeExcludes */;
            case 193 /* ObjectLiteralExpression */:
                return 536922112 /* ObjectLiteralExcludes */;
            case 280 /* CatchClause */:
                return 536887296 /* CatchClauseExcludes */;
            case 189 /* ObjectBindingPattern */:
            case 190 /* ArrayBindingPattern */:
                return 536879104 /* BindingPatternExcludes */;
            case 199 /* TypeAssertionExpression */:
            case 217 /* AsExpression */:
            case 326 /* PartiallyEmittedExpression */:
            case 200 /* ParenthesizedExpression */:
            case 102 /* SuperKeyword */:
                return 536870912 /* OuterExpressionExcludes */;
            case 194 /* PropertyAccessExpression */:
            case 195 /* ElementAccessExpression */:
                return 536870912 /* PropertyAccessExcludes */;
            default:
                return 536870912 /* NodeExcludes */;
        }
    }
    ts.getTransformFlagsSubtreeExclusions = getTransformFlagsSubtreeExclusions;
    /**
     * "Binds" JSDoc nodes in TypeScript code.
     * Since we will never create symbols for JSDoc, we just set parent pointers instead.
     */
    function setParentPointers(parent, child) {
        child.parent = parent;
        ts.forEachChild(child, function (grandchild) { return setParentPointers(child, grandchild); });
    }
})(ts || (ts = {}));
/** @internal */
var ts;
(function (ts) {
    function createGetSymbolWalker(getRestTypeOfSignature, getTypePredicateOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintOfTypeParameter, getFirstIdentifier, getTypeArguments) {
        return getSymbolWalker;
        function getSymbolWalker(accept) {
            if (accept === void 0) { accept = function () { return true; }; }
            var visitedTypes = []; // Sparse array from id to type
            var visitedSymbols = []; // Sparse array from id to symbol
            return {
                walkType: function (type) {
                    try {
                        visitType(type);
                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
                    }
                    finally {
                        ts.clear(visitedTypes);
                        ts.clear(visitedSymbols);
                    }
                },
                walkSymbol: function (symbol) {
                    try {
                        visitSymbol(symbol);
                        return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) };
                    }
                    finally {
                        ts.clear(visitedTypes);
                        ts.clear(visitedSymbols);
                    }
                },
            };
            function visitType(type) {
                if (!type) {
                    return;
                }
                if (visitedTypes[type.id]) {
                    return;
                }
                visitedTypes[type.id] = type;
                // Reuse visitSymbol to visit the type's symbol,
                //  but be sure to bail on recuring into the type if accept declines the symbol.
                var shouldBail = visitSymbol(type.symbol);
                if (shouldBail)
                    return;
                // Visit the type's related types, if any
                if (type.flags & 524288 /* Object */) {
                    var objectType = type;
                    var objectFlags = objectType.objectFlags;
                    if (objectFlags & 4 /* Reference */) {
                        visitTypeReference(type);
                    }
                    if (objectFlags & 32 /* Mapped */) {
                        visitMappedType(type);
                    }
                    if (objectFlags & (1 /* Class */ | 2 /* Interface */)) {
                        visitInterfaceType(type);
                    }
                    if (objectFlags & (8 /* Tuple */ | 16 /* Anonymous */)) {
                        visitObjectType(objectType);
                    }
                }
                if (type.flags & 262144 /* TypeParameter */) {
                    visitTypeParameter(type);
                }
                if (type.flags & 3145728 /* UnionOrIntersection */) {
                    visitUnionOrIntersectionType(type);
                }
                if (type.flags & 4194304 /* Index */) {
                    visitIndexType(type);
                }
                if (type.flags & 8388608 /* IndexedAccess */) {
                    visitIndexedAccessType(type);
                }
            }
            function visitTypeReference(type) {
                visitType(type.target);
                ts.forEach(getTypeArguments(type), visitType);
            }
            function visitTypeParameter(type) {
                visitType(getConstraintOfTypeParameter(type));
            }
            function visitUnionOrIntersectionType(type) {
                ts.forEach(type.types, visitType);
            }
            function visitIndexType(type) {
                visitType(type.type);
            }
            function visitIndexedAccessType(type) {
                visitType(type.objectType);
                visitType(type.indexType);
                visitType(type.constraint);
            }
            function visitMappedType(type) {
                visitType(type.typeParameter);
                visitType(type.constraintType);
                visitType(type.templateType);
                visitType(type.modifiersType);
            }
            function visitSignature(signature) {
                var typePredicate = getTypePredicateOfSignature(signature);
                if (typePredicate) {
                    visitType(typePredicate.type);
                }
                ts.forEach(signature.typeParameters, visitType);
                for (var _i = 0, _a = signature.parameters; _i < _a.length; _i++) {
                    var parameter = _a[_i];
                    visitSymbol(parameter);
                }
                visitType(getRestTypeOfSignature(signature));
                visitType(getReturnTypeOfSignature(signature));
            }
            function visitInterfaceType(interfaceT) {
                visitObjectType(interfaceT);
                ts.forEach(interfaceT.typeParameters, visitType);
                ts.forEach(getBaseTypes(interfaceT), visitType);
                visitType(interfaceT.thisType);
            }
            function visitObjectType(type) {
                var stringIndexType = getIndexTypeOfStructuredType(type, 0 /* String */);
                visitType(stringIndexType);
                var numberIndexType = getIndexTypeOfStructuredType(type, 1 /* Number */);
                visitType(numberIndexType);
                // The two checks above *should* have already resolved the type (if needed), so this should be cached
                var resolved = resolveStructuredTypeMembers(type);
                for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    visitSignature(signature);
                }
                for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) {
                    var signature = _c[_b];
                    visitSignature(signature);
                }
                for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) {
                    var p = _e[_d];
                    visitSymbol(p);
                }
            }
            function visitSymbol(symbol) {
                if (!symbol) {
                    return false;
                }
                var symbolId = ts.getSymbolId(symbol);
                if (visitedSymbols[symbolId]) {
                    return false;
                }
                visitedSymbols[symbolId] = symbol;
                if (!accept(symbol)) {
                    return true;
                }
                var t = getTypeOfSymbol(symbol);
                visitType(t); // Should handle members on classes and such
                if (symbol.exports) {
                    symbol.exports.forEach(visitSymbol);
                }
                ts.forEach(symbol.declarations, function (d) {
                    // Type queries are too far resolved when we just visit the symbol's type
                    //  (their type resolved directly to the member deeply referenced)
                    // So to get the intervening symbols, we need to check if there's a type
                    // query node on any of the symbol's declarations and get symbols there
                    if (d.type && d.type.kind === 172 /* TypeQuery */) {
                        var query = d.type;
                        var entity = getResolvedSymbol(getFirstIdentifier(query.exprName));
                        visitSymbol(entity);
                    }
                });
                return false;
            }
        }
    }
    ts.createGetSymbolWalker = createGetSymbolWalker;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var ambientModuleSymbolRegex = /^".+"$/;
    var anon = "(anonymous)";
    var nextSymbolId = 1;
    var nextNodeId = 1;
    var nextMergeId = 1;
    var nextFlowId = 1;
    var IterationUse;
    (function (IterationUse) {
        IterationUse[IterationUse["AllowsSyncIterablesFlag"] = 1] = "AllowsSyncIterablesFlag";
        IterationUse[IterationUse["AllowsAsyncIterablesFlag"] = 2] = "AllowsAsyncIterablesFlag";
        IterationUse[IterationUse["AllowsStringInputFlag"] = 4] = "AllowsStringInputFlag";
        IterationUse[IterationUse["ForOfFlag"] = 8] = "ForOfFlag";
        IterationUse[IterationUse["YieldStarFlag"] = 16] = "YieldStarFlag";
        IterationUse[IterationUse["SpreadFlag"] = 32] = "SpreadFlag";
        IterationUse[IterationUse["DestructuringFlag"] = 64] = "DestructuringFlag";
        // Spread, Destructuring, Array element assignment
        IterationUse[IterationUse["Element"] = 1] = "Element";
        IterationUse[IterationUse["Spread"] = 33] = "Spread";
        IterationUse[IterationUse["Destructuring"] = 65] = "Destructuring";
        IterationUse[IterationUse["ForOf"] = 13] = "ForOf";
        IterationUse[IterationUse["ForAwaitOf"] = 15] = "ForAwaitOf";
        IterationUse[IterationUse["YieldStar"] = 17] = "YieldStar";
        IterationUse[IterationUse["AsyncYieldStar"] = 19] = "AsyncYieldStar";
        IterationUse[IterationUse["GeneratorReturnType"] = 1] = "GeneratorReturnType";
        IterationUse[IterationUse["AsyncGeneratorReturnType"] = 2] = "AsyncGeneratorReturnType";
    })(IterationUse || (IterationUse = {}));
    var IterationTypeKind;
    (function (IterationTypeKind) {
        IterationTypeKind[IterationTypeKind["Yield"] = 0] = "Yield";
        IterationTypeKind[IterationTypeKind["Return"] = 1] = "Return";
        IterationTypeKind[IterationTypeKind["Next"] = 2] = "Next";
    })(IterationTypeKind || (IterationTypeKind = {}));
    var WideningKind;
    (function (WideningKind) {
        WideningKind[WideningKind["Normal"] = 0] = "Normal";
        WideningKind[WideningKind["FunctionReturn"] = 1] = "FunctionReturn";
        WideningKind[WideningKind["GeneratorNext"] = 2] = "GeneratorNext";
        WideningKind[WideningKind["GeneratorYield"] = 3] = "GeneratorYield";
    })(WideningKind || (WideningKind = {}));
    var TypeFacts;
    (function (TypeFacts) {
        TypeFacts[TypeFacts["None"] = 0] = "None";
        TypeFacts[TypeFacts["TypeofEQString"] = 1] = "TypeofEQString";
        TypeFacts[TypeFacts["TypeofEQNumber"] = 2] = "TypeofEQNumber";
        TypeFacts[TypeFacts["TypeofEQBigInt"] = 4] = "TypeofEQBigInt";
        TypeFacts[TypeFacts["TypeofEQBoolean"] = 8] = "TypeofEQBoolean";
        TypeFacts[TypeFacts["TypeofEQSymbol"] = 16] = "TypeofEQSymbol";
        TypeFacts[TypeFacts["TypeofEQObject"] = 32] = "TypeofEQObject";
        TypeFacts[TypeFacts["TypeofEQFunction"] = 64] = "TypeofEQFunction";
        TypeFacts[TypeFacts["TypeofEQHostObject"] = 128] = "TypeofEQHostObject";
        TypeFacts[TypeFacts["TypeofNEString"] = 256] = "TypeofNEString";
        TypeFacts[TypeFacts["TypeofNENumber"] = 512] = "TypeofNENumber";
        TypeFacts[TypeFacts["TypeofNEBigInt"] = 1024] = "TypeofNEBigInt";
        TypeFacts[TypeFacts["TypeofNEBoolean"] = 2048] = "TypeofNEBoolean";
        TypeFacts[TypeFacts["TypeofNESymbol"] = 4096] = "TypeofNESymbol";
        TypeFacts[TypeFacts["TypeofNEObject"] = 8192] = "TypeofNEObject";
        TypeFacts[TypeFacts["TypeofNEFunction"] = 16384] = "TypeofNEFunction";
        TypeFacts[TypeFacts["TypeofNEHostObject"] = 32768] = "TypeofNEHostObject";
        TypeFacts[TypeFacts["EQUndefined"] = 65536] = "EQUndefined";
        TypeFacts[TypeFacts["EQNull"] = 131072] = "EQNull";
        TypeFacts[TypeFacts["EQUndefinedOrNull"] = 262144] = "EQUndefinedOrNull";
        TypeFacts[TypeFacts["NEUndefined"] = 524288] = "NEUndefined";
        TypeFacts[TypeFacts["NENull"] = 1048576] = "NENull";
        TypeFacts[TypeFacts["NEUndefinedOrNull"] = 2097152] = "NEUndefinedOrNull";
        TypeFacts[TypeFacts["Truthy"] = 4194304] = "Truthy";
        TypeFacts[TypeFacts["Falsy"] = 8388608] = "Falsy";
        TypeFacts[TypeFacts["All"] = 16777215] = "All";
        // The following members encode facts about particular kinds of types for use in the getTypeFacts function.
        // The presence of a particular fact means that the given test is true for some (and possibly all) values
        // of that kind of type.
        TypeFacts[TypeFacts["BaseStringStrictFacts"] = 3735041] = "BaseStringStrictFacts";
        TypeFacts[TypeFacts["BaseStringFacts"] = 12582401] = "BaseStringFacts";
        TypeFacts[TypeFacts["StringStrictFacts"] = 16317953] = "StringStrictFacts";
        TypeFacts[TypeFacts["StringFacts"] = 16776705] = "StringFacts";
        TypeFacts[TypeFacts["EmptyStringStrictFacts"] = 12123649] = "EmptyStringStrictFacts";
        TypeFacts[TypeFacts["EmptyStringFacts"] = 12582401] = "EmptyStringFacts";
        TypeFacts[TypeFacts["NonEmptyStringStrictFacts"] = 7929345] = "NonEmptyStringStrictFacts";
        TypeFacts[TypeFacts["NonEmptyStringFacts"] = 16776705] = "NonEmptyStringFacts";
        TypeFacts[TypeFacts["BaseNumberStrictFacts"] = 3734786] = "BaseNumberStrictFacts";
        TypeFacts[TypeFacts["BaseNumberFacts"] = 12582146] = "BaseNumberFacts";
        TypeFacts[TypeFacts["NumberStrictFacts"] = 16317698] = "NumberStrictFacts";
        TypeFacts[TypeFacts["NumberFacts"] = 16776450] = "NumberFacts";
        TypeFacts[TypeFacts["ZeroNumberStrictFacts"] = 12123394] = "ZeroNumberStrictFacts";
        TypeFacts[TypeFacts["ZeroNumberFacts"] = 12582146] = "ZeroNumberFacts";
        TypeFacts[TypeFacts["NonZeroNumberStrictFacts"] = 7929090] = "NonZeroNumberStrictFacts";
        TypeFacts[TypeFacts["NonZeroNumberFacts"] = 16776450] = "NonZeroNumberFacts";
        TypeFacts[TypeFacts["BaseBigIntStrictFacts"] = 3734276] = "BaseBigIntStrictFacts";
        TypeFacts[TypeFacts["BaseBigIntFacts"] = 12581636] = "BaseBigIntFacts";
        TypeFacts[TypeFacts["BigIntStrictFacts"] = 16317188] = "BigIntStrictFacts";
        TypeFacts[TypeFacts["BigIntFacts"] = 16775940] = "BigIntFacts";
        TypeFacts[TypeFacts["ZeroBigIntStrictFacts"] = 12122884] = "ZeroBigIntStrictFacts";
        TypeFacts[TypeFacts["ZeroBigIntFacts"] = 12581636] = "ZeroBigIntFacts";
        TypeFacts[TypeFacts["NonZeroBigIntStrictFacts"] = 7928580] = "NonZeroBigIntStrictFacts";
        TypeFacts[TypeFacts["NonZeroBigIntFacts"] = 16775940] = "NonZeroBigIntFacts";
        TypeFacts[TypeFacts["BaseBooleanStrictFacts"] = 3733256] = "BaseBooleanStrictFacts";
        TypeFacts[TypeFacts["BaseBooleanFacts"] = 12580616] = "BaseBooleanFacts";
        TypeFacts[TypeFacts["BooleanStrictFacts"] = 16316168] = "BooleanStrictFacts";
        TypeFacts[TypeFacts["BooleanFacts"] = 16774920] = "BooleanFacts";
        TypeFacts[TypeFacts["FalseStrictFacts"] = 12121864] = "FalseStrictFacts";
        TypeFacts[TypeFacts["FalseFacts"] = 12580616] = "FalseFacts";
        TypeFacts[TypeFacts["TrueStrictFacts"] = 7927560] = "TrueStrictFacts";
        TypeFacts[TypeFacts["TrueFacts"] = 16774920] = "TrueFacts";
        TypeFacts[TypeFacts["SymbolStrictFacts"] = 7925520] = "SymbolStrictFacts";
        TypeFacts[TypeFacts["SymbolFacts"] = 16772880] = "SymbolFacts";
        TypeFacts[TypeFacts["ObjectStrictFacts"] = 7888800] = "ObjectStrictFacts";
        TypeFacts[TypeFacts["ObjectFacts"] = 16736160] = "ObjectFacts";
        TypeFacts[TypeFacts["FunctionStrictFacts"] = 7880640] = "FunctionStrictFacts";
        TypeFacts[TypeFacts["FunctionFacts"] = 16728000] = "FunctionFacts";
        TypeFacts[TypeFacts["UndefinedFacts"] = 9830144] = "UndefinedFacts";
        TypeFacts[TypeFacts["NullFacts"] = 9363232] = "NullFacts";
        TypeFacts[TypeFacts["EmptyObjectStrictFacts"] = 16318463] = "EmptyObjectStrictFacts";
        TypeFacts[TypeFacts["EmptyObjectFacts"] = 16777215] = "EmptyObjectFacts";
    })(TypeFacts || (TypeFacts = {}));
    var typeofEQFacts = ts.createMapFromTemplate({
        string: 1 /* TypeofEQString */,
        number: 2 /* TypeofEQNumber */,
        bigint: 4 /* TypeofEQBigInt */,
        boolean: 8 /* TypeofEQBoolean */,
        symbol: 16 /* TypeofEQSymbol */,
        undefined: 65536 /* EQUndefined */,
        object: 32 /* TypeofEQObject */,
        function: 64 /* TypeofEQFunction */
    });
    var typeofNEFacts = ts.createMapFromTemplate({
        string: 256 /* TypeofNEString */,
        number: 512 /* TypeofNENumber */,
        bigint: 1024 /* TypeofNEBigInt */,
        boolean: 2048 /* TypeofNEBoolean */,
        symbol: 4096 /* TypeofNESymbol */,
        undefined: 524288 /* NEUndefined */,
        object: 8192 /* TypeofNEObject */,
        function: 16384 /* TypeofNEFunction */
    });
    var TypeSystemPropertyName;
    (function (TypeSystemPropertyName) {
        TypeSystemPropertyName[TypeSystemPropertyName["Type"] = 0] = "Type";
        TypeSystemPropertyName[TypeSystemPropertyName["ResolvedBaseConstructorType"] = 1] = "ResolvedBaseConstructorType";
        TypeSystemPropertyName[TypeSystemPropertyName["DeclaredType"] = 2] = "DeclaredType";
        TypeSystemPropertyName[TypeSystemPropertyName["ResolvedReturnType"] = 3] = "ResolvedReturnType";
        TypeSystemPropertyName[TypeSystemPropertyName["ImmediateBaseConstraint"] = 4] = "ImmediateBaseConstraint";
        TypeSystemPropertyName[TypeSystemPropertyName["EnumTagType"] = 5] = "EnumTagType";
        TypeSystemPropertyName[TypeSystemPropertyName["ResolvedTypeArguments"] = 6] = "ResolvedTypeArguments";
    })(TypeSystemPropertyName || (TypeSystemPropertyName = {}));
    var CheckMode;
    (function (CheckMode) {
        CheckMode[CheckMode["Normal"] = 0] = "Normal";
        CheckMode[CheckMode["Contextual"] = 1] = "Contextual";
        CheckMode[CheckMode["Inferential"] = 2] = "Inferential";
        CheckMode[CheckMode["SkipContextSensitive"] = 4] = "SkipContextSensitive";
        CheckMode[CheckMode["SkipGenericFunctions"] = 8] = "SkipGenericFunctions";
        CheckMode[CheckMode["IsForSignatureHelp"] = 16] = "IsForSignatureHelp";
    })(CheckMode || (CheckMode = {}));
    var AccessFlags;
    (function (AccessFlags) {
        AccessFlags[AccessFlags["None"] = 0] = "None";
        AccessFlags[AccessFlags["NoIndexSignatures"] = 1] = "NoIndexSignatures";
        AccessFlags[AccessFlags["Writing"] = 2] = "Writing";
        AccessFlags[AccessFlags["CacheSymbol"] = 4] = "CacheSymbol";
        AccessFlags[AccessFlags["NoTupleBoundsCheck"] = 8] = "NoTupleBoundsCheck";
    })(AccessFlags || (AccessFlags = {}));
    var SignatureCheckMode;
    (function (SignatureCheckMode) {
        SignatureCheckMode[SignatureCheckMode["BivariantCallback"] = 1] = "BivariantCallback";
        SignatureCheckMode[SignatureCheckMode["StrictCallback"] = 2] = "StrictCallback";
        SignatureCheckMode[SignatureCheckMode["IgnoreReturnTypes"] = 4] = "IgnoreReturnTypes";
        SignatureCheckMode[SignatureCheckMode["StrictArity"] = 8] = "StrictArity";
        SignatureCheckMode[SignatureCheckMode["Callback"] = 3] = "Callback";
    })(SignatureCheckMode || (SignatureCheckMode = {}));
    var IntersectionState;
    (function (IntersectionState) {
        IntersectionState[IntersectionState["None"] = 0] = "None";
        IntersectionState[IntersectionState["Source"] = 1] = "Source";
        IntersectionState[IntersectionState["Target"] = 2] = "Target";
        IntersectionState[IntersectionState["PropertyCheck"] = 4] = "PropertyCheck";
        IntersectionState[IntersectionState["InPropertyCheck"] = 8] = "InPropertyCheck";
    })(IntersectionState || (IntersectionState = {}));
    var MappedTypeModifiers;
    (function (MappedTypeModifiers) {
        MappedTypeModifiers[MappedTypeModifiers["IncludeReadonly"] = 1] = "IncludeReadonly";
        MappedTypeModifiers[MappedTypeModifiers["ExcludeReadonly"] = 2] = "ExcludeReadonly";
        MappedTypeModifiers[MappedTypeModifiers["IncludeOptional"] = 4] = "IncludeOptional";
        MappedTypeModifiers[MappedTypeModifiers["ExcludeOptional"] = 8] = "ExcludeOptional";
    })(MappedTypeModifiers || (MappedTypeModifiers = {}));
    var ExpandingFlags;
    (function (ExpandingFlags) {
        ExpandingFlags[ExpandingFlags["None"] = 0] = "None";
        ExpandingFlags[ExpandingFlags["Source"] = 1] = "Source";
        ExpandingFlags[ExpandingFlags["Target"] = 2] = "Target";
        ExpandingFlags[ExpandingFlags["Both"] = 3] = "Both";
    })(ExpandingFlags || (ExpandingFlags = {}));
    var MembersOrExportsResolutionKind;
    (function (MembersOrExportsResolutionKind) {
        MembersOrExportsResolutionKind["resolvedExports"] = "resolvedExports";
        MembersOrExportsResolutionKind["resolvedMembers"] = "resolvedMembers";
    })(MembersOrExportsResolutionKind || (MembersOrExportsResolutionKind = {}));
    var UnusedKind;
    (function (UnusedKind) {
        UnusedKind[UnusedKind["Local"] = 0] = "Local";
        UnusedKind[UnusedKind["Parameter"] = 1] = "Parameter";
    })(UnusedKind || (UnusedKind = {}));
    var isNotOverloadAndNotAccessor = ts.and(isNotOverload, isNotAccessor);
    var DeclarationMeaning;
    (function (DeclarationMeaning) {
        DeclarationMeaning[DeclarationMeaning["GetAccessor"] = 1] = "GetAccessor";
        DeclarationMeaning[DeclarationMeaning["SetAccessor"] = 2] = "SetAccessor";
        DeclarationMeaning[DeclarationMeaning["PropertyAssignment"] = 4] = "PropertyAssignment";
        DeclarationMeaning[DeclarationMeaning["Method"] = 8] = "Method";
        DeclarationMeaning[DeclarationMeaning["GetOrSetAccessor"] = 3] = "GetOrSetAccessor";
        DeclarationMeaning[DeclarationMeaning["PropertyAssignmentOrMethod"] = 12] = "PropertyAssignmentOrMethod";
    })(DeclarationMeaning || (DeclarationMeaning = {}));
    var DeclarationSpaces;
    (function (DeclarationSpaces) {
        DeclarationSpaces[DeclarationSpaces["None"] = 0] = "None";
        DeclarationSpaces[DeclarationSpaces["ExportValue"] = 1] = "ExportValue";
        DeclarationSpaces[DeclarationSpaces["ExportType"] = 2] = "ExportType";
        DeclarationSpaces[DeclarationSpaces["ExportNamespace"] = 4] = "ExportNamespace";
    })(DeclarationSpaces || (DeclarationSpaces = {}));
    function SymbolLinks() {
    }
    function NodeLinks() {
        this.flags = 0;
    }
    function getNodeId(node) {
        if (!node.id) {
            node.id = nextNodeId;
            nextNodeId++;
        }
        return node.id;
    }
    ts.getNodeId = getNodeId;
    function getSymbolId(symbol) {
        if (!symbol.id) {
            symbol.id = nextSymbolId;
            nextSymbolId++;
        }
        return symbol.id;
    }
    ts.getSymbolId = getSymbolId;
    function isInstantiatedModule(node, preserveConstEnums) {
        var moduleState = ts.getModuleInstanceState(node);
        return moduleState === 1 /* Instantiated */ ||
            (preserveConstEnums && moduleState === 2 /* ConstEnumOnly */);
    }
    ts.isInstantiatedModule = isInstantiatedModule;
    function createTypeChecker(host, produceDiagnostics) {
        var getPackagesSet = ts.memoize(function () {
            var set = ts.createMap();
            host.getSourceFiles().forEach(function (sf) {
                if (!sf.resolvedModules)
                    return;
                ts.forEachEntry(sf.resolvedModules, function (r) {
                    if (r && r.packageId)
                        set.set(r.packageId.name, true);
                });
            });
            return set;
        });
        // Cancellation that controls whether or not we can cancel in the middle of type checking.
        // In general cancelling is *not* safe for the type checker.  We might be in the middle of
        // computing something, and we will leave our internals in an inconsistent state.  Callers
        // who set the cancellation token should catch if a cancellation exception occurs, and
        // should throw away and create a new TypeChecker.
        //
        // Currently we only support setting the cancellation token when getting diagnostics.  This
        // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if
        // they no longer need the information (for example, if the user started editing again).
        var cancellationToken;
        var requestedExternalEmitHelpers;
        var externalHelpersModule;
        var Symbol = ts.objectAllocator.getSymbolConstructor();
        var Type = ts.objectAllocator.getTypeConstructor();
        var Signature = ts.objectAllocator.getSignatureConstructor();
        var typeCount = 0;
        var symbolCount = 0;
        var enumCount = 0;
        var totalInstantiationCount = 0;
        var instantiationCount = 0;
        var instantiationDepth = 0;
        var constraintDepth = 0;
        var currentNode;
        var emptySymbols = ts.createSymbolTable();
        var arrayVariances = [1 /* Covariant */];
        var compilerOptions = host.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var allowSyntheticDefaultImports = ts.getAllowSyntheticDefaultImports(compilerOptions);
        var strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks");
        var strictFunctionTypes = ts.getStrictOptionValue(compilerOptions, "strictFunctionTypes");
        var strictBindCallApply = ts.getStrictOptionValue(compilerOptions, "strictBindCallApply");
        var strictPropertyInitialization = ts.getStrictOptionValue(compilerOptions, "strictPropertyInitialization");
        var noImplicitAny = ts.getStrictOptionValue(compilerOptions, "noImplicitAny");
        var noImplicitThis = ts.getStrictOptionValue(compilerOptions, "noImplicitThis");
        var keyofStringsOnly = !!compilerOptions.keyofStringsOnly;
        var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 32768 /* FreshLiteral */;
        var emitResolver = createResolver();
        var nodeBuilder = createNodeBuilder();
        var globals = ts.createSymbolTable();
        var undefinedSymbol = createSymbol(4 /* Property */, "undefined");
        undefinedSymbol.declarations = [];
        var globalThisSymbol = createSymbol(1536 /* Module */, "globalThis", 8 /* Readonly */);
        globalThisSymbol.exports = globals;
        globalThisSymbol.declarations = [];
        globals.set(globalThisSymbol.escapedName, globalThisSymbol);
        var argumentsSymbol = createSymbol(4 /* Property */, "arguments");
        var requireSymbol = createSymbol(4 /* Property */, "require");
        /** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
        var apparentArgumentCount;
        // for public members that accept a Node or one of its subtypes, we must guard against
        // synthetic nodes created during transformations by calling `getParseTreeNode`.
        // for most of these, we perform the guard only on `checker` to avoid any possible
        // extra cost of calling `getParseTreeNode` when calling these functions from inside the
        // checker.
        var checker = {
            getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); },
            getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); },
            getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; },
            getTypeCount: function () { return typeCount; },
            getInstantiationCount: function () { return totalInstantiationCount; },
            getRelationCacheSizes: function () { return ({
                assignable: assignableRelation.size,
                identity: identityRelation.size,
                subtype: subtypeRelation.size,
                strictSubtype: strictSubtypeRelation.size,
            }); },
            isUndefinedSymbol: function (symbol) { return symbol === undefinedSymbol; },
            isArgumentsSymbol: function (symbol) { return symbol === argumentsSymbol; },
            isUnknownSymbol: function (symbol) { return symbol === unknownSymbol; },
            getMergedSymbol: getMergedSymbol,
            getDiagnostics: getDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getTypeOfSymbolAtLocation: function (symbol, location) {
                location = ts.getParseTreeNode(location);
                return location ? getTypeOfSymbolAtLocation(symbol, location) : errorType;
            },
            getSymbolsOfParameterPropertyDeclaration: function (parameterIn, parameterName) {
                var parameter = ts.getParseTreeNode(parameterIn, ts.isParameter);
                if (parameter === undefined)
                    return ts.Debug.fail("Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node.");
                return getSymbolsOfParameterPropertyDeclaration(parameter, ts.escapeLeadingUnderscores(parameterName));
            },
            getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
            getPropertiesOfType: getPropertiesOfType,
            getPropertyOfType: function (type, name) { return getPropertyOfType(type, ts.escapeLeadingUnderscores(name)); },
            getPrivateIdentifierPropertyOfType: function (leftType, name, location) {
                var node = ts.getParseTreeNode(location);
                if (!node) {
                    return undefined;
                }
                var propName = ts.escapeLeadingUnderscores(name);
                var lexicallyScopedIdentifier = lookupSymbolForPrivateIdentifierDeclaration(propName, node);
                return lexicallyScopedIdentifier ? getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedIdentifier) : undefined;
            },
            getTypeOfPropertyOfType: function (type, name) { return getTypeOfPropertyOfType(type, ts.escapeLeadingUnderscores(name)); },
            getIndexInfoOfType: getIndexInfoOfType,
            getSignaturesOfType: getSignaturesOfType,
            getIndexTypeOfType: getIndexTypeOfType,
            getBaseTypes: getBaseTypes,
            getBaseTypeOfLiteralType: getBaseTypeOfLiteralType,
            getWidenedType: getWidenedType,
            getTypeFromTypeNode: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isTypeNode);
                return node ? getTypeFromTypeNode(node) : errorType;
            },
            getParameterType: getTypeAtPosition,
            getPromisedTypeOfPromise: getPromisedTypeOfPromise,
            getReturnTypeOfSignature: getReturnTypeOfSignature,
            isNullableType: isNullableType,
            getNullableType: getNullableType,
            getNonNullableType: getNonNullableType,
            getNonOptionalType: removeOptionalTypeMarker,
            getTypeArguments: getTypeArguments,
            typeToTypeNode: nodeBuilder.typeToTypeNode,
            indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration,
            signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration,
            symbolToEntityName: nodeBuilder.symbolToEntityName,
            symbolToExpression: nodeBuilder.symbolToExpression,
            symbolToTypeParameterDeclarations: nodeBuilder.symbolToTypeParameterDeclarations,
            symbolToParameterDeclaration: nodeBuilder.symbolToParameterDeclaration,
            typeParameterToDeclaration: nodeBuilder.typeParameterToDeclaration,
            getSymbolsInScope: function (location, meaning) {
                location = ts.getParseTreeNode(location);
                return location ? getSymbolsInScope(location, meaning) : [];
            },
            getSymbolAtLocation: function (node) {
                node = ts.getParseTreeNode(node);
                // set ignoreErrors: true because any lookups invoked by the API shouldn't cause any new errors
                return node ? getSymbolAtLocation(node, /*ignoreErrors*/ true) : undefined;
            },
            getShorthandAssignmentValueSymbol: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getShorthandAssignmentValueSymbol(node) : undefined;
            },
            getExportSpecifierLocalTargetSymbol: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isExportSpecifier);
                return node ? getExportSpecifierLocalTargetSymbol(node) : undefined;
            },
            getExportSymbolOfSymbol: function (symbol) {
                return getMergedSymbol(symbol.exportSymbol || symbol);
            },
            getTypeAtLocation: function (node) {
                node = ts.getParseTreeNode(node);
                return node ? getTypeOfNode(node) : errorType;
            },
            getTypeOfAssignmentPattern: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isAssignmentPattern);
                return node && getTypeOfAssignmentPattern(node) || errorType;
            },
            getPropertySymbolOfDestructuringAssignment: function (locationIn) {
                var location = ts.getParseTreeNode(locationIn, ts.isIdentifier);
                return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined;
            },
            signatureToString: function (signature, enclosingDeclaration, flags, kind) {
                return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind);
            },
            typeToString: function (type, enclosingDeclaration, flags) {
                return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags);
            },
            symbolToString: function (symbol, enclosingDeclaration, meaning, flags) {
                return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning, flags);
            },
            typePredicateToString: function (predicate, enclosingDeclaration, flags) {
                return typePredicateToString(predicate, ts.getParseTreeNode(enclosingDeclaration), flags);
            },
            writeSignature: function (signature, enclosingDeclaration, flags, kind, writer) {
                return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind, writer);
            },
            writeType: function (type, enclosingDeclaration, flags, writer) {
                return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags, writer);
            },
            writeSymbol: function (symbol, enclosingDeclaration, meaning, flags, writer) {
                return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning, flags, writer);
            },
            writeTypePredicate: function (predicate, enclosingDeclaration, flags, writer) {
                return typePredicateToString(predicate, ts.getParseTreeNode(enclosingDeclaration), flags, writer);
            },
            getAugmentedPropertiesOfType: getAugmentedPropertiesOfType,
            getRootSymbols: getRootSymbols,
            getContextualType: function (nodeIn, contextFlags) {
                var node = ts.getParseTreeNode(nodeIn, ts.isExpression);
                if (!node) {
                    return undefined;
                }
                var containingCall = ts.findAncestor(node, ts.isCallLikeExpression);
                var containingCallResolvedSignature = containingCall && getNodeLinks(containingCall).resolvedSignature;
                if (contextFlags & 4 /* Completions */ && containingCall) {
                    var toMarkSkip = node;
                    do {
                        getNodeLinks(toMarkSkip).skipDirectInference = true;
                        toMarkSkip = toMarkSkip.parent;
                    } while (toMarkSkip && toMarkSkip !== containingCall);
                    getNodeLinks(containingCall).resolvedSignature = undefined;
                }
                var result = getContextualType(node, contextFlags);
                if (contextFlags & 4 /* Completions */ && containingCall) {
                    var toMarkSkip = node;
                    do {
                        getNodeLinks(toMarkSkip).skipDirectInference = undefined;
                        toMarkSkip = toMarkSkip.parent;
                    } while (toMarkSkip && toMarkSkip !== containingCall);
                    getNodeLinks(containingCall).resolvedSignature = containingCallResolvedSignature;
                }
                return result;
            },
            getContextualTypeForObjectLiteralElement: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isObjectLiteralElementLike);
                return node ? getContextualTypeForObjectLiteralElement(node) : undefined;
            },
            getContextualTypeForArgumentAtIndex: function (nodeIn, argIndex) {
                var node = ts.getParseTreeNode(nodeIn, ts.isCallLikeExpression);
                return node && getContextualTypeForArgumentAtIndex(node, argIndex);
            },
            getContextualTypeForJsxAttribute: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isJsxAttributeLike);
                return node && getContextualTypeForJsxAttribute(node);
            },
            isContextSensitive: isContextSensitive,
            getFullyQualifiedName: getFullyQualifiedName,
            getResolvedSignature: function (node, candidatesOutArray, argumentCount) {
                return getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, 0 /* Normal */);
            },
            getResolvedSignatureForSignatureHelp: function (node, candidatesOutArray, argumentCount) {
                return getResolvedSignatureWorker(node, candidatesOutArray, argumentCount, 16 /* IsForSignatureHelp */);
            },
            getExpandedParameters: getExpandedParameters,
            hasEffectiveRestParameter: hasEffectiveRestParameter,
            getConstantValue: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, canHaveConstantValue);
                return node ? getConstantValue(node) : undefined;
            },
            isValidPropertyAccess: function (nodeIn, propertyName) {
                var node = ts.getParseTreeNode(nodeIn, ts.isPropertyAccessOrQualifiedNameOrImportTypeNode);
                return !!node && isValidPropertyAccess(node, ts.escapeLeadingUnderscores(propertyName));
            },
            isValidPropertyAccessForCompletions: function (nodeIn, type, property) {
                var node = ts.getParseTreeNode(nodeIn, ts.isPropertyAccessExpression);
                return !!node && isValidPropertyAccessForCompletions(node, type, property);
            },
            getSignatureFromDeclaration: function (declarationIn) {
                var declaration = ts.getParseTreeNode(declarationIn, ts.isFunctionLike);
                return declaration ? getSignatureFromDeclaration(declaration) : undefined;
            },
            isImplementationOfOverload: function (node) {
                var parsed = ts.getParseTreeNode(node, ts.isFunctionLike);
                return parsed ? isImplementationOfOverload(parsed) : undefined;
            },
            getImmediateAliasedSymbol: getImmediateAliasedSymbol,
            getAliasedSymbol: resolveAlias,
            getEmitResolver: getEmitResolver,
            getExportsOfModule: getExportsOfModuleAsArray,
            getExportsAndPropertiesOfModule: getExportsAndPropertiesOfModule,
            getSymbolWalker: ts.createGetSymbolWalker(getRestTypeOfSignature, getTypePredicateOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintOfTypeParameter, ts.getFirstIdentifier, getTypeArguments),
            getAmbientModules: getAmbientModules,
            getJsxIntrinsicTagNamesAt: getJsxIntrinsicTagNamesAt,
            isOptionalParameter: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isParameter);
                return node ? isOptionalParameter(node) : false;
            },
            tryGetMemberInModuleExports: function (name, symbol) { return tryGetMemberInModuleExports(ts.escapeLeadingUnderscores(name), symbol); },
            tryGetMemberInModuleExportsAndProperties: function (name, symbol) { return tryGetMemberInModuleExportsAndProperties(ts.escapeLeadingUnderscores(name), symbol); },
            tryFindAmbientModuleWithoutAugmentations: function (moduleName) {
                // we deliberately exclude augmentations
                // since we are only interested in declarations of the module itself
                return tryFindAmbientModule(moduleName, /*withAugmentations*/ false);
            },
            getApparentType: getApparentType,
            getUnionType: getUnionType,
            isTypeAssignableTo: isTypeAssignableTo,
            createAnonymousType: createAnonymousType,
            createSignature: createSignature,
            createSymbol: createSymbol,
            createIndexInfo: createIndexInfo,
            getAnyType: function () { return anyType; },
            getStringType: function () { return stringType; },
            getNumberType: function () { return numberType; },
            createPromiseType: createPromiseType,
            createArrayType: createArrayType,
            getElementTypeOfArrayType: getElementTypeOfArrayType,
            getBooleanType: function () { return booleanType; },
            getFalseType: function (fresh) { return fresh ? falseType : regularFalseType; },
            getTrueType: function (fresh) { return fresh ? trueType : regularTrueType; },
            getVoidType: function () { return voidType; },
            getUndefinedType: function () { return undefinedType; },
            getNullType: function () { return nullType; },
            getESSymbolType: function () { return esSymbolType; },
            getNeverType: function () { return neverType; },
            getOptionalType: function () { return optionalType; },
            isSymbolAccessible: isSymbolAccessible,
            isArrayType: isArrayType,
            isTupleType: isTupleType,
            isArrayLikeType: isArrayLikeType,
            isTypeInvalidDueToUnionDiscriminant: isTypeInvalidDueToUnionDiscriminant,
            getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes,
            getSuggestedSymbolForNonexistentProperty: getSuggestedSymbolForNonexistentProperty,
            getSuggestionForNonexistentProperty: getSuggestionForNonexistentProperty,
            getSuggestedSymbolForNonexistentSymbol: function (location, name, meaning) { return getSuggestedSymbolForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); },
            getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); },
            getSuggestedSymbolForNonexistentModule: getSuggestedSymbolForNonexistentModule,
            getSuggestionForNonexistentExport: getSuggestionForNonexistentExport,
            getBaseConstraintOfType: getBaseConstraintOfType,
            getDefaultFromTypeParameter: function (type) { return type && type.flags & 262144 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; },
            resolveName: function (name, location, meaning, excludeGlobals) {
                return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals);
            },
            getJsxNamespace: function (n) { return ts.unescapeLeadingUnderscores(getJsxNamespace(n)); },
            getAccessibleSymbolChain: getAccessibleSymbolChain,
            getTypePredicateOfSignature: getTypePredicateOfSignature,
            resolveExternalModuleName: function (moduleSpecifier) {
                return resolveExternalModuleName(moduleSpecifier, moduleSpecifier, /*ignoreErrors*/ true);
            },
            resolveExternalModuleSymbol: resolveExternalModuleSymbol,
            tryGetThisTypeAt: function (node, includeGlobalThis) {
                node = ts.getParseTreeNode(node);
                return node && tryGetThisTypeAt(node, includeGlobalThis);
            },
            getTypeArgumentConstraint: function (nodeIn) {
                var node = ts.getParseTreeNode(nodeIn, ts.isTypeNode);
                return node && getTypeArgumentConstraint(node);
            },
            getSuggestionDiagnostics: function (file, ct) {
                if (ts.skipTypeChecking(file, compilerOptions, host)) {
                    return ts.emptyArray;
                }
                var diagnostics;
                try {
                    // Record the cancellation token so it can be checked later on during checkSourceElement.
                    // Do this in a finally block so we can ensure that it gets reset back to nothing after
                    // this call is done.
                    cancellationToken = ct;
                    // Ensure file is type checked
                    checkSourceFile(file);
                    ts.Debug.assert(!!(getNodeLinks(file).flags & 1 /* TypeChecked */));
                    diagnostics = ts.addRange(diagnostics, suggestionDiagnostics.getDiagnostics(file.fileName));
                    checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), function (containingNode, kind, diag) {
                        if (!ts.containsParseError(containingNode) && !unusedIsError(kind, !!(containingNode.flags & 8388608 /* Ambient */))) {
                            (diagnostics || (diagnostics = [])).push(__assign(__assign({}, diag), { category: ts.DiagnosticCategory.Suggestion }));
                        }
                    });
                    return diagnostics || ts.emptyArray;
                }
                finally {
                    cancellationToken = undefined;
                }
            },
            runWithCancellationToken: function (token, callback) {
                try {
                    cancellationToken = token;
                    return callback(checker);
                }
                finally {
                    cancellationToken = undefined;
                }
            },
            getLocalTypeParametersOfClassOrInterfaceOrTypeAlias: getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
            isDeclarationVisible: isDeclarationVisible,
        };
        function getResolvedSignatureWorker(nodeIn, candidatesOutArray, argumentCount, checkMode) {
            var node = ts.getParseTreeNode(nodeIn, ts.isCallLikeExpression);
            apparentArgumentCount = argumentCount;
            var res = node ? getResolvedSignature(node, candidatesOutArray, checkMode) : undefined;
            apparentArgumentCount = undefined;
            return res;
        }
        var tupleTypes = ts.createMap();
        var unionTypes = ts.createMap();
        var intersectionTypes = ts.createMap();
        var literalTypes = ts.createMap();
        var indexedAccessTypes = ts.createMap();
        var substitutionTypes = ts.createMap();
        var evolvingArrayTypes = [];
        var undefinedProperties = ts.createMap();
        var unknownSymbol = createSymbol(4 /* Property */, "unknown");
        var resolvingSymbol = createSymbol(0, "__resolving__" /* Resolving */);
        var anyType = createIntrinsicType(1 /* Any */, "any");
        var autoType = createIntrinsicType(1 /* Any */, "any");
        var wildcardType = createIntrinsicType(1 /* Any */, "any");
        var errorType = createIntrinsicType(1 /* Any */, "error");
        var nonInferrableAnyType = createIntrinsicType(1 /* Any */, "any", 524288 /* ContainsWideningType */);
        var unknownType = createIntrinsicType(2 /* Unknown */, "unknown");
        var undefinedType = createIntrinsicType(32768 /* Undefined */, "undefined");
        var undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(32768 /* Undefined */, "undefined", 524288 /* ContainsWideningType */);
        var optionalType = createIntrinsicType(32768 /* Undefined */, "undefined");
        var nullType = createIntrinsicType(65536 /* Null */, "null");
        var nullWideningType = strictNullChecks ? nullType : createIntrinsicType(65536 /* Null */, "null", 524288 /* ContainsWideningType */);
        var stringType = createIntrinsicType(4 /* String */, "string");
        var numberType = createIntrinsicType(8 /* Number */, "number");
        var bigintType = createIntrinsicType(64 /* BigInt */, "bigint");
        var falseType = createIntrinsicType(512 /* BooleanLiteral */, "false");
        var regularFalseType = createIntrinsicType(512 /* BooleanLiteral */, "false");
        var trueType = createIntrinsicType(512 /* BooleanLiteral */, "true");
        var regularTrueType = createIntrinsicType(512 /* BooleanLiteral */, "true");
        trueType.regularType = regularTrueType;
        trueType.freshType = trueType;
        regularTrueType.regularType = regularTrueType;
        regularTrueType.freshType = trueType;
        falseType.regularType = regularFalseType;
        falseType.freshType = falseType;
        regularFalseType.regularType = regularFalseType;
        regularFalseType.freshType = falseType;
        var booleanType = createBooleanType([regularFalseType, regularTrueType]);
        // Also mark all combinations of fresh/regular booleans as "Boolean" so they print as `boolean` instead of `true | false`
        // (The union is cached, so simply doing the marking here is sufficient)
        createBooleanType([regularFalseType, trueType]);
        createBooleanType([falseType, regularTrueType]);
        createBooleanType([falseType, trueType]);
        var esSymbolType = createIntrinsicType(4096 /* ESSymbol */, "symbol");
        var voidType = createIntrinsicType(16384 /* Void */, "void");
        var neverType = createIntrinsicType(131072 /* Never */, "never");
        var silentNeverType = createIntrinsicType(131072 /* Never */, "never");
        var nonInferrableType = createIntrinsicType(131072 /* Never */, "never", 2097152 /* NonInferrableType */);
        var implicitNeverType = createIntrinsicType(131072 /* Never */, "never");
        var unreachableNeverType = createIntrinsicType(131072 /* Never */, "never");
        var nonPrimitiveType = createIntrinsicType(67108864 /* NonPrimitive */, "object");
        var stringNumberSymbolType = getUnionType([stringType, numberType, esSymbolType]);
        var keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
        var numberOrBigIntType = getUnionType([numberType, bigintType]);
        var restrictiveMapper = makeFunctionTypeMapper(function (t) { return t.flags & 262144 /* TypeParameter */ ? getRestrictiveTypeParameter(t) : t; });
        var permissiveMapper = makeFunctionTypeMapper(function (t) { return t.flags & 262144 /* TypeParameter */ ? wildcardType : t; });
        var emptyObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var emptyJsxObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        emptyJsxObjectType.objectFlags |= 4096 /* JsxAttributes */;
        var emptyTypeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
        emptyTypeLiteralSymbol.members = ts.createSymbolTable();
        var emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var emptyGenericType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        emptyGenericType.instantiations = ts.createMap();
        var anyFunctionType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated
        // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes.
        anyFunctionType.objectFlags |= 2097152 /* NonInferrableType */;
        var noConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var circularConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var resolvingDefaultType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
        var markerSuperType = createTypeParameter();
        var markerSubType = createTypeParameter();
        markerSubType.constraint = markerSuperType;
        var markerOtherType = createTypeParameter();
        var noTypePredicate = createTypePredicate(1 /* Identifier */, "<<unresolved>>", 0, anyType);
        var anySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
        var unknownSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, errorType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
        var resolvingSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
        var silentNeverSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, silentNeverType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
        var enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true);
        var iterationTypesCache = ts.createMap(); // cache for common IterationTypes instances
        var noIterationTypes = {
            get yieldType() { return ts.Debug.fail("Not supported"); },
            get returnType() { return ts.Debug.fail("Not supported"); },
            get nextType() { return ts.Debug.fail("Not supported"); },
        };
        var anyIterationTypes = createIterationTypes(anyType, anyType, anyType);
        var anyIterationTypesExceptNext = createIterationTypes(anyType, anyType, unknownType);
        var defaultIterationTypes = createIterationTypes(neverType, anyType, undefinedType); // default iteration types for `Iterator`.
        var asyncIterationTypesResolver = {
            iterableCacheKey: "iterationTypesOfAsyncIterable",
            iteratorCacheKey: "iterationTypesOfAsyncIterator",
            iteratorSymbolName: "asyncIterator",
            getGlobalIteratorType: getGlobalAsyncIteratorType,
            getGlobalIterableType: getGlobalAsyncIterableType,
            getGlobalIterableIteratorType: getGlobalAsyncIterableIteratorType,
            getGlobalGeneratorType: getGlobalAsyncGeneratorType,
            resolveIterationType: getAwaitedType,
            mustHaveANextMethodDiagnostic: ts.Diagnostics.An_async_iterator_must_have_a_next_method,
            mustBeAMethodDiagnostic: ts.Diagnostics.The_0_property_of_an_async_iterator_must_be_a_method,
            mustHaveAValueDiagnostic: ts.Diagnostics.The_type_returned_by_the_0_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property,
        };
        var syncIterationTypesResolver = {
            iterableCacheKey: "iterationTypesOfIterable",
            iteratorCacheKey: "iterationTypesOfIterator",
            iteratorSymbolName: "iterator",
            getGlobalIteratorType: getGlobalIteratorType,
            getGlobalIterableType: getGlobalIterableType,
            getGlobalIterableIteratorType: getGlobalIterableIteratorType,
            getGlobalGeneratorType: getGlobalGeneratorType,
            resolveIterationType: function (type, _errorNode) { return type; },
            mustHaveANextMethodDiagnostic: ts.Diagnostics.An_iterator_must_have_a_next_method,
            mustBeAMethodDiagnostic: ts.Diagnostics.The_0_property_of_an_iterator_must_be_a_method,
            mustHaveAValueDiagnostic: ts.Diagnostics.The_type_returned_by_the_0_method_of_an_iterator_must_have_a_value_property,
        };
        /** Key is "/path/to/a.ts|/path/to/b.ts". */
        var amalgamatedDuplicates;
        var reverseMappedCache = ts.createMap();
        var ambientModulesCache;
        /**
         * List of every ambient module with a "*" wildcard.
         * Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches.
         * This is only used if there is no exact match.
         */
        var patternAmbientModules;
        var patternAmbientModuleAugmentations;
        var globalObjectType;
        var globalFunctionType;
        var globalCallableFunctionType;
        var globalNewableFunctionType;
        var globalArrayType;
        var globalReadonlyArrayType;
        var globalStringType;
        var globalNumberType;
        var globalBooleanType;
        var globalRegExpType;
        var globalThisType;
        var anyArrayType;
        var autoArrayType;
        var anyReadonlyArrayType;
        var deferredGlobalNonNullableTypeAlias;
        // The library files are only loaded when the feature is used.
        // This allows users to just specify library files they want to used through --lib
        // and they will not get an error from not having unrelated library files
        var deferredGlobalESSymbolConstructorSymbol;
        var deferredGlobalESSymbolType;
        var deferredGlobalTypedPropertyDescriptorType;
        var deferredGlobalPromiseType;
        var deferredGlobalPromiseLikeType;
        var deferredGlobalPromiseConstructorSymbol;
        var deferredGlobalPromiseConstructorLikeType;
        var deferredGlobalIterableType;
        var deferredGlobalIteratorType;
        var deferredGlobalIterableIteratorType;
        var deferredGlobalGeneratorType;
        var deferredGlobalIteratorYieldResultType;
        var deferredGlobalIteratorReturnResultType;
        var deferredGlobalAsyncIterableType;
        var deferredGlobalAsyncIteratorType;
        var deferredGlobalAsyncIterableIteratorType;
        var deferredGlobalAsyncGeneratorType;
        var deferredGlobalTemplateStringsArrayType;
        var deferredGlobalImportMetaType;
        var deferredGlobalExtractSymbol;
        var deferredGlobalOmitSymbol;
        var deferredGlobalBigIntType;
        var allPotentiallyUnusedIdentifiers = ts.createMap(); // key is file name
        var flowLoopStart = 0;
        var flowLoopCount = 0;
        var sharedFlowCount = 0;
        var flowAnalysisDisabled = false;
        var flowInvocationCount = 0;
        var lastFlowNode;
        var lastFlowNodeReachable;
        var flowTypeCache;
        var emptyStringType = getLiteralType("");
        var zeroType = getLiteralType(0);
        var zeroBigIntType = getLiteralType({ negative: false, base10Value: "0" });
        var resolutionTargets = [];
        var resolutionResults = [];
        var resolutionPropertyNames = [];
        var suggestionCount = 0;
        var maximumSuggestionCount = 10;
        var mergedSymbols = [];
        var symbolLinks = [];
        var nodeLinks = [];
        var flowLoopCaches = [];
        var flowLoopNodes = [];
        var flowLoopKeys = [];
        var flowLoopTypes = [];
        var sharedFlowNodes = [];
        var sharedFlowTypes = [];
        var flowNodeReachable = [];
        var potentialThisCollisions = [];
        var potentialNewTargetCollisions = [];
        var potentialWeakMapCollisions = [];
        var awaitedTypeStack = [];
        var diagnostics = ts.createDiagnosticCollection();
        var suggestionDiagnostics = ts.createDiagnosticCollection();
        var typeofTypesByName = ts.createMapFromTemplate({
            string: stringType,
            number: numberType,
            bigint: bigintType,
            boolean: booleanType,
            symbol: esSymbolType,
            undefined: undefinedType
        });
        var typeofType = createTypeofType();
        var _jsxNamespace;
        var _jsxFactoryEntity;
        var outofbandVarianceMarkerHandler;
        var subtypeRelation = ts.createMap();
        var strictSubtypeRelation = ts.createMap();
        var assignableRelation = ts.createMap();
        var comparableRelation = ts.createMap();
        var identityRelation = ts.createMap();
        var enumRelation = ts.createMap();
        var builtinGlobals = ts.createSymbolTable();
        builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
        initializeTypeChecker();
        return checker;
        function getJsxNamespace(location) {
            if (location) {
                var file = ts.getSourceFileOfNode(location);
                if (file) {
                    if (file.localJsxNamespace) {
                        return file.localJsxNamespace;
                    }
                    var jsxPragma = file.pragmas.get("jsx");
                    if (jsxPragma) {
                        var chosenpragma = ts.isArray(jsxPragma) ? jsxPragma[0] : jsxPragma;
                        file.localJsxFactory = ts.parseIsolatedEntityName(chosenpragma.arguments.factory, languageVersion);
                        ts.visitNode(file.localJsxFactory, markAsSynthetic);
                        if (file.localJsxFactory) {
                            return file.localJsxNamespace = ts.getFirstIdentifier(file.localJsxFactory).escapedText;
                        }
                    }
                }
            }
            if (!_jsxNamespace) {
                _jsxNamespace = "React";
                if (compilerOptions.jsxFactory) {
                    _jsxFactoryEntity = ts.parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
                    ts.visitNode(_jsxFactoryEntity, markAsSynthetic);
                    if (_jsxFactoryEntity) {
                        _jsxNamespace = ts.getFirstIdentifier(_jsxFactoryEntity).escapedText;
                    }
                }
                else if (compilerOptions.reactNamespace) {
                    _jsxNamespace = ts.escapeLeadingUnderscores(compilerOptions.reactNamespace);
                }
            }
            if (!_jsxFactoryEntity) {
                _jsxFactoryEntity = ts.createQualifiedName(ts.createIdentifier(ts.unescapeLeadingUnderscores(_jsxNamespace)), "createElement");
            }
            return _jsxNamespace;
            function markAsSynthetic(node) {
                node.pos = -1;
                node.end = -1;
                return ts.visitEachChild(node, markAsSynthetic, ts.nullTransformationContext);
            }
        }
        function getEmitResolver(sourceFile, cancellationToken) {
            // Ensure we have all the type information in place for this file so that all the
            // emitter questions of this resolver will return the right information.
            getDiagnostics(sourceFile, cancellationToken);
            return emitResolver;
        }
        function lookupOrIssueError(location, message, arg0, arg1, arg2, arg3) {
            var diagnostic = location
                ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3)
                : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3);
            var existing = diagnostics.lookup(diagnostic);
            if (existing) {
                return existing;
            }
            else {
                diagnostics.add(diagnostic);
                return diagnostic;
            }
        }
        function error(location, message, arg0, arg1, arg2, arg3) {
            var diagnostic = location
                ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3)
                : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3);
            diagnostics.add(diagnostic);
            return diagnostic;
        }
        function addErrorOrSuggestion(isError, diagnostic) {
            if (isError) {
                diagnostics.add(diagnostic);
            }
            else {
                suggestionDiagnostics.add(__assign(__assign({}, diagnostic), { category: ts.DiagnosticCategory.Suggestion }));
            }
        }
        function errorOrSuggestion(isError, location, message, arg0, arg1, arg2, arg3) {
            addErrorOrSuggestion(isError, "message" in message ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : ts.createDiagnosticForNodeFromMessageChain(location, message)); // eslint-disable-line no-in-operator
        }
        function errorAndMaybeSuggestAwait(location, maybeMissingAwait, message, arg0, arg1, arg2, arg3) {
            var diagnostic = error(location, message, arg0, arg1, arg2, arg3);
            if (maybeMissingAwait) {
                var related = ts.createDiagnosticForNode(location, ts.Diagnostics.Did_you_forget_to_use_await);
                ts.addRelatedInfo(diagnostic, related);
            }
            return diagnostic;
        }
        function createSymbol(flags, name, checkFlags) {
            symbolCount++;
            var symbol = (new Symbol(flags | 33554432 /* Transient */, name));
            symbol.checkFlags = checkFlags || 0;
            return symbol;
        }
        function getExcludedSymbolFlags(flags) {
            var result = 0;
            if (flags & 2 /* BlockScopedVariable */)
                result |= 111551 /* BlockScopedVariableExcludes */;
            if (flags & 1 /* FunctionScopedVariable */)
                result |= 111550 /* FunctionScopedVariableExcludes */;
            if (flags & 4 /* Property */)
                result |= 0 /* PropertyExcludes */;
            if (flags & 8 /* EnumMember */)
                result |= 900095 /* EnumMemberExcludes */;
            if (flags & 16 /* Function */)
                result |= 110991 /* FunctionExcludes */;
            if (flags & 32 /* Class */)
                result |= 899503 /* ClassExcludes */;
            if (flags & 64 /* Interface */)
                result |= 788872 /* InterfaceExcludes */;
            if (flags & 256 /* RegularEnum */)
                result |= 899327 /* RegularEnumExcludes */;
            if (flags & 128 /* ConstEnum */)
                result |= 899967 /* ConstEnumExcludes */;
            if (flags & 512 /* ValueModule */)
                result |= 110735 /* ValueModuleExcludes */;
            if (flags & 8192 /* Method */)
                result |= 103359 /* MethodExcludes */;
            if (flags & 32768 /* GetAccessor */)
                result |= 46015 /* GetAccessorExcludes */;
            if (flags & 65536 /* SetAccessor */)
                result |= 78783 /* SetAccessorExcludes */;
            if (flags & 262144 /* TypeParameter */)
                result |= 526824 /* TypeParameterExcludes */;
            if (flags & 524288 /* TypeAlias */)
                result |= 788968 /* TypeAliasExcludes */;
            if (flags & 2097152 /* Alias */)
                result |= 2097152 /* AliasExcludes */;
            return result;
        }
        function recordMergedSymbol(target, source) {
            if (!source.mergeId) {
                source.mergeId = nextMergeId;
                nextMergeId++;
            }
            mergedSymbols[source.mergeId] = target;
        }
        function cloneSymbol(symbol) {
            var result = createSymbol(symbol.flags, symbol.escapedName);
            result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
            result.parent = symbol.parent;
            if (symbol.valueDeclaration)
                result.valueDeclaration = symbol.valueDeclaration;
            if (symbol.constEnumOnlyModule)
                result.constEnumOnlyModule = true;
            if (symbol.members)
                result.members = ts.cloneMap(symbol.members);
            if (symbol.exports)
                result.exports = ts.cloneMap(symbol.exports);
            recordMergedSymbol(result, symbol);
            return result;
        }
        /**
         * Note: if target is transient, then it is mutable, and mergeSymbol with both mutate and return it.
         * If target is not transient, mergeSymbol will produce a transient clone, mutate that and return it.
         */
        function mergeSymbol(target, source, unidirectional) {
            if (unidirectional === void 0) { unidirectional = false; }
            if (!(target.flags & getExcludedSymbolFlags(source.flags)) ||
                (source.flags | target.flags) & 67108864 /* Assignment */) {
                if (source === target) {
                    // This can happen when an export assigned namespace exports something also erroneously exported at the top level
                    // See `declarationFileNoCrashOnExtraExportModifier` for an example
                    return target;
                }
                if (!(target.flags & 33554432 /* Transient */)) {
                    var resolvedTarget = resolveSymbol(target);
                    if (resolvedTarget === unknownSymbol) {
                        return source;
                    }
                    target = cloneSymbol(resolvedTarget);
                }
                // Javascript static-property-assignment declarations always merge, even though they are also values
                if (source.flags & 512 /* ValueModule */ && target.flags & 512 /* ValueModule */ && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
                    // reset flag when merging instantiated module into value module that has only const enums
                    target.constEnumOnlyModule = false;
                }
                target.flags |= source.flags;
                if (source.valueDeclaration) {
                    ts.setValueDeclaration(target, source.valueDeclaration);
                }
                ts.addRange(target.declarations, source.declarations);
                if (source.members) {
                    if (!target.members)
                        target.members = ts.createSymbolTable();
                    mergeSymbolTable(target.members, source.members, unidirectional);
                }
                if (source.exports) {
                    if (!target.exports)
                        target.exports = ts.createSymbolTable();
                    mergeSymbolTable(target.exports, source.exports, unidirectional);
                }
                if (!unidirectional) {
                    recordMergedSymbol(target, source);
                }
            }
            else if (target.flags & 1024 /* NamespaceModule */) {
                // Do not report an error when merging `var globalThis` with the built-in `globalThis`,
                // as we will already report a "Declaration name conflicts..." error, and this error
                // won't make much sense.
                if (target !== globalThisSymbol) {
                    error(ts.getNameOfDeclaration(source.declarations[0]), ts.Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target));
                }
            }
            else { // error
                var isEitherEnum = !!(target.flags & 384 /* Enum */ || source.flags & 384 /* Enum */);
                var isEitherBlockScoped_1 = !!(target.flags & 2 /* BlockScopedVariable */ || source.flags & 2 /* BlockScopedVariable */);
                var message = isEitherEnum
                    ? ts.Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations
                    : isEitherBlockScoped_1
                        ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0
                        : ts.Diagnostics.Duplicate_identifier_0;
                var sourceSymbolFile = source.declarations && ts.getSourceFileOfNode(source.declarations[0]);
                var targetSymbolFile = target.declarations && ts.getSourceFileOfNode(target.declarations[0]);
                var symbolName_1 = symbolToString(source);
                // Collect top-level duplicate identifier errors into one mapping, so we can then merge their diagnostics if there are a bunch
                if (sourceSymbolFile && targetSymbolFile && amalgamatedDuplicates && !isEitherEnum && sourceSymbolFile !== targetSymbolFile) {
                    var firstFile_1 = ts.comparePaths(sourceSymbolFile.path, targetSymbolFile.path) === -1 /* LessThan */ ? sourceSymbolFile : targetSymbolFile;
                    var secondFile_1 = firstFile_1 === sourceSymbolFile ? targetSymbolFile : sourceSymbolFile;
                    var filesDuplicates = ts.getOrUpdate(amalgamatedDuplicates, firstFile_1.path + "|" + secondFile_1.path, function () {
                        return ({ firstFile: firstFile_1, secondFile: secondFile_1, conflictingSymbols: ts.createMap() });
                    });
                    var conflictingSymbolInfo = ts.getOrUpdate(filesDuplicates.conflictingSymbols, symbolName_1, function () {
                        return ({ isBlockScoped: isEitherBlockScoped_1, firstFileLocations: [], secondFileLocations: [] });
                    });
                    addDuplicateLocations(conflictingSymbolInfo.firstFileLocations, source);
                    addDuplicateLocations(conflictingSymbolInfo.secondFileLocations, target);
                }
                else {
                    addDuplicateDeclarationErrorsForSymbols(source, message, symbolName_1, target);
                    addDuplicateDeclarationErrorsForSymbols(target, message, symbolName_1, source);
                }
            }
            return target;
            function addDuplicateLocations(locs, symbol) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    ts.pushIfUnique(locs, decl);
                }
            }
        }
        function addDuplicateDeclarationErrorsForSymbols(target, message, symbolName, source) {
            ts.forEach(target.declarations, function (node) {
                addDuplicateDeclarationError(node, message, symbolName, source.declarations);
            });
        }
        function addDuplicateDeclarationError(node, message, symbolName, relatedNodes) {
            var errorNode = (ts.getExpandoInitializer(node, /*isPrototypeAssignment*/ false) ? ts.getNameOfExpando(node) : ts.getNameOfDeclaration(node)) || node;
            var err = lookupOrIssueError(errorNode, message, symbolName);
            var _loop_6 = function (relatedNode) {
                var adjustedNode = (ts.getExpandoInitializer(relatedNode, /*isPrototypeAssignment*/ false) ? ts.getNameOfExpando(relatedNode) : ts.getNameOfDeclaration(relatedNode)) || relatedNode;
                if (adjustedNode === errorNode)
                    return "continue";
                err.relatedInformation = err.relatedInformation || [];
                var leadingMessage = ts.createDiagnosticForNode(adjustedNode, ts.Diagnostics._0_was_also_declared_here, symbolName);
                var followOnMessage = ts.createDiagnosticForNode(adjustedNode, ts.Diagnostics.and_here);
                if (ts.length(err.relatedInformation) >= 5 || ts.some(err.relatedInformation, function (r) { return ts.compareDiagnostics(r, followOnMessage) === 0 /* EqualTo */ || ts.compareDiagnostics(r, leadingMessage) === 0 /* EqualTo */; }))
                    return "continue";
                ts.addRelatedInfo(err, !ts.length(err.relatedInformation) ? leadingMessage : followOnMessage);
            };
            for (var _i = 0, _a = relatedNodes || ts.emptyArray; _i < _a.length; _i++) {
                var relatedNode = _a[_i];
                _loop_6(relatedNode);
            }
        }
        function combineSymbolTables(first, second) {
            if (!ts.hasEntries(first))
                return second;
            if (!ts.hasEntries(second))
                return first;
            var combined = ts.createSymbolTable();
            mergeSymbolTable(combined, first);
            mergeSymbolTable(combined, second);
            return combined;
        }
        function mergeSymbolTable(target, source, unidirectional) {
            if (unidirectional === void 0) { unidirectional = false; }
            source.forEach(function (sourceSymbol, id) {
                var targetSymbol = target.get(id);
                target.set(id, targetSymbol ? mergeSymbol(targetSymbol, sourceSymbol, unidirectional) : sourceSymbol);
            });
        }
        function mergeModuleAugmentation(moduleName) {
            var _a, _b;
            var moduleAugmentation = moduleName.parent;
            if (moduleAugmentation.symbol.declarations[0] !== moduleAugmentation) {
                // this is a combined symbol for multiple augmentations within the same file.
                // its symbol already has accumulated information for all declarations
                // so we need to add it just once - do the work only for first declaration
                ts.Debug.assert(moduleAugmentation.symbol.declarations.length > 1);
                return;
            }
            if (ts.isGlobalScopeAugmentation(moduleAugmentation)) {
                mergeSymbolTable(globals, moduleAugmentation.symbol.exports);
            }
            else {
                // find a module that about to be augmented
                // do not validate names of augmentations that are defined in ambient context
                var moduleNotFoundError = !(moduleName.parent.parent.flags & 8388608 /* Ambient */)
                    ? ts.Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found
                    : undefined;
                var mainModule_1 = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true);
                if (!mainModule_1) {
                    return;
                }
                // obtain item referenced by 'export='
                mainModule_1 = resolveExternalModuleSymbol(mainModule_1);
                if (mainModule_1.flags & 1920 /* Namespace */) {
                    // If we're merging an augmentation to a pattern ambient module, we want to
                    // perform the merge unidirectionally from the augmentation ('a.foo') to
                    // the pattern ('*.foo'), so that 'getMergedSymbol()' on a.foo gives you
                    // all the exports both from the pattern and from the augmentation, but
                    // 'getMergedSymbol()' on *.foo only gives you exports from *.foo.
                    if (ts.some(patternAmbientModules, function (module) { return mainModule_1 === module.symbol; })) {
                        var merged = mergeSymbol(moduleAugmentation.symbol, mainModule_1, /*unidirectional*/ true);
                        if (!patternAmbientModuleAugmentations) {
                            patternAmbientModuleAugmentations = ts.createMap();
                        }
                        // moduleName will be a StringLiteral since this is not `declare global`.
                        patternAmbientModuleAugmentations.set(moduleName.text, merged);
                    }
                    else {
                        if (((_a = mainModule_1.exports) === null || _a === void 0 ? void 0 : _a.get("__export" /* ExportStar */)) && ((_b = moduleAugmentation.symbol.exports) === null || _b === void 0 ? void 0 : _b.size)) {
                            // We may need to merge the module augmentation's exports into the target symbols of the resolved exports
                            var resolvedExports = getResolvedMembersOrExportsOfSymbol(mainModule_1, "resolvedExports" /* resolvedExports */);
                            for (var _i = 0, _c = ts.arrayFrom(moduleAugmentation.symbol.exports.entries()); _i < _c.length; _i++) {
                                var _d = _c[_i], key = _d[0], value = _d[1];
                                if (resolvedExports.has(key) && !mainModule_1.exports.has(key)) {
                                    mergeSymbol(resolvedExports.get(key), value);
                                }
                            }
                        }
                        mergeSymbol(mainModule_1, moduleAugmentation.symbol);
                    }
                }
                else {
                    // moduleName will be a StringLiteral since this is not `declare global`.
                    error(moduleName, ts.Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text);
                }
            }
        }
        function addToSymbolTable(target, source, message) {
            source.forEach(function (sourceSymbol, id) {
                var targetSymbol = target.get(id);
                if (targetSymbol) {
                    // Error on redeclarations
                    ts.forEach(targetSymbol.declarations, addDeclarationDiagnostic(ts.unescapeLeadingUnderscores(id), message));
                }
                else {
                    target.set(id, sourceSymbol);
                }
            });
            function addDeclarationDiagnostic(id, message) {
                return function (declaration) { return diagnostics.add(ts.createDiagnosticForNode(declaration, message, id)); };
            }
        }
        function getSymbolLinks(symbol) {
            if (symbol.flags & 33554432 /* Transient */)
                return symbol;
            var id = getSymbolId(symbol);
            return symbolLinks[id] || (symbolLinks[id] = new SymbolLinks());
        }
        function getNodeLinks(node) {
            var nodeId = getNodeId(node);
            return nodeLinks[nodeId] || (nodeLinks[nodeId] = new NodeLinks());
        }
        function isGlobalSourceFile(node) {
            return node.kind === 290 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node);
        }
        function getSymbol(symbols, name, meaning) {
            if (meaning) {
                var symbol = getMergedSymbol(symbols.get(name));
                if (symbol) {
                    ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
                    if (symbol.flags & meaning) {
                        return symbol;
                    }
                    if (symbol.flags & 2097152 /* Alias */) {
                        var target = resolveAlias(symbol);
                        // Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors
                        if (target === unknownSymbol || target.flags & meaning) {
                            return symbol;
                        }
                    }
                }
            }
            // return undefined if we can't find a symbol.
        }
        /**
         * Get symbols that represent parameter-property-declaration as parameter and as property declaration
         * @param parameter a parameterDeclaration node
         * @param parameterName a name of the parameter to get the symbols for.
         * @return a tuple of two symbols
         */
        function getSymbolsOfParameterPropertyDeclaration(parameter, parameterName) {
            var constructorDeclaration = parameter.parent;
            var classDeclaration = parameter.parent.parent;
            var parameterSymbol = getSymbol(constructorDeclaration.locals, parameterName, 111551 /* Value */);
            var propertySymbol = getSymbol(getMembersOfSymbol(classDeclaration.symbol), parameterName, 111551 /* Value */);
            if (parameterSymbol && propertySymbol) {
                return [parameterSymbol, propertySymbol];
            }
            return ts.Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration");
        }
        function isBlockScopedNameDeclaredBeforeUse(declaration, usage) {
            var declarationFile = ts.getSourceFileOfNode(declaration);
            var useFile = ts.getSourceFileOfNode(usage);
            var declContainer = ts.getEnclosingBlockScopeContainer(declaration);
            if (declarationFile !== useFile) {
                if ((moduleKind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) ||
                    (!compilerOptions.outFile && !compilerOptions.out) ||
                    isInTypeQuery(usage) ||
                    declaration.flags & 8388608 /* Ambient */) {
                    // nodes are in different files and order cannot be determined
                    return true;
                }
                // declaration is after usage
                // can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
                if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
                    return true;
                }
                var sourceFiles = host.getSourceFiles();
                return sourceFiles.indexOf(declarationFile) <= sourceFiles.indexOf(useFile);
            }
            if (declaration.pos <= usage.pos) {
                // declaration is before usage
                if (declaration.kind === 191 /* BindingElement */) {
                    // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2])
                    var errorBindingElement = ts.getAncestor(usage, 191 /* BindingElement */);
                    if (errorBindingElement) {
                        return ts.findAncestor(errorBindingElement, ts.isBindingElement) !== ts.findAncestor(declaration, ts.isBindingElement) ||
                            declaration.pos < errorBindingElement.pos;
                    }
                    // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a)
                    return isBlockScopedNameDeclaredBeforeUse(ts.getAncestor(declaration, 242 /* VariableDeclaration */), usage);
                }
                else if (declaration.kind === 242 /* VariableDeclaration */) {
                    // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
                    return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage);
                }
                else if (ts.isClassDeclaration(declaration)) {
                    // still might be illegal if the usage is within a computed property name in the class (eg class A { static p = "a"; [A.p]() {} })
                    return !ts.findAncestor(usage, function (n) { return ts.isComputedPropertyName(n) && n.parent.parent === declaration; });
                }
                else if (ts.isPropertyDeclaration(declaration)) {
                    // still might be illegal if a self-referencing property initializer (eg private x = this.x)
                    return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ false);
                }
                else if (ts.isParameterPropertyDeclaration(declaration, declaration.parent)) {
                    // foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property
                    return !(compilerOptions.target === 99 /* ESNext */ && !!compilerOptions.useDefineForClassFields
                        && ts.getContainingClass(declaration) === ts.getContainingClass(usage)
                        && isUsedInFunctionOrInstanceProperty(usage, declaration));
                }
                return true;
            }
            // declaration is after usage, but it can still be legal if usage is deferred:
            // 1. inside an export specifier
            // 2. inside a function
            // 3. inside an instance property initializer, a reference to a non-instance property
            //    (except when target: "esnext" and useDefineForClassFields: true and the reference is to a parameter property)
            // 4. inside a static property initializer, a reference to a static method in the same class
            // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ)
            // or if usage is in a type context:
            // 1. inside a type query (typeof in type position)
            // 2. inside a jsdoc comment
            if (usage.parent.kind === 263 /* ExportSpecifier */ || (usage.parent.kind === 259 /* ExportAssignment */ && usage.parent.isExportEquals)) {
                // export specifiers do not use the variable, they only make it available for use
                return true;
            }
            // When resolving symbols for exports, the `usage` location passed in can be the export site directly
            if (usage.kind === 259 /* ExportAssignment */ && usage.isExportEquals) {
                return true;
            }
            if (!!(usage.flags & 4194304 /* JSDoc */) || isInTypeQuery(usage) || usageInTypeDeclaration()) {
                return true;
            }
            if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
                if (compilerOptions.target === 99 /* ESNext */ && !!compilerOptions.useDefineForClassFields
                    && ts.getContainingClass(declaration)
                    && (ts.isPropertyDeclaration(declaration) || ts.isParameterPropertyDeclaration(declaration, declaration.parent))) {
                    return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true);
                }
                else {
                    return true;
                }
            }
            return false;
            function usageInTypeDeclaration() {
                return !!ts.findAncestor(usage, function (node) { return ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node); });
            }
            function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) {
                switch (declaration.parent.parent.kind) {
                    case 225 /* VariableStatement */:
                    case 230 /* ForStatement */:
                    case 232 /* ForOfStatement */:
                        // variable statement/for/for-of statement case,
                        // use site should not be inside variable declaration (initializer of declaration or binding element)
                        if (isSameScopeDescendentOf(usage, declaration, declContainer)) {
                            return true;
                        }
                        break;
                }
                // ForIn/ForOf case - use site should not be used in expression part
                var grandparent = declaration.parent.parent;
                return ts.isForInOrOfStatement(grandparent) && isSameScopeDescendentOf(usage, grandparent.expression, declContainer);
            }
            function isUsedInFunctionOrInstanceProperty(usage, declaration) {
                return !!ts.findAncestor(usage, function (current) {
                    if (current === declContainer) {
                        return "quit";
                    }
                    if (ts.isFunctionLike(current)) {
                        return true;
                    }
                    var initializerOfProperty = current.parent &&
                        current.parent.kind === 159 /* PropertyDeclaration */ &&
                        current.parent.initializer === current;
                    if (initializerOfProperty) {
                        if (ts.hasModifier(current.parent, 32 /* Static */)) {
                            if (declaration.kind === 161 /* MethodDeclaration */) {
                                return true;
                            }
                        }
                        else {
                            var isDeclarationInstanceProperty = declaration.kind === 159 /* PropertyDeclaration */ && !ts.hasModifier(declaration, 32 /* Static */);
                            if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) {
                                return true;
                            }
                        }
                    }
                    return false;
                });
            }
            /** stopAtAnyPropertyDeclaration is used for detecting ES-standard class field use-before-def errors */
            function isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, stopAtAnyPropertyDeclaration) {
                // always legal if usage is after declaration
                if (usage.end > declaration.end) {
                    return false;
                }
                // still might be legal if usage is deferred (e.g. x: any = () => this.x)
                // otherwise illegal if immediately referenced within the declaration (e.g. x: any = this.x)
                var ancestorChangingReferenceScope = ts.findAncestor(usage, function (node) {
                    if (node === declaration) {
                        return "quit";
                    }
                    switch (node.kind) {
                        case 202 /* ArrowFunction */:
                            return true;
                        case 159 /* PropertyDeclaration */:
                            // even when stopping at any property declaration, they need to come from the same class
                            return stopAtAnyPropertyDeclaration &&
                                (ts.isPropertyDeclaration(declaration) && node.parent === declaration.parent
                                    || ts.isParameterPropertyDeclaration(declaration, declaration.parent) && node.parent === declaration.parent.parent)
                                ? "quit" : true;
                        case 223 /* Block */:
                            switch (node.parent.kind) {
                                case 163 /* GetAccessor */:
                                case 161 /* MethodDeclaration */:
                                case 164 /* SetAccessor */:
                                    return true;
                                default:
                                    return false;
                            }
                        default:
                            return false;
                    }
                });
                return ancestorChangingReferenceScope === undefined;
            }
        }
        function useOuterVariableScopeInParameter(result, location, lastLocation) {
            var target = ts.getEmitScriptTarget(compilerOptions);
            var functionLocation = location;
            if (ts.isParameter(lastLocation) && functionLocation.body && result.valueDeclaration.pos >= functionLocation.body.pos && result.valueDeclaration.end <= functionLocation.body.end) {
                // check for several cases where we introduce temporaries that require moving the name/initializer of the parameter to the body
                // - static field in a class expression
                // - optional chaining pre-es2020
                // - nullish coalesce pre-es2020
                // - spread assignment in binding pattern pre-es2017
                if (target >= 2 /* ES2015 */) {
                    var links = getNodeLinks(functionLocation);
                    if (links.declarationRequiresScopeChange === undefined) {
                        links.declarationRequiresScopeChange = ts.forEach(functionLocation.parameters, requiresScopeChange) || false;
                    }
                    return !links.declarationRequiresScopeChange;
                }
            }
            return false;
            function requiresScopeChange(node) {
                return requiresScopeChangeWorker(node.name)
                    || !!node.initializer && requiresScopeChangeWorker(node.initializer);
            }
            function requiresScopeChangeWorker(node) {
                switch (node.kind) {
                    case 202 /* ArrowFunction */:
                    case 201 /* FunctionExpression */:
                    case 244 /* FunctionDeclaration */:
                    case 162 /* Constructor */:
                        // do not descend into these
                        return false;
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 281 /* PropertyAssignment */:
                        return requiresScopeChangeWorker(node.name);
                    case 159 /* PropertyDeclaration */:
                        // static properties in classes introduce temporary variables
                        if (ts.hasStaticModifier(node)) {
                            return target < 99 /* ESNext */ || !compilerOptions.useDefineForClassFields;
                        }
                        return requiresScopeChangeWorker(node.name);
                    default:
                        // null coalesce and optional chain pre-es2020 produce temporary variables
                        if (ts.isNullishCoalesce(node) || ts.isOptionalChain(node)) {
                            return target < 7 /* ES2020 */;
                        }
                        if (ts.isBindingElement(node) && node.dotDotDotToken && ts.isObjectBindingPattern(node.parent)) {
                            return target < 4 /* ES2017 */;
                        }
                        if (ts.isTypeNode(node))
                            return false;
                        return ts.forEachChild(node, requiresScopeChangeWorker) || false;
                }
            }
        }
        /**
         * Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
         * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with
         * the given name can be found.
         *
         * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters.
         */
        function resolveName(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, suggestedNameNotFoundMessage) {
            if (excludeGlobals === void 0) { excludeGlobals = false; }
            return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSymbol, suggestedNameNotFoundMessage);
        }
        function resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, lookup, suggestedNameNotFoundMessage) {
            var originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location
            var result;
            var lastLocation;
            var lastSelfReferenceLocation;
            var propertyWithInvalidInitializer;
            var associatedDeclarationForContainingInitializerOrBindingName;
            var withinDeferredContext = false;
            var errorLocation = location;
            var grandparent;
            var isInExternalModule = false;
            loop: while (location) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location.locals && !isGlobalSourceFile(location)) {
                    if (result = lookup(location.locals, name, meaning)) {
                        var useResult = true;
                        if (ts.isFunctionLike(location) && lastLocation && lastLocation !== location.body) {
                            // symbol lookup restrictions for function-like declarations
                            // - Type parameters of a function are in scope in the entire function declaration, including the parameter
                            //   list and return type. However, local types are only in scope in the function body.
                            // - parameters are only in the scope of function body
                            // This restriction does not apply to JSDoc comment types because they are parented
                            // at a higher level than type parameters would normally be
                            if (meaning & result.flags & 788968 /* Type */ && lastLocation.kind !== 303 /* JSDocComment */) {
                                useResult = result.flags & 262144 /* TypeParameter */
                                    // type parameters are visible in parameter list, return type and type parameter list
                                    ? lastLocation === location.type ||
                                        lastLocation.kind === 156 /* Parameter */ ||
                                        lastLocation.kind === 155 /* TypeParameter */
                                    // local types not visible outside the function body
                                    : false;
                            }
                            if (meaning & result.flags & 3 /* Variable */) {
                                // expression inside parameter will lookup as normal variable scope when targeting es2015+
                                if (useOuterVariableScopeInParameter(result, location, lastLocation)) {
                                    useResult = false;
                                }
                                else if (result.flags & 1 /* FunctionScopedVariable */) {
                                    // parameters are visible only inside function body, parameter list and return type
                                    // technically for parameter list case here we might mix parameters and variables declared in function,
                                    // however it is detected separately when checking initializers of parameters
                                    // to make sure that they reference no variables declared after them.
                                    useResult =
                                        lastLocation.kind === 156 /* Parameter */ ||
                                            (lastLocation === location.type &&
                                                !!ts.findAncestor(result.valueDeclaration, ts.isParameter));
                                }
                            }
                        }
                        else if (location.kind === 180 /* ConditionalType */) {
                            // A type parameter declared using 'infer T' in a conditional type is visible only in
                            // the true branch of the conditional type.
                            useResult = lastLocation === location.trueType;
                        }
                        if (useResult) {
                            break loop;
                        }
                        else {
                            result = undefined;
                        }
                    }
                }
                withinDeferredContext = withinDeferredContext || getIsDeferredContext(location, lastLocation);
                switch (location.kind) {
                    case 290 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location))
                            break;
                        isInExternalModule = true;
                    // falls through
                    case 249 /* ModuleDeclaration */:
                        var moduleExports = getSymbolOfNode(location).exports || emptySymbols;
                        if (location.kind === 290 /* SourceFile */ || (ts.isModuleDeclaration(location) && location.flags & 8388608 /* Ambient */ && !ts.isGlobalScopeAugmentation(location))) {
                            // It's an external module. First see if the module has an export default and if the local
                            // name of that export default matches.
                            if (result = moduleExports.get("default" /* Default */)) {
                                var localSymbol = ts.getLocalSymbolForExportDefault(result);
                                if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) {
                                    break loop;
                                }
                                result = undefined;
                            }
                            // Because of module/namespace merging, a module's exports are in scope,
                            // yet we never want to treat an export specifier as putting a member in scope.
                            // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
                            // Two things to note about this:
                            //     1. We have to check this without calling getSymbol. The problem with calling getSymbol
                            //        on an export specifier is that it might find the export specifier itself, and try to
                            //        resolve it as an alias. This will cause the checker to consider the export specifier
                            //        a circular alias reference when it might not be.
                            //     2. We check === SymbolFlags.Alias in order to check that the symbol is *purely*
                            //        an alias. If we used &, we'd be throwing out symbols that have non alias aspects,
                            //        which is not the desired behavior.
                            var moduleExport = moduleExports.get(name);
                            if (moduleExport &&
                                moduleExport.flags === 2097152 /* Alias */ &&
                                (ts.getDeclarationOfKind(moduleExport, 263 /* ExportSpecifier */) || ts.getDeclarationOfKind(moduleExport, 262 /* NamespaceExport */))) {
                                break;
                            }
                        }
                        // ES6 exports are also visible locally (except for 'default'), but commonjs exports are not (except typedefs)
                        if (name !== "default" /* Default */ && (result = lookup(moduleExports, name, meaning & 2623475 /* ModuleMember */))) {
                            if (ts.isSourceFile(location) && location.commonJsModuleIndicator && !result.declarations.some(ts.isJSDocTypeAlias)) {
                                result = undefined;
                            }
                            else {
                                break loop;
                            }
                        }
                        break;
                    case 248 /* EnumDeclaration */:
                        if (result = lookup(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) {
                            break loop;
                        }
                        break;
                    case 159 /* PropertyDeclaration */:
                        // TypeScript 1.0 spec (April 2014): 8.4.1
                        // Initializer expressions for instance member variables are evaluated in the scope
                        // of the class constructor body but are not permitted to reference parameters or
                        // local variables of the constructor. This effectively means that entities from outer scopes
                        // by the same name as a constructor parameter or local variable are inaccessible
                        // in initializer expressions for instance member variables.
                        if (!ts.hasModifier(location, 32 /* Static */)) {
                            var ctor = findConstructorDeclaration(location.parent);
                            if (ctor && ctor.locals) {
                                if (lookup(ctor.locals, name, meaning & 111551 /* Value */)) {
                                    // Remember the property node, it will be used later to report appropriate error
                                    propertyWithInvalidInitializer = location;
                                }
                            }
                        }
                        break;
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                        // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals
                        // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would
                        // trigger resolving late-bound names, which we may already be in the process of doing while we're here!
                        if (result = lookup(getSymbolOfNode(location).members || emptySymbols, name, meaning & 788968 /* Type */)) {
                            if (!isTypeParameterSymbolDeclaredInContainer(result, location)) {
                                // ignore type parameters not declared in this container
                                result = undefined;
                                break;
                            }
                            if (lastLocation && ts.hasModifier(lastLocation, 32 /* Static */)) {
                                // TypeScript 1.0 spec (April 2014): 3.4.1
                                // The scope of a type parameter extends over the entire declaration with which the type
                                // parameter list is associated, with the exception of static member declarations in classes.
                                error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters);
                                return undefined;
                            }
                            break loop;
                        }
                        if (location.kind === 214 /* ClassExpression */ && meaning & 32 /* Class */) {
                            var className = location.name;
                            if (className && name === className.escapedText) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 216 /* ExpressionWithTypeArguments */:
                        // The type parameters of a class are not in scope in the base class expression.
                        if (lastLocation === location.expression && location.parent.token === 90 /* ExtendsKeyword */) {
                            var container = location.parent.parent;
                            if (ts.isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & 788968 /* Type */))) {
                                if (nameNotFoundMessage) {
                                    error(errorLocation, ts.Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters);
                                }
                                return undefined;
                            }
                        }
                        break;
                    // It is not legal to reference a class's own type parameters from a computed property name that
                    // belongs to the class. For example:
                    //
                    //   function foo<T>() { return '' }
                    //   class C<T> { // <-- Class's own type parameter T
                    //       [foo<T>()]() { } // <-- Reference to T from class's own computed property
                    //   }
                    //
                    case 154 /* ComputedPropertyName */:
                        grandparent = location.parent.parent;
                        if (ts.isClassLike(grandparent) || grandparent.kind === 246 /* InterfaceDeclaration */) {
                            // A reference to this grandparent's type parameters would be an error
                            if (result = lookup(getSymbolOfNode(grandparent).members, name, meaning & 788968 /* Type */)) {
                                error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type);
                                return undefined;
                            }
                        }
                        break;
                    case 202 /* ArrowFunction */:
                        // when targeting ES6 or higher there is no 'arguments' in an arrow function
                        // for lower compile targets the resolved symbol is used to emit an error
                        if (compilerOptions.target >= 2 /* ES2015 */) {
                            break;
                        }
                    // falls through
                    case 161 /* MethodDeclaration */:
                    case 162 /* Constructor */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 244 /* FunctionDeclaration */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        break;
                    case 201 /* FunctionExpression */:
                        if (meaning & 3 /* Variable */ && name === "arguments") {
                            result = argumentsSymbol;
                            break loop;
                        }
                        if (meaning & 16 /* Function */) {
                            var functionName = location.name;
                            if (functionName && name === functionName.escapedText) {
                                result = location.symbol;
                                break loop;
                            }
                        }
                        break;
                    case 157 /* Decorator */:
                        // Decorators are resolved at the class declaration. Resolving at the parameter
                        // or member would result in looking up locals in the method.
                        //
                        //   function y() {}
                        //   class C {
                        //       method(@y x, y) {} // <-- decorator y should be resolved at the class declaration, not the parameter.
                        //   }
                        //
                        if (location.parent && location.parent.kind === 156 /* Parameter */) {
                            location = location.parent;
                        }
                        //
                        //   function y() {}
                        //   class C {
                        //       @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method.
                        //   }
                        //
                        // class Decorators are resolved outside of the class to avoid referencing type parameters of that class.
                        //
                        //   type T = number;
                        //   declare function y(x: T): any;
                        //   @param(1 as T) // <-- T should resolve to the type alias outside of class C
                        //   class C<T> {}
                        if (location.parent && (ts.isClassElement(location.parent) || location.parent.kind === 245 /* ClassDeclaration */)) {
                            location = location.parent;
                        }
                        break;
                    case 322 /* JSDocTypedefTag */:
                    case 315 /* JSDocCallbackTag */:
                    case 316 /* JSDocEnumTag */:
                        // js type aliases do not resolve names from their host, so skip past it
                        location = ts.getJSDocHost(location);
                        break;
                    case 156 /* Parameter */:
                        if (lastLocation && (lastLocation === location.initializer ||
                            lastLocation === location.name && ts.isBindingPattern(lastLocation))) {
                            if (!associatedDeclarationForContainingInitializerOrBindingName) {
                                associatedDeclarationForContainingInitializerOrBindingName = location;
                            }
                        }
                        break;
                    case 191 /* BindingElement */:
                        if (lastLocation && (lastLocation === location.initializer ||
                            lastLocation === location.name && ts.isBindingPattern(lastLocation))) {
                            var root = ts.getRootDeclaration(location);
                            if (root.kind === 156 /* Parameter */) {
                                if (!associatedDeclarationForContainingInitializerOrBindingName) {
                                    associatedDeclarationForContainingInitializerOrBindingName = location;
                                }
                            }
                        }
                        break;
                }
                if (isSelfReferenceLocation(location)) {
                    lastSelfReferenceLocation = location;
                }
                lastLocation = location;
                location = location.parent;
            }
            // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
            // If `result === lastSelfReferenceLocation.symbol`, that means that we are somewhere inside `lastSelfReferenceLocation` looking up a name, and resolving to `lastLocation` itself.
            // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used.
            if (isUse && result && (!lastSelfReferenceLocation || result !== lastSelfReferenceLocation.symbol)) {
                result.isReferenced |= meaning;
            }
            if (!result) {
                if (lastLocation) {
                    ts.Debug.assert(lastLocation.kind === 290 /* SourceFile */);
                    if (lastLocation.commonJsModuleIndicator && name === "exports" && meaning & lastLocation.symbol.flags) {
                        return lastLocation.symbol;
                    }
                }
                if (!excludeGlobals) {
                    result = lookup(globals, name, meaning);
                }
            }
            if (!result) {
                if (originalLocation && ts.isInJSFile(originalLocation) && originalLocation.parent) {
                    if (ts.isRequireCall(originalLocation.parent, /*checkArgumentIsStringLiteralLike*/ false)) {
                        return requireSymbol;
                    }
                }
            }
            if (!result) {
                if (nameNotFoundMessage) {
                    if (!errorLocation ||
                        !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && // TODO: GH#18217
                            !checkAndReportErrorForExtendingInterface(errorLocation) &&
                            !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
                            !checkAndReportErrorForExportingPrimitiveType(errorLocation, name) &&
                            !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) &&
                            !checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning)) {
                        var suggestion = void 0;
                        if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) {
                            suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
                            if (suggestion) {
                                var suggestionName = symbolToString(suggestion);
                                var diagnostic = error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg), suggestionName);
                                if (suggestion.valueDeclaration) {
                                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName));
                                }
                            }
                        }
                        if (!suggestion) {
                            error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg));
                        }
                        suggestionCount++;
                    }
                }
                return undefined;
            }
            // Perform extra checks only if error reporting was requested
            if (nameNotFoundMessage) {
                if (propertyWithInvalidInitializer && !(compilerOptions.target === 99 /* ESNext */ && compilerOptions.useDefineForClassFields)) {
                    // We have a match, but the reference occurred within a property initializer and the identifier also binds
                    // to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
                    // with ESNext+useDefineForClassFields because the scope semantics are different.
                    var propertyName = propertyWithInvalidInitializer.name;
                    error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), diagnosticName(nameArg));
                    return undefined;
                }
                // Only check for block-scoped variable if we have an error location and are looking for the
                // name with variable meaning
                //      For example,
                //          declare module foo {
                //              interface bar {}
                //          }
                //      const foo/*1*/: foo/*2*/.bar;
                // The foo at /*1*/ and /*2*/ will share same symbol with two meanings:
                // block-scoped variable and namespace module. However, only when we
                // try to resolve name in /*1*/ which is used in variable position,
                // we want to check for block-scoped
                if (errorLocation &&
                    (meaning & 2 /* BlockScopedVariable */ ||
                        ((meaning & 32 /* Class */ || meaning & 384 /* Enum */) && (meaning & 111551 /* Value */) === 111551 /* Value */))) {
                    var exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result);
                    if (exportOrLocalSymbol.flags & 2 /* BlockScopedVariable */ || exportOrLocalSymbol.flags & 32 /* Class */ || exportOrLocalSymbol.flags & 384 /* Enum */) {
                        checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation);
                    }
                }
                // If we're in an external module, we can't reference value symbols created from UMD export declarations
                if (result && isInExternalModule && (meaning & 111551 /* Value */) === 111551 /* Value */ && !(originalLocation.flags & 4194304 /* JSDoc */)) {
                    var merged = getMergedSymbol(result);
                    if (ts.length(merged.declarations) && ts.every(merged.declarations, function (d) { return ts.isNamespaceExportDeclaration(d) || ts.isSourceFile(d) && !!d.symbol.globalExports; })) {
                        errorOrSuggestion(!compilerOptions.allowUmdGlobalAccess, errorLocation, ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, ts.unescapeLeadingUnderscores(name));
                    }
                }
                // If we're in a parameter initializer or binding name, we can't reference the values of the parameter whose initializer we're within or parameters to the right
                if (result && associatedDeclarationForContainingInitializerOrBindingName && !withinDeferredContext && (meaning & 111551 /* Value */) === 111551 /* Value */) {
                    var candidate = getMergedSymbol(getLateBoundSymbol(result));
                    var root = ts.getRootDeclaration(associatedDeclarationForContainingInitializerOrBindingName);
                    // A parameter initializer or binding pattern initializer within a parameter cannot refer to itself
                    if (candidate === getSymbolOfNode(associatedDeclarationForContainingInitializerOrBindingName)) {
                        error(errorLocation, ts.Diagnostics.Parameter_0_cannot_reference_itself, ts.declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name));
                    }
                    // And it cannot refer to any declarations which come after it
                    else if (candidate.valueDeclaration && candidate.valueDeclaration.pos > associatedDeclarationForContainingInitializerOrBindingName.pos && root.parent.locals && lookup(root.parent.locals, candidate.escapedName, meaning) === candidate) {
                        error(errorLocation, ts.Diagnostics.Parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(associatedDeclarationForContainingInitializerOrBindingName.name), ts.declarationNameToString(errorLocation));
                    }
                }
                if (result && errorLocation && meaning & 111551 /* Value */ && result.flags & 2097152 /* Alias */) {
                    checkSymbolUsageInExpressionContext(result, name, errorLocation);
                }
            }
            return result;
        }
        function checkSymbolUsageInExpressionContext(symbol, name, useSite) {
            if (!ts.isValidTypeOnlyAliasUseSite(useSite)) {
                var typeOnlyDeclaration = getTypeOnlyAliasDeclaration(symbol);
                if (typeOnlyDeclaration) {
                    var isExport = ts.typeOnlyDeclarationIsExport(typeOnlyDeclaration);
                    var message = isExport
                        ? ts.Diagnostics._0_cannot_be_used_as_a_value_because_it_was_exported_using_export_type
                        : ts.Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type;
                    var relatedMessage = isExport
                        ? ts.Diagnostics._0_was_exported_here
                        : ts.Diagnostics._0_was_imported_here;
                    var unescapedName = ts.unescapeLeadingUnderscores(name);
                    ts.addRelatedInfo(error(useSite, message, unescapedName), ts.createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, unescapedName));
                }
            }
        }
        function getIsDeferredContext(location, lastLocation) {
            if (location.kind !== 202 /* ArrowFunction */ && location.kind !== 201 /* FunctionExpression */) {
                // initializers in instance property declaration of class like entities are executed in constructor and thus deferred
                return ts.isTypeQueryNode(location) || ((ts.isFunctionLikeDeclaration(location) ||
                    (location.kind === 159 /* PropertyDeclaration */ && !ts.hasModifier(location, 32 /* Static */))) && (!lastLocation || lastLocation !== location.name)); // A name is evaluated within the enclosing scope - so it shouldn't count as deferred
            }
            if (lastLocation && lastLocation === location.name) {
                return false;
            }
            // generator functions and async functions are not inlined in control flow when immediately invoked
            if (location.asteriskToken || ts.hasModifier(location, 256 /* Async */)) {
                return true;
            }
            return !ts.getImmediatelyInvokedFunctionExpression(location);
        }
        function isSelfReferenceLocation(node) {
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                case 245 /* ClassDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 248 /* EnumDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 249 /* ModuleDeclaration */: // For `namespace N { N; }`
                    return true;
                default:
                    return false;
            }
        }
        function diagnosticName(nameArg) {
            return ts.isString(nameArg) ? ts.unescapeLeadingUnderscores(nameArg) : ts.declarationNameToString(nameArg);
        }
        function isTypeParameterSymbolDeclaredInContainer(symbol, container) {
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (decl.kind === 155 /* TypeParameter */) {
                    var parent = ts.isJSDocTemplateTag(decl.parent) ? ts.getJSDocHost(decl.parent) : decl.parent;
                    if (parent === container) {
                        return !(ts.isJSDocTemplateTag(decl.parent) && ts.find(decl.parent.parent.tags, ts.isJSDocTypeAlias)); // TODO: GH#18217
                    }
                }
            }
            return false;
        }
        function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) {
            if (!ts.isIdentifier(errorLocation) || errorLocation.escapedText !== name || isTypeReferenceIdentifier(errorLocation) || isInTypeQuery(errorLocation)) {
                return false;
            }
            var container = ts.getThisContainer(errorLocation, /*includeArrowFunctions*/ false);
            var location = container;
            while (location) {
                if (ts.isClassLike(location.parent)) {
                    var classSymbol = getSymbolOfNode(location.parent);
                    if (!classSymbol) {
                        break;
                    }
                    // Check to see if a static member exists.
                    var constructorType = getTypeOfSymbol(classSymbol);
                    if (getPropertyOfType(constructorType, name)) {
                        error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol));
                        return true;
                    }
                    // No static member is present.
                    // Check if we're in an instance method and look for a relevant instance member.
                    if (location === container && !ts.hasModifier(location, 32 /* Static */)) {
                        var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; // TODO: GH#18217
                        if (getPropertyOfType(instanceType, name)) {
                            error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg));
                            return true;
                        }
                    }
                }
                location = location.parent;
            }
            return false;
        }
        function checkAndReportErrorForExtendingInterface(errorLocation) {
            var expression = getEntityNameForExtendingInterface(errorLocation);
            if (expression && resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)) {
                error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression));
                return true;
            }
            return false;
        }
        /**
         * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression,
         * but returns undefined if that expression is not an EntityNameExpression.
         */
        function getEntityNameForExtendingInterface(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                case 194 /* PropertyAccessExpression */:
                    return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined;
                case 216 /* ExpressionWithTypeArguments */:
                    if (ts.isEntityNameExpression(node.expression)) {
                        return node.expression;
                    }
                // falls through
                default:
                    return undefined;
            }
        }
        function checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) {
            var namespaceMeaning = 1920 /* Namespace */ | (ts.isInJSFile(errorLocation) ? 111551 /* Value */ : 0);
            if (meaning === namespaceMeaning) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 788968 /* Type */ & ~namespaceMeaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                var parent = errorLocation.parent;
                if (symbol) {
                    if (ts.isQualifiedName(parent)) {
                        ts.Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace");
                        var propName = parent.right.escapedText;
                        var propType = getPropertyOfType(getDeclaredTypeOfSymbol(symbol), propName);
                        if (propType) {
                            error(parent, ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, ts.unescapeLeadingUnderscores(name), ts.unescapeLeadingUnderscores(propName));
                            return true;
                        }
                    }
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkAndReportErrorForUsingValueAsType(errorLocation, name, meaning) {
            if (meaning & (788968 /* Type */ & ~1920 /* Namespace */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, ~788968 /* Type */ & 111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol && !(symbol.flags & 1920 /* Namespace */)) {
                    error(errorLocation, ts.Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function isPrimitiveTypeName(name) {
            return name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never" || name === "unknown";
        }
        function checkAndReportErrorForExportingPrimitiveType(errorLocation, name) {
            if (isPrimitiveTypeName(name) && errorLocation.parent.kind === 263 /* ExportSpecifier */) {
                error(errorLocation, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, name);
                return true;
            }
            return false;
        }
        function checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) {
            if (meaning & (111551 /* Value */ & ~1024 /* NamespaceModule */)) {
                if (isPrimitiveTypeName(name)) {
                    error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
                var symbol = resolveSymbol(resolveName(errorLocation, name, 788968 /* Type */ & ~111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol && !(symbol.flags & 1024 /* NamespaceModule */)) {
                    var message = isES2015OrLaterConstructorName(name)
                        ? ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later
                        : ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here;
                    error(errorLocation, message, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function isES2015OrLaterConstructorName(n) {
            switch (n) {
                case "Promise":
                case "Symbol":
                case "Map":
                case "WeakMap":
                case "Set":
                case "WeakSet":
                    return true;
            }
            return false;
        }
        function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) {
            if (meaning & (111551 /* Value */ & ~1024 /* NamespaceModule */ & ~788968 /* Type */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, 1024 /* NamespaceModule */ & ~111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol) {
                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_value, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            else if (meaning & (788968 /* Type */ & ~1024 /* NamespaceModule */ & ~111551 /* Value */)) {
                var symbol = resolveSymbol(resolveName(errorLocation, name, (512 /* ValueModule */ | 1024 /* NamespaceModule */) & ~788968 /* Type */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false));
                if (symbol) {
                    error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_type, ts.unescapeLeadingUnderscores(name));
                    return true;
                }
            }
            return false;
        }
        function checkResolvedBlockScopedVariable(result, errorLocation) {
            ts.Debug.assert(!!(result.flags & 2 /* BlockScopedVariable */ || result.flags & 32 /* Class */ || result.flags & 384 /* Enum */));
            if (result.flags & (16 /* Function */ | 1 /* FunctionScopedVariable */ | 67108864 /* Assignment */) && result.flags & 32 /* Class */) {
                // constructor functions aren't block scoped
                return;
            }
            // Block-scoped variables cannot be used before their definition
            var declaration = ts.find(result.declarations, function (d) { return ts.isBlockOrCatchScoped(d) || ts.isClassLike(d) || (d.kind === 248 /* EnumDeclaration */); });
            if (declaration === undefined)
                return ts.Debug.fail("checkResolvedBlockScopedVariable could not find block-scoped declaration");
            if (!(declaration.flags & 8388608 /* Ambient */) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
                var diagnosticMessage = void 0;
                var declarationName = ts.declarationNameToString(ts.getNameOfDeclaration(declaration));
                if (result.flags & 2 /* BlockScopedVariable */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationName);
                }
                else if (result.flags & 32 /* Class */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
                }
                else if (result.flags & 256 /* RegularEnum */) {
                    diagnosticMessage = error(errorLocation, ts.Diagnostics.Enum_0_used_before_its_declaration, declarationName);
                }
                else {
                    ts.Debug.assert(!!(result.flags & 128 /* ConstEnum */));
                    if (compilerOptions.preserveConstEnums) {
                        diagnosticMessage = error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
                    }
                }
                if (diagnosticMessage) {
                    ts.addRelatedInfo(diagnosticMessage, ts.createDiagnosticForNode(declaration, ts.Diagnostics._0_is_declared_here, declarationName));
                }
            }
        }
        /* Starting from 'initial' node walk up the parent chain until 'stopAt' node is reached.
         * If at any point current node is equal to 'parent' node - return true.
         * Return false if 'stopAt' node is reached or isFunctionLike(current) === true.
         */
        function isSameScopeDescendentOf(initial, parent, stopAt) {
            return !!parent && !!ts.findAncestor(initial, function (n) { return n === stopAt || ts.isFunctionLike(n) ? "quit" : n === parent; });
        }
        function getAnyImportSyntax(node) {
            switch (node.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    return node;
                case 255 /* ImportClause */:
                    return node.parent;
                case 256 /* NamespaceImport */:
                    return node.parent.parent;
                case 258 /* ImportSpecifier */:
                    return node.parent.parent.parent;
                default:
                    return undefined;
            }
        }
        function getDeclarationOfAliasSymbol(symbol) {
            return ts.find(symbol.declarations, isAliasSymbolDeclaration);
        }
        /**
         * An alias symbol is created by one of the following declarations:
         * import <symbol> = ...
         * import <symbol> from ...
         * import * as <symbol> from ...
         * import { x as <symbol> } from ...
         * export { x as <symbol> } from ...
         * export * as ns <symbol> from ...
         * export = <EntityNameExpression>
         * export default <EntityNameExpression>
         * module.exports = <EntityNameExpression>
         * {<Identifier>}
         * {name: <EntityNameExpression>}
         */
        function isAliasSymbolDeclaration(node) {
            return node.kind === 253 /* ImportEqualsDeclaration */ ||
                node.kind === 252 /* NamespaceExportDeclaration */ ||
                node.kind === 255 /* ImportClause */ && !!node.name ||
                node.kind === 256 /* NamespaceImport */ ||
                node.kind === 262 /* NamespaceExport */ ||
                node.kind === 258 /* ImportSpecifier */ ||
                node.kind === 263 /* ExportSpecifier */ ||
                node.kind === 259 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node) ||
                ts.isBinaryExpression(node) && ts.getAssignmentDeclarationKind(node) === 2 /* ModuleExports */ && ts.exportAssignmentIsAlias(node) ||
                ts.isPropertyAccessExpression(node)
                    && ts.isBinaryExpression(node.parent)
                    && node.parent.left === node
                    && node.parent.operatorToken.kind === 62 /* EqualsToken */
                    && isAliasableOrJsExpression(node.parent.right) ||
                node.kind === 282 /* ShorthandPropertyAssignment */ ||
                node.kind === 281 /* PropertyAssignment */ && isAliasableOrJsExpression(node.initializer);
        }
        function isAliasableOrJsExpression(e) {
            return ts.isAliasableExpression(e) || ts.isFunctionExpression(e) && isJSConstructor(e);
        }
        function getTargetOfImportEqualsDeclaration(node, dontResolveAlias) {
            if (node.moduleReference.kind === 265 /* ExternalModuleReference */) {
                var immediate = resolveExternalModuleName(node, ts.getExternalModuleImportEqualsDeclarationExpression(node));
                var resolved_4 = resolveExternalModuleSymbol(immediate);
                markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved_4, /*overwriteEmpty*/ false);
                return resolved_4;
            }
            var resolved = getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias);
            checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node, resolved);
            return resolved;
        }
        function checkAndReportErrorForResolvingImportAliasToTypeOnlySymbol(node, resolved) {
            if (markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false)) {
                var typeOnlyDeclaration = getTypeOnlyAliasDeclaration(getSymbolOfNode(node));
                var isExport = ts.typeOnlyDeclarationIsExport(typeOnlyDeclaration);
                var message = isExport
                    ? ts.Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_exported_using_export_type
                    : ts.Diagnostics.An_import_alias_cannot_reference_a_declaration_that_was_imported_using_import_type;
                var relatedMessage = isExport
                    ? ts.Diagnostics._0_was_exported_here
                    : ts.Diagnostics._0_was_imported_here;
                // Non-null assertion is safe because the optionality comes from ImportClause,
                // but if an ImportClause was the typeOnlyDeclaration, it had to have a `name`.
                var name = ts.unescapeLeadingUnderscores(typeOnlyDeclaration.name.escapedText);
                ts.addRelatedInfo(error(node.moduleReference, message), ts.createDiagnosticForNode(typeOnlyDeclaration, relatedMessage, name));
            }
        }
        function resolveExportByName(moduleSymbol, name, sourceNode, dontResolveAlias) {
            var exportValue = moduleSymbol.exports.get("export=" /* ExportEquals */);
            if (exportValue) {
                return getPropertyOfType(getTypeOfSymbol(exportValue), name);
            }
            var exportSymbol = moduleSymbol.exports.get(name);
            var resolved = resolveSymbol(exportSymbol, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(sourceNode, exportSymbol, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function isSyntacticDefault(node) {
            return ((ts.isExportAssignment(node) && !node.isExportEquals) || ts.hasModifier(node, 512 /* Default */) || ts.isExportSpecifier(node));
        }
        function canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias) {
            if (!allowSyntheticDefaultImports) {
                return false;
            }
            // Declaration files (and ambient modules)
            if (!file || file.isDeclarationFile) {
                // Definitely cannot have a synthetic default if they have a syntactic default member specified
                var defaultExportSymbol = resolveExportByName(moduleSymbol, "default" /* Default */, /*sourceNode*/ undefined, /*dontResolveAlias*/ true); // Dont resolve alias because we want the immediately exported symbol's declaration
                if (defaultExportSymbol && ts.some(defaultExportSymbol.declarations, isSyntacticDefault)) {
                    return false;
                }
                // It _might_ still be incorrect to assume there is no __esModule marker on the import at runtime, even if there is no `default` member
                // So we check a bit more,
                if (resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias)) {
                    // If there is an `__esModule` specified in the declaration (meaning someone explicitly added it or wrote it in their code),
                    // it definitely is a module and does not have a synthetic default
                    return false;
                }
                // There are _many_ declaration files not written with esmodules in mind that still get compiled into a format with __esModule set
                // Meaning there may be no default at runtime - however to be on the permissive side, we allow access to a synthetic default member
                // as there is no marker to indicate if the accompanying JS has `__esModule` or not, or is even native esm
                return true;
            }
            // TypeScript files never have a synthetic default (as they are always emitted with an __esModule marker) _unless_ they contain an export= statement
            if (!ts.isSourceFileJS(file)) {
                return hasExportAssignmentSymbol(moduleSymbol);
            }
            // JS files have a synthetic default if they do not contain ES2015+ module syntax (export = is not valid in js) _and_ do not have an __esModule marker
            return !file.externalModuleIndicator && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias);
        }
        function getTargetOfImportClause(node, dontResolveAlias) {
            var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier);
            if (moduleSymbol) {
                var exportDefaultSymbol = void 0;
                if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                    exportDefaultSymbol = moduleSymbol;
                }
                else {
                    exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* Default */, node, dontResolveAlias);
                }
                var file = ts.find(moduleSymbol.declarations, ts.isSourceFile);
                var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias);
                if (!exportDefaultSymbol && !hasSyntheticDefault) {
                    if (hasExportAssignmentSymbol(moduleSymbol)) {
                        var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop";
                        var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* ExportEquals */);
                        var exportAssignment = exportEqualsSymbol.valueDeclaration;
                        var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName);
                        ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName));
                    }
                    else {
                        reportNonDefaultExport(moduleSymbol, node);
                    }
                }
                else if (hasSyntheticDefault) {
                    // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present
                    var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
                    markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false);
                    return resolved;
                }
                markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false);
                return exportDefaultSymbol;
            }
        }
        function reportNonDefaultExport(moduleSymbol, node) {
            var _a, _b;
            if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has(node.symbol.escapedName)) {
                error(node.name, ts.Diagnostics.Module_0_has_no_default_export_Did_you_mean_to_use_import_1_from_0_instead, symbolToString(moduleSymbol), symbolToString(node.symbol));
            }
            else {
                var diagnostic = error(node.name, ts.Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol));
                var exportStar = (_b = moduleSymbol.exports) === null || _b === void 0 ? void 0 : _b.get("__export" /* ExportStar */);
                if (exportStar) {
                    var defaultExport = ts.find(exportStar.declarations, function (decl) {
                        var _a, _b;
                        return !!(ts.isExportDeclaration(decl) && decl.moduleSpecifier && ((_b = (_a = resolveExternalModuleName(decl, decl.moduleSpecifier)) === null || _a === void 0 ? void 0 : _a.exports) === null || _b === void 0 ? void 0 : _b.has("default" /* Default */)));
                    });
                    if (defaultExport) {
                        ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(defaultExport, ts.Diagnostics.export_Asterisk_does_not_re_export_a_default));
                    }
                }
            }
        }
        function getTargetOfNamespaceImport(node, dontResolveAlias) {
            var moduleSpecifier = node.parent.parent.moduleSpecifier;
            var immediate = resolveExternalModuleName(node, moduleSpecifier);
            var resolved = resolveESModuleSymbol(immediate, moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
            markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfNamespaceExport(node, dontResolveAlias) {
            var moduleSpecifier = node.parent.moduleSpecifier;
            var immediate = moduleSpecifier && resolveExternalModuleName(node, moduleSpecifier);
            var resolved = moduleSpecifier && resolveESModuleSymbol(immediate, moduleSpecifier, dontResolveAlias, /*suppressUsageError*/ false);
            markSymbolOfAliasDeclarationIfTypeOnly(node, immediate, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        // This function creates a synthetic symbol that combines the value side of one symbol with the
        // type/namespace side of another symbol. Consider this example:
        //
        //   declare module graphics {
        //       interface Point {
        //           x: number;
        //           y: number;
        //       }
        //   }
        //   declare var graphics: {
        //       Point: new (x: number, y: number) => graphics.Point;
        //   }
        //   declare module "graphics" {
        //       export = graphics;
        //   }
        //
        // An 'import { Point } from "graphics"' needs to create a symbol that combines the value side 'Point'
        // property with the type/namespace side interface 'Point'.
        function combineValueAndTypeSymbols(valueSymbol, typeSymbol) {
            if (valueSymbol === unknownSymbol && typeSymbol === unknownSymbol) {
                return unknownSymbol;
            }
            if (valueSymbol.flags & (788968 /* Type */ | 1920 /* Namespace */)) {
                return valueSymbol;
            }
            var result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName);
            result.declarations = ts.deduplicate(ts.concatenate(valueSymbol.declarations, typeSymbol.declarations), ts.equateValues);
            result.parent = valueSymbol.parent || typeSymbol.parent;
            if (valueSymbol.valueDeclaration)
                result.valueDeclaration = valueSymbol.valueDeclaration;
            if (typeSymbol.members)
                result.members = ts.cloneMap(typeSymbol.members);
            if (valueSymbol.exports)
                result.exports = ts.cloneMap(valueSymbol.exports);
            return result;
        }
        function getExportOfModule(symbol, specifier, dontResolveAlias) {
            var _a;
            if (symbol.flags & 1536 /* Module */) {
                var name = ((_a = specifier.propertyName) !== null && _a !== void 0 ? _a : specifier.name).escapedText;
                var exportSymbol = getExportsOfSymbol(symbol).get(name);
                var resolved = resolveSymbol(exportSymbol, dontResolveAlias);
                markSymbolOfAliasDeclarationIfTypeOnly(specifier, exportSymbol, resolved, /*overwriteEmpty*/ false);
                return resolved;
            }
        }
        function getPropertyOfVariable(symbol, name) {
            if (symbol.flags & 3 /* Variable */) {
                var typeAnnotation = symbol.valueDeclaration.type;
                if (typeAnnotation) {
                    return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name));
                }
            }
        }
        function getExternalModuleMember(node, specifier, dontResolveAlias) {
            var _a;
            if (dontResolveAlias === void 0) { dontResolveAlias = false; }
            var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); // TODO: GH#18217
            var name = specifier.propertyName || specifier.name;
            var suppressInteropError = name.escapedText === "default" /* Default */ && !!(compilerOptions.allowSyntheticDefaultImports || compilerOptions.esModuleInterop);
            var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias, suppressInteropError);
            if (targetSymbol) {
                if (name.escapedText) {
                    if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                        return moduleSymbol;
                    }
                    var symbolFromVariable = void 0;
                    // First check if module was specified with "export=". If so, get the member from the resolved type
                    if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=" /* ExportEquals */)) {
                        symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText);
                    }
                    else {
                        symbolFromVariable = getPropertyOfVariable(targetSymbol, name.escapedText);
                    }
                    // if symbolFromVariable is export - get its final target
                    symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias);
                    var symbolFromModule = getExportOfModule(targetSymbol, specifier, dontResolveAlias);
                    if (symbolFromModule === undefined && name.escapedText === "default" /* Default */) {
                        var file = ts.find(moduleSymbol.declarations, ts.isSourceFile);
                        if (canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias)) {
                            symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias);
                        }
                    }
                    var symbol = symbolFromModule && symbolFromVariable && symbolFromModule !== symbolFromVariable ?
                        combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) :
                        symbolFromModule || symbolFromVariable;
                    if (!symbol) {
                        var moduleName = getFullyQualifiedName(moduleSymbol, node);
                        var declarationName = ts.declarationNameToString(name);
                        var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
                        if (suggestion !== undefined) {
                            var suggestionName = symbolToString(suggestion);
                            var diagnostic = error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
                            if (suggestion.valueDeclaration) {
                                ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName));
                            }
                        }
                        else {
                            if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has("default" /* Default */)) {
                                error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName);
                            }
                            else {
                                reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName);
                            }
                        }
                    }
                    return symbol;
                }
            }
        }
        function reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName) {
            var _a;
            var localSymbol = (_a = moduleSymbol.valueDeclaration.locals) === null || _a === void 0 ? void 0 : _a.get(name.escapedText);
            var exports = moduleSymbol.exports;
            if (localSymbol) {
                var exportedEqualsSymbol = exports === null || exports === void 0 ? void 0 : exports.get("export=" /* ExportEquals */);
                if (exportedEqualsSymbol) {
                    getSymbolIfSameReference(exportedEqualsSymbol, localSymbol) ? reportInvalidImportEqualsExportMember(node, name, declarationName, moduleName) :
                        error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
                }
                else {
                    var exportedSymbol = exports ? ts.find(symbolsToArray(exports), function (symbol) { return !!getSymbolIfSameReference(symbol, localSymbol); }) : undefined;
                    var diagnostic = exportedSymbol ? error(name, ts.Diagnostics.Module_0_declares_1_locally_but_it_is_exported_as_2, moduleName, declarationName, symbolToString(exportedSymbol)) :
                        error(name, ts.Diagnostics.Module_0_declares_1_locally_but_it_is_not_exported, moduleName, declarationName);
                    ts.addRelatedInfo.apply(void 0, __spreadArrays([diagnostic], ts.map(localSymbol.declarations, function (decl, index) {
                        return ts.createDiagnosticForNode(decl, index === 0 ? ts.Diagnostics._0_is_declared_here : ts.Diagnostics.and_here, declarationName);
                    })));
                }
            }
            else {
                error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
            }
        }
        function reportInvalidImportEqualsExportMember(node, name, declarationName, moduleName) {
            if (moduleKind >= ts.ModuleKind.ES2015) {
                var message = compilerOptions.esModuleInterop ? ts.Diagnostics._0_can_only_be_imported_by_using_a_default_import :
                    ts.Diagnostics._0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
                error(name, message, declarationName);
            }
            else {
                if (ts.isInJSFile(node)) {
                    var message = compilerOptions.esModuleInterop ? ts.Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import :
                        ts.Diagnostics._0_can_only_be_imported_by_using_a_require_call_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
                    error(name, message, declarationName);
                }
                else {
                    var message = compilerOptions.esModuleInterop ? ts.Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_a_default_import :
                        ts.Diagnostics._0_can_only_be_imported_by_using_import_1_require_2_or_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import;
                    error(name, message, declarationName, declarationName, moduleName);
                }
            }
        }
        function getTargetOfImportSpecifier(node, dontResolveAlias) {
            var resolved = getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfNamespaceExportDeclaration(node, dontResolveAlias) {
            var resolved = resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) {
            var resolved = node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node, dontResolveAlias) :
                resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfExportAssignment(node, dontResolveAlias) {
            var expression = ts.isExportAssignment(node) ? node.expression : node.right;
            var resolved = getTargetOfAliasLikeExpression(expression, dontResolveAlias);
            markSymbolOfAliasDeclarationIfTypeOnly(node, /*immediateTarget*/ undefined, resolved, /*overwriteEmpty*/ false);
            return resolved;
        }
        function getTargetOfAliasLikeExpression(expression, dontResolveAlias) {
            if (ts.isClassExpression(expression)) {
                return checkExpressionCached(expression).symbol;
            }
            if (!ts.isEntityName(expression) && !ts.isEntityNameExpression(expression)) {
                return undefined;
            }
            var aliasLike = resolveEntityName(expression, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ true, dontResolveAlias);
            if (aliasLike) {
                return aliasLike;
            }
            checkExpressionCached(expression);
            return getNodeLinks(expression).resolvedSymbol;
        }
        function getTargetOfPropertyAssignment(node, dontRecursivelyResolve) {
            var expression = node.initializer;
            return getTargetOfAliasLikeExpression(expression, dontRecursivelyResolve);
        }
        function getTargetOfPropertyAccessExpression(node, dontRecursivelyResolve) {
            if (!(ts.isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === 62 /* EqualsToken */)) {
                return undefined;
            }
            return getTargetOfAliasLikeExpression(node.parent.right, dontRecursivelyResolve);
        }
        function getTargetOfAliasDeclaration(node, dontRecursivelyResolve) {
            if (dontRecursivelyResolve === void 0) { dontRecursivelyResolve = false; }
            switch (node.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    return getTargetOfImportEqualsDeclaration(node, dontRecursivelyResolve);
                case 255 /* ImportClause */:
                    return getTargetOfImportClause(node, dontRecursivelyResolve);
                case 256 /* NamespaceImport */:
                    return getTargetOfNamespaceImport(node, dontRecursivelyResolve);
                case 262 /* NamespaceExport */:
                    return getTargetOfNamespaceExport(node, dontRecursivelyResolve);
                case 258 /* ImportSpecifier */:
                    return getTargetOfImportSpecifier(node, dontRecursivelyResolve);
                case 263 /* ExportSpecifier */:
                    return getTargetOfExportSpecifier(node, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, dontRecursivelyResolve);
                case 259 /* ExportAssignment */:
                case 209 /* BinaryExpression */:
                    return getTargetOfExportAssignment(node, dontRecursivelyResolve);
                case 252 /* NamespaceExportDeclaration */:
                    return getTargetOfNamespaceExportDeclaration(node, dontRecursivelyResolve);
                case 282 /* ShorthandPropertyAssignment */:
                    return resolveEntityName(node.name, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ true, dontRecursivelyResolve);
                case 281 /* PropertyAssignment */:
                    return getTargetOfPropertyAssignment(node, dontRecursivelyResolve);
                case 194 /* PropertyAccessExpression */:
                    return getTargetOfPropertyAccessExpression(node, dontRecursivelyResolve);
                default:
                    return ts.Debug.fail();
            }
        }
        /**
         * Indicates that a symbol is an alias that does not merge with a local declaration.
         * OR Is a JSContainer which may merge an alias with a local declaration
         */
        function isNonLocalAlias(symbol, excludes) {
            if (excludes === void 0) { excludes = 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */; }
            if (!symbol)
                return false;
            return (symbol.flags & (2097152 /* Alias */ | excludes)) === 2097152 /* Alias */ || !!(symbol.flags & 2097152 /* Alias */ && symbol.flags & 67108864 /* Assignment */);
        }
        function resolveSymbol(symbol, dontResolveAlias) {
            return !dontResolveAlias && isNonLocalAlias(symbol) ? resolveAlias(symbol) : symbol;
        }
        function resolveAlias(symbol) {
            ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
            var links = getSymbolLinks(symbol);
            if (!links.target) {
                links.target = resolvingSymbol;
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                var target = getTargetOfAliasDeclaration(node);
                if (links.target === resolvingSymbol) {
                    links.target = target || unknownSymbol;
                }
                else {
                    error(node, ts.Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol));
                }
            }
            else if (links.target === resolvingSymbol) {
                links.target = unknownSymbol;
            }
            return links.target;
        }
        function tryResolveAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.target !== resolvingSymbol) {
                return resolveAlias(symbol);
            }
            return undefined;
        }
        /**
         * Marks a symbol as type-only if its declaration is syntactically type-only.
         * If it is not itself marked type-only, but resolves to a type-only alias
         * somewhere in its resolution chain, save a reference to the type-only alias declaration
         * so the alias _not_ marked type-only can be identified as _transitively_ type-only.
         *
         * This function is called on each alias declaration that could be type-only or resolve to
         * another type-only alias during `resolveAlias`, so that later, when an alias is used in a
         * JS-emitting expression, we can quickly determine if that symbol is effectively type-only
         * and issue an error if so.
         *
         * @param aliasDeclaration The alias declaration not marked as type-only
         * has already been marked as not resolving to a type-only alias. Used when recursively resolving qualified
         * names of import aliases, e.g. `import C = a.b.C`. If namespace `a` is not found to be type-only, the
         * import declaration will initially be marked as not resolving to a type-only symbol. But, namespace `b`
         * must still be checked for a type-only marker, overwriting the previous negative result if found.
         * @param immediateTarget The symbol to which the alias declaration immediately resolves
         * @param finalTarget The symbol to which the alias declaration ultimately resolves
         * @param overwriteEmpty Checks `resolvesToSymbol` for type-only declarations even if `aliasDeclaration`
         */
        function markSymbolOfAliasDeclarationIfTypeOnly(aliasDeclaration, immediateTarget, finalTarget, overwriteEmpty) {
            if (!aliasDeclaration)
                return false;
            // If the declaration itself is type-only, mark it and return.
            // No need to check what it resolves to.
            var sourceSymbol = getSymbolOfNode(aliasDeclaration);
            if (ts.isTypeOnlyImportOrExportDeclaration(aliasDeclaration)) {
                var links_1 = getSymbolLinks(sourceSymbol);
                links_1.typeOnlyDeclaration = aliasDeclaration;
                return true;
            }
            var links = getSymbolLinks(sourceSymbol);
            return markSymbolOfAliasDeclarationIfTypeOnlyWorker(links, immediateTarget, overwriteEmpty)
                || markSymbolOfAliasDeclarationIfTypeOnlyWorker(links, finalTarget, overwriteEmpty);
        }
        function markSymbolOfAliasDeclarationIfTypeOnlyWorker(aliasDeclarationLinks, target, overwriteEmpty) {
            var _a, _b, _c;
            if (target && (aliasDeclarationLinks.typeOnlyDeclaration === undefined || overwriteEmpty && aliasDeclarationLinks.typeOnlyDeclaration === false)) {
                var exportSymbol = (_b = (_a = target.exports) === null || _a === void 0 ? void 0 : _a.get("export=" /* ExportEquals */)) !== null && _b !== void 0 ? _b : target;
                var typeOnly = exportSymbol.declarations && ts.find(exportSymbol.declarations, ts.isTypeOnlyImportOrExportDeclaration);
                aliasDeclarationLinks.typeOnlyDeclaration = (_c = typeOnly !== null && typeOnly !== void 0 ? typeOnly : getSymbolLinks(exportSymbol).typeOnlyDeclaration) !== null && _c !== void 0 ? _c : false;
            }
            return !!aliasDeclarationLinks.typeOnlyDeclaration;
        }
        /** Indicates that a symbol directly or indirectly resolves to a type-only import or export. */
        function getTypeOnlyAliasDeclaration(symbol) {
            if (!(symbol.flags & 2097152 /* Alias */)) {
                return undefined;
            }
            var links = getSymbolLinks(symbol);
            return links.typeOnlyDeclaration || undefined;
        }
        function markExportAsReferenced(node) {
            var symbol = getSymbolOfNode(node);
            var target = resolveAlias(symbol);
            if (target) {
                var markAlias = target === unknownSymbol ||
                    ((target.flags & 111551 /* Value */) && !isConstEnumOrConstEnumOnlyModule(target) && !getTypeOnlyAliasDeclaration(symbol));
                if (markAlias) {
                    markAliasSymbolAsReferenced(symbol);
                }
            }
        }
        // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until
        // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of
        // the alias as an expression (which recursively takes us back here if the target references another alias).
        function markAliasSymbolAsReferenced(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.referenced) {
                links.referenced = true;
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                // We defer checking of the reference of an `import =` until the import itself is referenced,
                // This way a chain of imports can be elided if ultimately the final input is only used in a type
                // position.
                if (ts.isInternalModuleImportEqualsDeclaration(node)) {
                    var target = resolveSymbol(symbol);
                    if (target === unknownSymbol || target.flags & 111551 /* Value */) {
                        // import foo = <symbol>
                        checkExpressionCached(node.moduleReference);
                    }
                }
            }
        }
        // Aliases that resolve to const enums are not marked as referenced because they are not emitted,
        // but their usage in value positions must be tracked to determine if the import can be type-only.
        function markConstEnumAliasAsReferenced(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.constEnumReferenced) {
                links.constEnumReferenced = true;
            }
        }
        // This function is only for imports with entity names
        function getSymbolOfPartOfRightHandSideOfImportEquals(entityName, dontResolveAlias) {
            // There are three things we might try to look for. In the following examples,
            // the search term is enclosed in |...|:
            //
            //     import a = |b|; // Namespace
            //     import a = |b.c|; // Value, type, namespace
            //     import a = |b.c|.d; // Namespace
            if (entityName.kind === 75 /* Identifier */ && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) {
                entityName = entityName.parent;
            }
            // Check for case 1 and 3 in the above example
            if (entityName.kind === 75 /* Identifier */ || entityName.parent.kind === 153 /* QualifiedName */) {
                return resolveEntityName(entityName, 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
            }
            else {
                // Case 2 in above example
                // entityName.kind could be a QualifiedName or a Missing identifier
                ts.Debug.assert(entityName.parent.kind === 253 /* ImportEqualsDeclaration */);
                return resolveEntityName(entityName, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias);
            }
        }
        function getFullyQualifiedName(symbol, containingLocation) {
            return symbol.parent ? getFullyQualifiedName(symbol.parent, containingLocation) + "." + symbolToString(symbol) : symbolToString(symbol, containingLocation, /*meaning*/ undefined, 16 /* DoNotIncludeSymbolChain */ | 4 /* AllowAnyNodeKind */);
        }
        /**
         * Resolves a qualified name and any involved aliases.
         */
        function resolveEntityName(name, meaning, ignoreErrors, dontResolveAlias, location) {
            if (ts.nodeIsMissing(name)) {
                return undefined;
            }
            var namespaceMeaning = 1920 /* Namespace */ | (ts.isInJSFile(name) ? meaning & 111551 /* Value */ : 0);
            var symbol;
            if (name.kind === 75 /* Identifier */) {
                var message = meaning === namespaceMeaning || ts.nodeIsSynthesized(name) ? ts.Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(ts.getFirstIdentifier(name));
                var symbolFromJSPrototype = ts.isInJSFile(name) && !ts.nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined;
                symbol = getMergedSymbol(resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true));
                if (!symbol) {
                    return getMergedSymbol(symbolFromJSPrototype);
                }
            }
            else if (name.kind === 153 /* QualifiedName */ || name.kind === 194 /* PropertyAccessExpression */) {
                var left = name.kind === 153 /* QualifiedName */ ? name.left : name.expression;
                var right = name.kind === 153 /* QualifiedName */ ? name.right : name.name;
                var namespace = resolveEntityName(left, namespaceMeaning, ignoreErrors, /*dontResolveAlias*/ false, location);
                if (!namespace || ts.nodeIsMissing(right)) {
                    return undefined;
                }
                else if (namespace === unknownSymbol) {
                    return namespace;
                }
                if (ts.isInJSFile(name)) {
                    if (namespace.valueDeclaration &&
                        ts.isVariableDeclaration(namespace.valueDeclaration) &&
                        namespace.valueDeclaration.initializer &&
                        isCommonJsRequire(namespace.valueDeclaration.initializer)) {
                        var moduleName = namespace.valueDeclaration.initializer.arguments[0];
                        var moduleSym = resolveExternalModuleName(moduleName, moduleName);
                        if (moduleSym) {
                            var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
                            if (resolvedModuleSymbol) {
                                namespace = resolvedModuleSymbol;
                            }
                        }
                    }
                }
                symbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning));
                if (!symbol) {
                    if (!ignoreErrors) {
                        error(right, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(right));
                    }
                    return undefined;
                }
            }
            else {
                throw ts.Debug.assertNever(name, "Unknown entity name kind.");
            }
            ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here.");
            if (!ts.nodeIsSynthesized(name) && ts.isEntityName(name) && (symbol.flags & 2097152 /* Alias */ || name.parent.kind === 259 /* ExportAssignment */)) {
                markSymbolOfAliasDeclarationIfTypeOnly(ts.getAliasDeclarationFromName(name), symbol, /*finalTarget*/ undefined, /*overwriteEmpty*/ true);
            }
            return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol);
        }
        /**
         * 1. For prototype-property methods like `A.prototype.m = function () ...`, try to resolve names in the scope of `A` too.
         * Note that prototype-property assignment to locations outside the current file (eg globals) doesn't work, so
         * name resolution won't work either.
         * 2. For property assignments like `{ x: function f () { } }`, try to resolve names in the scope of `f` too.
         */
        function resolveEntityNameFromAssignmentDeclaration(name, meaning) {
            if (isJSDocTypeReference(name.parent)) {
                var secondaryLocation = getAssignmentDeclarationLocation(name.parent);
                if (secondaryLocation) {
                    return resolveName(secondaryLocation, name.escapedText, meaning, /*nameNotFoundMessage*/ undefined, name, /*isUse*/ true);
                }
            }
        }
        function getAssignmentDeclarationLocation(node) {
            var typeAlias = ts.findAncestor(node, function (node) { return !(ts.isJSDocNode(node) || node.flags & 4194304 /* JSDoc */) ? "quit" : ts.isJSDocTypeAlias(node); });
            if (typeAlias) {
                return;
            }
            var host = ts.getJSDocHost(node);
            if (ts.isExpressionStatement(host) &&
                ts.isBinaryExpression(host.expression) &&
                ts.getAssignmentDeclarationKind(host.expression) === 3 /* PrototypeProperty */) {
                // X.prototype.m = /** @param {K} p */ function () { } <-- look for K on X's declaration
                var symbol = getSymbolOfNode(host.expression.left);
                if (symbol) {
                    return getDeclarationOfJSPrototypeContainer(symbol);
                }
            }
            if ((ts.isObjectLiteralMethod(host) || ts.isPropertyAssignment(host)) &&
                ts.isBinaryExpression(host.parent.parent) &&
                ts.getAssignmentDeclarationKind(host.parent.parent) === 6 /* Prototype */) {
                // X.prototype = { /** @param {K} p */m() { } } <-- look for K on X's declaration
                var symbol = getSymbolOfNode(host.parent.parent.left);
                if (symbol) {
                    return getDeclarationOfJSPrototypeContainer(symbol);
                }
            }
            var sig = ts.getEffectiveJSDocHost(node);
            if (sig && ts.isFunctionLike(sig)) {
                var symbol = getSymbolOfNode(sig);
                return symbol && symbol.valueDeclaration;
            }
        }
        function getDeclarationOfJSPrototypeContainer(symbol) {
            var decl = symbol.parent.valueDeclaration;
            if (!decl) {
                return undefined;
            }
            var initializer = ts.isAssignmentDeclaration(decl) ? ts.getAssignedExpandoInitializer(decl) :
                ts.hasOnlyExpressionInitializer(decl) ? ts.getDeclaredExpandoInitializer(decl) :
                    undefined;
            return initializer || decl;
        }
        /**
         * Get the real symbol of a declaration with an expando initializer.
         *
         * Normally, declarations have an associated symbol, but when a declaration has an expando
         * initializer, the expando's symbol is the one that has all the members merged into it.
         */
        function getExpandoSymbol(symbol) {
            var decl = symbol.valueDeclaration;
            if (!decl || !ts.isInJSFile(decl) || symbol.flags & 524288 /* TypeAlias */ || ts.getExpandoInitializer(decl, /*isPrototypeAssignment*/ false)) {
                return undefined;
            }
            var init = ts.isVariableDeclaration(decl) ? ts.getDeclaredExpandoInitializer(decl) : ts.getAssignedExpandoInitializer(decl);
            if (init) {
                var initSymbol = getSymbolOfNode(init);
                if (initSymbol) {
                    return mergeJSSymbols(initSymbol, symbol);
                }
            }
        }
        function resolveExternalModuleName(location, moduleReferenceExpression, ignoreErrors) {
            return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ignoreErrors ? undefined : ts.Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations);
        }
        function resolveExternalModuleNameWorker(location, moduleReferenceExpression, moduleNotFoundError, isForAugmentation) {
            if (isForAugmentation === void 0) { isForAugmentation = false; }
            return ts.isStringLiteralLike(moduleReferenceExpression)
                ? resolveExternalModule(location, moduleReferenceExpression.text, moduleNotFoundError, moduleReferenceExpression, isForAugmentation)
                : undefined;
        }
        function resolveExternalModule(location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation) {
            if (isForAugmentation === void 0) { isForAugmentation = false; }
            if (ts.startsWith(moduleReference, "@types/")) {
                var diag = ts.Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1;
                var withoutAtTypePrefix = ts.removePrefix(moduleReference, "@types/");
                error(errorNode, diag, withoutAtTypePrefix, moduleReference);
            }
            var ambientModule = tryFindAmbientModule(moduleReference, /*withAugmentations*/ true);
            if (ambientModule) {
                return ambientModule;
            }
            var currentSourceFile = ts.getSourceFileOfNode(location);
            var resolvedModule = ts.getResolvedModule(currentSourceFile, moduleReference); // TODO: GH#18217
            var resolutionDiagnostic = resolvedModule && ts.getResolutionDiagnostic(compilerOptions, resolvedModule);
            var sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName);
            if (sourceFile) {
                if (sourceFile.symbol) {
                    if (resolvedModule.isExternalLibraryImport && !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension)) {
                        errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference);
                    }
                    // merged symbol is module declaration symbol combined with all augmentations
                    return getMergedSymbol(sourceFile.symbol);
                }
                if (moduleNotFoundError) {
                    // report errors only if it was requested
                    error(errorNode, ts.Diagnostics.File_0_is_not_a_module, sourceFile.fileName);
                }
                return undefined;
            }
            if (patternAmbientModules) {
                var pattern = ts.findBestPatternMatch(patternAmbientModules, function (_) { return _.pattern; }, moduleReference);
                if (pattern) {
                    // If the module reference matched a pattern ambient module ('*.foo') but there's also a
                    // module augmentation by the specific name requested ('a.foo'), we store the merged symbol
                    // by the augmentation name ('a.foo'), because asking for *.foo should not give you exports
                    // from a.foo.
                    var augmentation = patternAmbientModuleAugmentations && patternAmbientModuleAugmentations.get(moduleReference);
                    if (augmentation) {
                        return getMergedSymbol(augmentation);
                    }
                    return getMergedSymbol(pattern.symbol);
                }
            }
            // May be an untyped module. If so, ignore resolutionDiagnostic.
            if (resolvedModule && !ts.resolutionExtensionIsTSOrJson(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) {
                if (isForAugmentation) {
                    var diag = ts.Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented;
                    error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName);
                }
                else {
                    errorOnImplicitAnyModule(/*isError*/ noImplicitAny && !!moduleNotFoundError, errorNode, resolvedModule, moduleReference);
                }
                // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first.
                return undefined;
            }
            if (moduleNotFoundError) {
                // See if this was possibly a projectReference redirect
                if (resolvedModule) {
                    var redirect = host.getProjectReferenceRedirect(resolvedModule.resolvedFileName);
                    if (redirect) {
                        error(errorNode, ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, resolvedModule.resolvedFileName);
                        return undefined;
                    }
                }
                if (resolutionDiagnostic) {
                    error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
                }
                else {
                    var tsExtension = ts.tryExtractTSExtension(moduleReference);
                    if (tsExtension) {
                        var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
                        error(errorNode, diag, tsExtension, ts.removeExtension(moduleReference, tsExtension));
                    }
                    else if (!compilerOptions.resolveJsonModule &&
                        ts.fileExtensionIs(moduleReference, ".json" /* Json */) &&
                        ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs &&
                        ts.hasJsonModuleEmitEnabled(compilerOptions)) {
                        error(errorNode, ts.Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference);
                    }
                    else {
                        error(errorNode, moduleNotFoundError, moduleReference);
                    }
                }
            }
            return undefined;
        }
        function errorOnImplicitAnyModule(isError, errorNode, _a, moduleReference) {
            var packageId = _a.packageId, resolvedFileName = _a.resolvedFileName;
            var errorInfo = !ts.isExternalModuleNameRelative(moduleReference) && packageId
                ? typesPackageExists(packageId.name)
                    ? ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_1, packageId.name, ts.mangleScopedPackageName(packageId.name))
                    : ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.Try_npm_install_types_Slash_1_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, moduleReference, ts.mangleScopedPackageName(packageId.name))
                : undefined;
            errorOrSuggestion(isError, errorNode, ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedFileName));
        }
        function typesPackageExists(packageName) {
            return getPackagesSet().has(ts.getTypesPackageName(packageName));
        }
        function resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) {
            if (moduleSymbol === null || moduleSymbol === void 0 ? void 0 : moduleSymbol.exports) {
                var exportEquals = resolveSymbol(moduleSymbol.exports.get("export=" /* ExportEquals */), dontResolveAlias);
                var exported = getCommonJsExportEquals(getMergedSymbol(exportEquals), getMergedSymbol(moduleSymbol));
                return getMergedSymbol(exported) || moduleSymbol;
            }
            return undefined;
        }
        function getCommonJsExportEquals(exported, moduleSymbol) {
            if (!exported || exported === unknownSymbol || exported === moduleSymbol || moduleSymbol.exports.size === 1 || exported.flags & 2097152 /* Alias */) {
                return exported;
            }
            var links = getSymbolLinks(exported);
            if (links.cjsExportMerged) {
                return links.cjsExportMerged;
            }
            var merged = exported.flags & 33554432 /* Transient */ ? exported : cloneSymbol(exported);
            merged.flags = merged.flags | 512 /* ValueModule */;
            if (merged.exports === undefined) {
                merged.exports = ts.createSymbolTable();
            }
            moduleSymbol.exports.forEach(function (s, name) {
                if (name === "export=" /* ExportEquals */)
                    return;
                merged.exports.set(name, merged.exports.has(name) ? mergeSymbol(merged.exports.get(name), s) : s);
            });
            getSymbolLinks(merged).cjsExportMerged = merged;
            return links.cjsExportMerged = merged;
        }
        // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export ='
        // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may
        // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable).
        function resolveESModuleSymbol(moduleSymbol, referencingLocation, dontResolveAlias, suppressInteropError) {
            var symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias);
            if (!dontResolveAlias && symbol) {
                if (!suppressInteropError && !(symbol.flags & (1536 /* Module */ | 3 /* Variable */)) && !ts.getDeclarationOfKind(symbol, 290 /* SourceFile */)) {
                    var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015
                        ? "allowSyntheticDefaultImports"
                        : "esModuleInterop";
                    error(referencingLocation, ts.Diagnostics.This_module_can_only_be_referenced_with_ECMAScript_imports_Slashexports_by_turning_on_the_0_flag_and_referencing_its_default_export, compilerOptionName);
                    return symbol;
                }
                if (compilerOptions.esModuleInterop) {
                    var referenceParent = referencingLocation.parent;
                    if ((ts.isImportDeclaration(referenceParent) && ts.getNamespaceDeclarationNode(referenceParent)) ||
                        ts.isImportCall(referenceParent)) {
                        var type = getTypeOfSymbol(symbol);
                        var sigs = getSignaturesOfStructuredType(type, 0 /* Call */);
                        if (!sigs || !sigs.length) {
                            sigs = getSignaturesOfStructuredType(type, 1 /* Construct */);
                        }
                        if (sigs && sigs.length) {
                            var moduleType = getTypeWithSyntheticDefaultImportType(type, symbol, moduleSymbol);
                            // Create a new symbol which has the module's type less the call and construct signatures
                            var result = createSymbol(symbol.flags, symbol.escapedName);
                            result.declarations = symbol.declarations ? symbol.declarations.slice() : [];
                            result.parent = symbol.parent;
                            result.target = symbol;
                            result.originatingImport = referenceParent;
                            if (symbol.valueDeclaration)
                                result.valueDeclaration = symbol.valueDeclaration;
                            if (symbol.constEnumOnlyModule)
                                result.constEnumOnlyModule = true;
                            if (symbol.members)
                                result.members = ts.cloneMap(symbol.members);
                            if (symbol.exports)
                                result.exports = ts.cloneMap(symbol.exports);
                            var resolvedModuleType = resolveStructuredTypeMembers(moduleType); // Should already be resolved from the signature checks above
                            result.type = createAnonymousType(result, resolvedModuleType.members, ts.emptyArray, ts.emptyArray, resolvedModuleType.stringIndexInfo, resolvedModuleType.numberIndexInfo);
                            return result;
                        }
                    }
                }
            }
            return symbol;
        }
        function hasExportAssignmentSymbol(moduleSymbol) {
            return moduleSymbol.exports.get("export=" /* ExportEquals */) !== undefined;
        }
        function getExportsOfModuleAsArray(moduleSymbol) {
            return symbolsToArray(getExportsOfModule(moduleSymbol));
        }
        function getExportsAndPropertiesOfModule(moduleSymbol) {
            var exports = getExportsOfModuleAsArray(moduleSymbol);
            var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
            if (exportEquals !== moduleSymbol) {
                ts.addRange(exports, getPropertiesOfType(getTypeOfSymbol(exportEquals)));
            }
            return exports;
        }
        function tryGetMemberInModuleExports(memberName, moduleSymbol) {
            var symbolTable = getExportsOfModule(moduleSymbol);
            if (symbolTable) {
                return symbolTable.get(memberName);
            }
        }
        function tryGetMemberInModuleExportsAndProperties(memberName, moduleSymbol) {
            var symbol = tryGetMemberInModuleExports(memberName, moduleSymbol);
            if (symbol) {
                return symbol;
            }
            var exportEquals = resolveExternalModuleSymbol(moduleSymbol);
            if (exportEquals === moduleSymbol) {
                return undefined;
            }
            var type = getTypeOfSymbol(exportEquals);
            return type.flags & 131068 /* Primitive */ ||
                ts.getObjectFlags(type) & 1 /* Class */ ||
                isArrayOrTupleLikeType(type)
                ? undefined
                : getPropertyOfType(type, memberName);
        }
        function getExportsOfSymbol(symbol) {
            return symbol.flags & 6256 /* LateBindingContainer */ ? getResolvedMembersOrExportsOfSymbol(symbol, "resolvedExports" /* resolvedExports */) :
                symbol.flags & 1536 /* Module */ ? getExportsOfModule(symbol) :
                    symbol.exports || emptySymbols;
        }
        function getExportsOfModule(moduleSymbol) {
            var links = getSymbolLinks(moduleSymbol);
            return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol));
        }
        /**
         * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument
         * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables
         */
        function extendExportSymbols(target, source, lookupTable, exportNode) {
            if (!source)
                return;
            source.forEach(function (sourceSymbol, id) {
                if (id === "default" /* Default */)
                    return;
                var targetSymbol = target.get(id);
                if (!targetSymbol) {
                    target.set(id, sourceSymbol);
                    if (lookupTable && exportNode) {
                        lookupTable.set(id, {
                            specifierText: ts.getTextOfNode(exportNode.moduleSpecifier)
                        });
                    }
                }
                else if (lookupTable && exportNode && targetSymbol && resolveSymbol(targetSymbol) !== resolveSymbol(sourceSymbol)) {
                    var collisionTracker = lookupTable.get(id);
                    if (!collisionTracker.exportsWithDuplicate) {
                        collisionTracker.exportsWithDuplicate = [exportNode];
                    }
                    else {
                        collisionTracker.exportsWithDuplicate.push(exportNode);
                    }
                }
            });
        }
        function getExportsOfModuleWorker(moduleSymbol) {
            var visitedSymbols = [];
            // A module defined by an 'export=' consists of one export that needs to be resolved
            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
            return visit(moduleSymbol) || emptySymbols;
            // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example,
            // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error.
            function visit(symbol) {
                if (!(symbol && symbol.exports && ts.pushIfUnique(visitedSymbols, symbol))) {
                    return;
                }
                var symbols = ts.cloneMap(symbol.exports);
                // All export * declarations are collected in an __export symbol by the binder
                var exportStars = symbol.exports.get("__export" /* ExportStar */);
                if (exportStars) {
                    var nestedSymbols = ts.createSymbolTable();
                    var lookupTable_1 = ts.createMap();
                    for (var _i = 0, _a = exportStars.declarations; _i < _a.length; _i++) {
                        var node = _a[_i];
                        var resolvedModule = resolveExternalModuleName(node, node.moduleSpecifier);
                        var exportedSymbols = visit(resolvedModule);
                        extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable_1, node);
                    }
                    lookupTable_1.forEach(function (_a, id) {
                        var exportsWithDuplicate = _a.exportsWithDuplicate;
                        // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself
                        if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols.has(id)) {
                            return;
                        }
                        for (var _i = 0, exportsWithDuplicate_1 = exportsWithDuplicate; _i < exportsWithDuplicate_1.length; _i++) {
                            var node = exportsWithDuplicate_1[_i];
                            diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable_1.get(id).specifierText, ts.unescapeLeadingUnderscores(id)));
                        }
                    });
                    extendExportSymbols(symbols, nestedSymbols);
                }
                return symbols;
            }
        }
        function getMergedSymbol(symbol) {
            var merged;
            return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol;
        }
        function getSymbolOfNode(node) {
            return getMergedSymbol(node.symbol && getLateBoundSymbol(node.symbol));
        }
        function getParentOfSymbol(symbol) {
            return getMergedSymbol(symbol.parent && getLateBoundSymbol(symbol.parent));
        }
        function getAlternativeContainingModules(symbol, enclosingDeclaration) {
            var containingFile = ts.getSourceFileOfNode(enclosingDeclaration);
            var id = "" + getNodeId(containingFile);
            var links = getSymbolLinks(symbol);
            var results;
            if (links.extendedContainersByFile && (results = links.extendedContainersByFile.get(id))) {
                return results;
            }
            if (containingFile && containingFile.imports) {
                // Try to make an import using an import already in the enclosing file, if possible
                for (var _i = 0, _a = containingFile.imports; _i < _a.length; _i++) {
                    var importRef = _a[_i];
                    if (ts.nodeIsSynthesized(importRef))
                        continue; // Synthetic names can't be resolved by `resolveExternalModuleName` - they'll cause a debug assert if they error
                    var resolvedModule = resolveExternalModuleName(enclosingDeclaration, importRef, /*ignoreErrors*/ true);
                    if (!resolvedModule)
                        continue;
                    var ref = getAliasForSymbolInContainer(resolvedModule, symbol);
                    if (!ref)
                        continue;
                    results = ts.append(results, resolvedModule);
                }
                if (ts.length(results)) {
                    (links.extendedContainersByFile || (links.extendedContainersByFile = ts.createMap())).set(id, results);
                    return results;
                }
            }
            if (links.extendedContainers) {
                return links.extendedContainers;
            }
            // No results from files already being imported by this file - expand search (expensive, but not location-specific, so cached)
            var otherFiles = host.getSourceFiles();
            for (var _b = 0, otherFiles_1 = otherFiles; _b < otherFiles_1.length; _b++) {
                var file = otherFiles_1[_b];
                if (!ts.isExternalModule(file))
                    continue;
                var sym = getSymbolOfNode(file);
                var ref = getAliasForSymbolInContainer(sym, symbol);
                if (!ref)
                    continue;
                results = ts.append(results, sym);
            }
            return links.extendedContainers = results || ts.emptyArray;
        }
        /**
         * Attempts to find the symbol corresponding to the container a symbol is in - usually this
         * is just its' `.parent`, but for locals, this value is `undefined`
         */
        function getContainersOfSymbol(symbol, enclosingDeclaration) {
            var container = getParentOfSymbol(symbol);
            // Type parameters end up in the `members` lists but are not externally visible
            if (container && !(symbol.flags & 262144 /* TypeParameter */)) {
                var additionalContainers = ts.mapDefined(container.declarations, fileSymbolIfFileSymbolExportEqualsContainer);
                var reexportContainers = enclosingDeclaration && getAlternativeContainingModules(symbol, enclosingDeclaration);
                if (enclosingDeclaration && getAccessibleSymbolChain(container, enclosingDeclaration, 1920 /* Namespace */, /*externalOnly*/ false)) {
                    return ts.concatenate(ts.concatenate([container], additionalContainers), reexportContainers); // This order expresses a preference for the real container if it is in scope
                }
                var res = ts.append(additionalContainers, container);
                return ts.concatenate(res, reexportContainers);
            }
            var candidates = ts.mapDefined(symbol.declarations, function (d) {
                if (!ts.isAmbientModule(d) && d.parent && hasNonGlobalAugmentationExternalModuleSymbol(d.parent)) {
                    return getSymbolOfNode(d.parent);
                }
                if (ts.isClassExpression(d) && ts.isBinaryExpression(d.parent) && d.parent.operatorToken.kind === 62 /* EqualsToken */ && ts.isAccessExpression(d.parent.left) && ts.isEntityNameExpression(d.parent.left.expression)) {
                    if (ts.isModuleExportsAccessExpression(d.parent.left) || ts.isExportsIdentifier(d.parent.left.expression)) {
                        return getSymbolOfNode(ts.getSourceFileOfNode(d));
                    }
                    checkExpressionCached(d.parent.left.expression);
                    return getNodeLinks(d.parent.left.expression).resolvedSymbol;
                }
            });
            if (!ts.length(candidates)) {
                return undefined;
            }
            return ts.mapDefined(candidates, function (candidate) { return getAliasForSymbolInContainer(candidate, symbol) ? candidate : undefined; });
            function fileSymbolIfFileSymbolExportEqualsContainer(d) {
                return container && getFileSymbolIfFileSymbolExportEqualsContainer(d, container);
            }
        }
        function getFileSymbolIfFileSymbolExportEqualsContainer(d, container) {
            var fileSymbol = getExternalModuleContainer(d);
            var exported = fileSymbol && fileSymbol.exports && fileSymbol.exports.get("export=" /* ExportEquals */);
            return exported && getSymbolIfSameReference(exported, container) ? fileSymbol : undefined;
        }
        function getAliasForSymbolInContainer(container, symbol) {
            if (container === getParentOfSymbol(symbol)) {
                // fast path, `symbol` is either already the alias or isn't aliased
                return symbol;
            }
            // Check if container is a thing with an `export=` which points directly at `symbol`, and if so, return
            // the container itself as the alias for the symbol
            var exportEquals = container.exports && container.exports.get("export=" /* ExportEquals */);
            if (exportEquals && getSymbolIfSameReference(exportEquals, symbol)) {
                return container;
            }
            var exports = getExportsOfSymbol(container);
            var quick = exports.get(symbol.escapedName);
            if (quick && getSymbolIfSameReference(quick, symbol)) {
                return quick;
            }
            return ts.forEachEntry(exports, function (exported) {
                if (getSymbolIfSameReference(exported, symbol)) {
                    return exported;
                }
            });
        }
        /**
         * Checks if two symbols, through aliasing and/or merging, refer to the same thing
         */
        function getSymbolIfSameReference(s1, s2) {
            if (getMergedSymbol(resolveSymbol(getMergedSymbol(s1))) === getMergedSymbol(resolveSymbol(getMergedSymbol(s2)))) {
                return s1;
            }
        }
        function getExportSymbolOfValueSymbolIfExported(symbol) {
            return getMergedSymbol(symbol && (symbol.flags & 1048576 /* ExportValue */) !== 0 ? symbol.exportSymbol : symbol);
        }
        function symbolIsValue(symbol) {
            return !!(symbol.flags & 111551 /* Value */ || symbol.flags & 2097152 /* Alias */ && resolveAlias(symbol).flags & 111551 /* Value */ && !getTypeOnlyAliasDeclaration(symbol));
        }
        function findConstructorDeclaration(node) {
            var members = node.members;
            for (var _i = 0, members_3 = members; _i < members_3.length; _i++) {
                var member = members_3[_i];
                if (member.kind === 162 /* Constructor */ && ts.nodeIsPresent(member.body)) {
                    return member;
                }
            }
        }
        function createType(flags) {
            var result = new Type(checker, flags);
            typeCount++;
            result.id = typeCount;
            return result;
        }
        function createIntrinsicType(kind, intrinsicName, objectFlags) {
            if (objectFlags === void 0) { objectFlags = 0; }
            var type = createType(kind);
            type.intrinsicName = intrinsicName;
            type.objectFlags = objectFlags;
            return type;
        }
        function createBooleanType(trueFalseTypes) {
            var type = getUnionType(trueFalseTypes);
            type.flags |= 16 /* Boolean */;
            type.intrinsicName = "boolean";
            return type;
        }
        function createObjectType(objectFlags, symbol) {
            var type = createType(524288 /* Object */);
            type.objectFlags = objectFlags;
            type.symbol = symbol;
            type.members = undefined;
            type.properties = undefined;
            type.callSignatures = undefined;
            type.constructSignatures = undefined;
            type.stringIndexInfo = undefined;
            type.numberIndexInfo = undefined;
            return type;
        }
        function createTypeofType() {
            return getUnionType(ts.arrayFrom(typeofEQFacts.keys(), getLiteralType));
        }
        function createTypeParameter(symbol) {
            var type = createType(262144 /* TypeParameter */);
            if (symbol)
                type.symbol = symbol;
            return type;
        }
        // A reserved member name starts with two underscores, but the third character cannot be an underscore,
        // @, or #. A third underscore indicates an escaped form of an identifier that started
        // with at least two underscores. The @ character indicates that the name is denoted by a well known ES
        // Symbol instance and the # character indicates that the name is a PrivateIdentifier.
        function isReservedMemberName(name) {
            return name.charCodeAt(0) === 95 /* _ */ &&
                name.charCodeAt(1) === 95 /* _ */ &&
                name.charCodeAt(2) !== 95 /* _ */ &&
                name.charCodeAt(2) !== 64 /* at */ &&
                name.charCodeAt(2) !== 35 /* hash */;
        }
        function getNamedMembers(members) {
            var result;
            members.forEach(function (symbol, id) {
                if (!isReservedMemberName(id) && symbolIsValue(symbol)) {
                    (result || (result = [])).push(symbol);
                }
            });
            return result || ts.emptyArray;
        }
        function setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
            type.members = members;
            type.properties = members === emptySymbols ? ts.emptyArray : getNamedMembers(members);
            type.callSignatures = callSignatures;
            type.constructSignatures = constructSignatures;
            type.stringIndexInfo = stringIndexInfo;
            type.numberIndexInfo = numberIndexInfo;
            return type;
        }
        function createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) {
            return setStructuredTypeMembers(createObjectType(16 /* Anonymous */, symbol), members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function forEachSymbolTableInScope(enclosingDeclaration, callback) {
            var result;
            var _loop_7 = function (location) {
                // Locals of a source file are not in scope (because they get merged into the global symbol table)
                if (location.locals && !isGlobalSourceFile(location)) {
                    if (result = callback(location.locals)) {
                        return { value: result };
                    }
                }
                switch (location.kind) {
                    case 290 /* SourceFile */:
                        if (!ts.isExternalOrCommonJsModule(location)) {
                            break;
                        }
                    // falls through
                    case 249 /* ModuleDeclaration */:
                        var sym = getSymbolOfNode(location);
                        // `sym` may not have exports if this module declaration is backed by the symbol for a `const` that's being rewritten
                        // into a namespace - in such cases, it's best to just let the namespace appear empty (the const members couldn't have referred
                        // to one another anyway)
                        if (result = callback((sym === null || sym === void 0 ? void 0 : sym.exports) || emptySymbols)) {
                            return { value: result };
                        }
                        break;
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                        // Type parameters are bound into `members` lists so they can merge across declarations
                        // This is troublesome, since in all other respects, they behave like locals :cries:
                        // TODO: the below is shared with similar code in `resolveName` - in fact, rephrasing all this symbol
                        // lookup logic in terms of `resolveName` would be nice
                        // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals
                        // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would
                        // trigger resolving late-bound names, which we may already be in the process of doing while we're here!
                        var table_1;
                        // TODO: Should this filtered table be cached in some way?
                        (getSymbolOfNode(location).members || emptySymbols).forEach(function (memberSymbol, key) {
                            if (memberSymbol.flags & (788968 /* Type */ & ~67108864 /* Assignment */)) {
                                (table_1 || (table_1 = ts.createSymbolTable())).set(key, memberSymbol);
                            }
                        });
                        if (table_1 && (result = callback(table_1))) {
                            return { value: result };
                        }
                        break;
                }
            };
            for (var location = enclosingDeclaration; location; location = location.parent) {
                var state_2 = _loop_7(location);
                if (typeof state_2 === "object")
                    return state_2.value;
            }
            return callback(globals);
        }
        function getQualifiedLeftMeaning(rightMeaning) {
            // If we are looking in value space, the parent meaning is value, other wise it is namespace
            return rightMeaning === 111551 /* Value */ ? 111551 /* Value */ : 1920 /* Namespace */;
        }
        function getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing, visitedSymbolTablesMap) {
            if (visitedSymbolTablesMap === void 0) { visitedSymbolTablesMap = ts.createMap(); }
            if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) {
                return undefined;
            }
            var id = "" + getSymbolId(symbol);
            var visitedSymbolTables = visitedSymbolTablesMap.get(id);
            if (!visitedSymbolTables) {
                visitedSymbolTablesMap.set(id, visitedSymbolTables = []);
            }
            return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
            /**
             * @param {ignoreQualification} boolean Set when a symbol is being looked for through the exports of another symbol (meaning we have a route to qualify it already)
             */
            function getAccessibleSymbolChainFromSymbolTable(symbols, ignoreQualification) {
                if (!ts.pushIfUnique(visitedSymbolTables, symbols)) {
                    return undefined;
                }
                var result = trySymbolTable(symbols, ignoreQualification);
                visitedSymbolTables.pop();
                return result;
            }
            function canQualifySymbol(symbolFromSymbolTable, meaning) {
                // If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
                return !needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning) ||
                    // If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too
                    !!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing, visitedSymbolTablesMap);
            }
            function isAccessible(symbolFromSymbolTable, resolvedAliasSymbol, ignoreQualification) {
                return (symbol === (resolvedAliasSymbol || symbolFromSymbolTable) || getMergedSymbol(symbol) === getMergedSymbol(resolvedAliasSymbol || symbolFromSymbolTable)) &&
                    // if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
                    // and if symbolFromSymbolTable or alias resolution matches the symbol,
                    // check the symbol can be qualified, it is only then this symbol is accessible
                    !ts.some(symbolFromSymbolTable.declarations, hasNonGlobalAugmentationExternalModuleSymbol) &&
                    (ignoreQualification || canQualifySymbol(getMergedSymbol(symbolFromSymbolTable), meaning));
            }
            function trySymbolTable(symbols, ignoreQualification) {
                // If symbol is directly available by its name in the symbol table
                if (isAccessible(symbols.get(symbol.escapedName), /*resolvedAliasSymbol*/ undefined, ignoreQualification)) {
                    return [symbol];
                }
                // Check if symbol is any of the aliases in scope
                var result = ts.forEachEntry(symbols, function (symbolFromSymbolTable) {
                    if (symbolFromSymbolTable.flags & 2097152 /* Alias */
                        && symbolFromSymbolTable.escapedName !== "export=" /* ExportEquals */
                        && symbolFromSymbolTable.escapedName !== "default" /* Default */
                        && !(ts.isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && ts.isExternalModule(ts.getSourceFileOfNode(enclosingDeclaration)))
                        // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
                        && (!useOnlyExternalAliasing || ts.some(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration))
                        // While exports are generally considered to be in scope, export-specifier declared symbols are _not_
                        // See similar comment in `resolveName` for details
                        && (ignoreQualification || !ts.getDeclarationOfKind(symbolFromSymbolTable, 263 /* ExportSpecifier */))) {
                        var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
                        var candidate = getCandidateListForSymbol(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification);
                        if (candidate) {
                            return candidate;
                        }
                    }
                    if (symbolFromSymbolTable.escapedName === symbol.escapedName && symbolFromSymbolTable.exportSymbol) {
                        if (isAccessible(getMergedSymbol(symbolFromSymbolTable.exportSymbol), /*aliasSymbol*/ undefined, ignoreQualification)) {
                            return [symbol];
                        }
                    }
                });
                // If there's no result and we're looking at the global symbol table, treat `globalThis` like an alias and try to lookup thru that
                return result || (symbols === globals ? getCandidateListForSymbol(globalThisSymbol, globalThisSymbol, ignoreQualification) : undefined);
            }
            function getCandidateListForSymbol(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification) {
                if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol, ignoreQualification)) {
                    return [symbolFromSymbolTable];
                }
                // Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
                // but only if the symbolFromSymbolTable can be qualified
                var candidateTable = getExportsOfSymbol(resolvedImportedSymbol);
                var accessibleSymbolsFromExports = candidateTable && getAccessibleSymbolChainFromSymbolTable(candidateTable, /*ignoreQualification*/ true);
                if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
                    return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
                }
            }
        }
        function needsQualification(symbol, enclosingDeclaration, meaning) {
            var qualify = false;
            forEachSymbolTableInScope(enclosingDeclaration, function (symbolTable) {
                // If symbol of this name is not available in the symbol table we are ok
                var symbolFromSymbolTable = getMergedSymbol(symbolTable.get(symbol.escapedName));
                if (!symbolFromSymbolTable) {
                    // Continue to the next symbol table
                    return false;
                }
                // If the symbol with this name is present it should refer to the symbol
                if (symbolFromSymbolTable === symbol) {
                    // No need to qualify
                    return true;
                }
                // Qualify if the symbol from symbol table has same meaning as expected
                symbolFromSymbolTable = (symbolFromSymbolTable.flags & 2097152 /* Alias */ && !ts.getDeclarationOfKind(symbolFromSymbolTable, 263 /* ExportSpecifier */)) ? resolveAlias(symbolFromSymbolTable) : symbolFromSymbolTable;
                if (symbolFromSymbolTable.flags & meaning) {
                    qualify = true;
                    return true;
                }
                // Continue to the next symbol table
                return false;
            });
            return qualify;
        }
        function isPropertyOrMethodDeclarationSymbol(symbol) {
            if (symbol.declarations && symbol.declarations.length) {
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    switch (declaration.kind) {
                        case 159 /* PropertyDeclaration */:
                        case 161 /* MethodDeclaration */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                            continue;
                        default:
                            return false;
                    }
                }
                return true;
            }
            return false;
        }
        function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) {
            var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 788968 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false);
            return access.accessibility === 0 /* Accessible */;
        }
        function isValueSymbolAccessible(typeSymbol, enclosingDeclaration) {
            var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 111551 /* Value */, /*shouldComputeAliasesToMakeVisible*/ false);
            return access.accessibility === 0 /* Accessible */;
        }
        function isAnySymbolAccessible(symbols, enclosingDeclaration, initialSymbol, meaning, shouldComputeAliasesToMakeVisible) {
            if (!ts.length(symbols))
                return;
            var hadAccessibleChain;
            var earlyModuleBail = false;
            for (var _i = 0, _a = symbols; _i < _a.length; _i++) {
                var symbol = _a[_i];
                // Symbol is accessible if it by itself is accessible
                var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false);
                if (accessibleSymbolChain) {
                    hadAccessibleChain = symbol;
                    var hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible);
                    if (hasAccessibleDeclarations) {
                        return hasAccessibleDeclarations;
                    }
                }
                else {
                    if (ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                        if (shouldComputeAliasesToMakeVisible) {
                            earlyModuleBail = true;
                            // Generally speaking, we want to use the aliases that already exist to refer to a module, if present
                            // In order to do so, we need to find those aliases in order to retain them in declaration emit; so
                            // if we are in declaration emit, we cannot use the fast path for module visibility until we've exhausted
                            // all other visibility options (in order to capture the possible aliases used to reference the module)
                            continue;
                        }
                        // Any meaning of a module symbol is always accessible via an `import` type
                        return {
                            accessibility: 0 /* Accessible */
                        };
                    }
                }
                // If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible.
                // It could be a qualified symbol and hence verify the path
                // e.g.:
                // module m {
                //     export class c {
                //     }
                // }
                // const x: typeof m.c
                // In the above example when we start with checking if typeof m.c symbol is accessible,
                // we are going to see if c can be accessed in scope directly.
                // But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
                // It is accessible if the parent m is accessible because then m.c can be accessed through qualification
                var containers = getContainersOfSymbol(symbol, enclosingDeclaration);
                // If we're trying to reference some object literal in, eg `var a = { x: 1 }`, the symbol for the literal, `__object`, is distinct
                // from the symbol of the declaration it is being assigned to. Since we can use the declaration to refer to the literal, however,
                // we'd like to make that connection here - potentially causing us to paint the declaration's visibility, and therefore the literal.
                var firstDecl = !!ts.length(symbol.declarations) && ts.first(symbol.declarations);
                if (!ts.length(containers) && meaning & 111551 /* Value */ && firstDecl && ts.isObjectLiteralExpression(firstDecl)) {
                    if (firstDecl.parent && ts.isVariableDeclaration(firstDecl.parent) && firstDecl === firstDecl.parent.initializer) {
                        containers = [getSymbolOfNode(firstDecl.parent)];
                    }
                }
                var parentResult = isAnySymbolAccessible(containers, enclosingDeclaration, initialSymbol, initialSymbol === symbol ? getQualifiedLeftMeaning(meaning) : meaning, shouldComputeAliasesToMakeVisible);
                if (parentResult) {
                    return parentResult;
                }
            }
            if (earlyModuleBail) {
                return {
                    accessibility: 0 /* Accessible */
                };
            }
            if (hadAccessibleChain) {
                return {
                    accessibility: 1 /* NotAccessible */,
                    errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning),
                    errorModuleName: hadAccessibleChain !== initialSymbol ? symbolToString(hadAccessibleChain, enclosingDeclaration, 1920 /* Namespace */) : undefined,
                };
            }
        }
        /**
         * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested
         *
         * @param symbol a Symbol to check if accessible
         * @param enclosingDeclaration a Node containing reference to the symbol
         * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible
         * @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible
         */
        function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) {
            if (symbol && enclosingDeclaration) {
                var result = isAnySymbolAccessible([symbol], enclosingDeclaration, symbol, meaning, shouldComputeAliasesToMakeVisible);
                if (result) {
                    return result;
                }
                // This could be a symbol that is not exported in the external module
                // or it could be a symbol from different external module that is not aliased and hence cannot be named
                var symbolExternalModule = ts.forEach(symbol.declarations, getExternalModuleContainer);
                if (symbolExternalModule) {
                    var enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration);
                    if (symbolExternalModule !== enclosingExternalModule) {
                        // name from different external module that is not visible
                        return {
                            accessibility: 2 /* CannotBeNamed */,
                            errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning),
                            errorModuleName: symbolToString(symbolExternalModule)
                        };
                    }
                }
                // Just a local name that is not accessible
                return {
                    accessibility: 1 /* NotAccessible */,
                    errorSymbolName: symbolToString(symbol, enclosingDeclaration, meaning),
                };
            }
            return { accessibility: 0 /* Accessible */ };
        }
        function getExternalModuleContainer(declaration) {
            var node = ts.findAncestor(declaration, hasExternalModuleSymbol);
            return node && getSymbolOfNode(node);
        }
        function hasExternalModuleSymbol(declaration) {
            return ts.isAmbientModule(declaration) || (declaration.kind === 290 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
        }
        function hasNonGlobalAugmentationExternalModuleSymbol(declaration) {
            return ts.isModuleWithStringLiteralName(declaration) || (declaration.kind === 290 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration));
        }
        function hasVisibleDeclarations(symbol, shouldComputeAliasToMakeVisible) {
            var aliasesToMakeVisible;
            if (!ts.every(ts.filter(symbol.declarations, function (d) { return d.kind !== 75 /* Identifier */; }), getIsDeclarationVisible)) {
                return undefined;
            }
            return { accessibility: 0 /* Accessible */, aliasesToMakeVisible: aliasesToMakeVisible };
            function getIsDeclarationVisible(declaration) {
                if (!isDeclarationVisible(declaration)) {
                    // Mark the unexported alias as visible if its parent is visible
                    // because these kind of aliases can be used to name types in declaration file
                    var anyImportSyntax = getAnyImportSyntax(declaration);
                    if (anyImportSyntax &&
                        !ts.hasModifier(anyImportSyntax, 1 /* Export */) && // import clause without export
                        isDeclarationVisible(anyImportSyntax.parent)) {
                        return addVisibleAlias(declaration, anyImportSyntax);
                    }
                    else if (ts.isVariableDeclaration(declaration) && ts.isVariableStatement(declaration.parent.parent) &&
                        !ts.hasModifier(declaration.parent.parent, 1 /* Export */) && // unexported variable statement
                        isDeclarationVisible(declaration.parent.parent.parent)) {
                        return addVisibleAlias(declaration, declaration.parent.parent);
                    }
                    else if (ts.isLateVisibilityPaintedStatement(declaration) // unexported top-level statement
                        && !ts.hasModifier(declaration, 1 /* Export */)
                        && isDeclarationVisible(declaration.parent)) {
                        return addVisibleAlias(declaration, declaration);
                    }
                    // Declaration is not visible
                    return false;
                }
                return true;
            }
            function addVisibleAlias(declaration, aliasingStatement) {
                // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types,
                // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time
                // since we will do the emitting later in trackSymbol.
                if (shouldComputeAliasToMakeVisible) {
                    getNodeLinks(declaration).isVisible = true;
                    aliasesToMakeVisible = ts.appendIfUnique(aliasesToMakeVisible, aliasingStatement);
                }
                return true;
            }
        }
        function isEntityNameVisible(entityName, enclosingDeclaration) {
            // get symbol of the first identifier of the entityName
            var meaning;
            if (entityName.parent.kind === 172 /* TypeQuery */ ||
                ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent) ||
                entityName.parent.kind === 154 /* ComputedPropertyName */) {
                // Typeof value
                meaning = 111551 /* Value */ | 1048576 /* ExportValue */;
            }
            else if (entityName.kind === 153 /* QualifiedName */ || entityName.kind === 194 /* PropertyAccessExpression */ ||
                entityName.parent.kind === 253 /* ImportEqualsDeclaration */) {
                // Left identifier from type reference or TypeAlias
                // Entity name of the import declaration
                meaning = 1920 /* Namespace */;
            }
            else {
                // Type Reference or TypeAlias entity = Identifier
                meaning = 788968 /* Type */;
            }
            var firstIdentifier = ts.getFirstIdentifier(entityName);
            var symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
            // Verify if the symbol is accessible
            return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || {
                accessibility: 1 /* NotAccessible */,
                errorSymbolName: ts.getTextOfNode(firstIdentifier),
                errorNode: firstIdentifier
            };
        }
        function symbolToString(symbol, enclosingDeclaration, meaning, flags, writer) {
            if (flags === void 0) { flags = 4 /* AllowAnyNodeKind */; }
            var nodeFlags = 70221824 /* IgnoreErrors */;
            if (flags & 2 /* UseOnlyExternalAliasing */) {
                nodeFlags |= 128 /* UseOnlyExternalAliasing */;
            }
            if (flags & 1 /* WriteTypeParametersOrArguments */) {
                nodeFlags |= 512 /* WriteTypeParametersInQualifiedName */;
            }
            if (flags & 8 /* UseAliasDefinedOutsideCurrentScope */) {
                nodeFlags |= 16384 /* UseAliasDefinedOutsideCurrentScope */;
            }
            if (flags & 16 /* DoNotIncludeSymbolChain */) {
                nodeFlags |= 134217728 /* DoNotIncludeSymbolChain */;
            }
            var builder = flags & 4 /* AllowAnyNodeKind */ ? nodeBuilder.symbolToExpression : nodeBuilder.symbolToEntityName;
            return writer ? symbolToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(symbolToStringWorker);
            function symbolToStringWorker(writer) {
                var entity = builder(symbol, meaning, enclosingDeclaration, nodeFlags); // TODO: GH#18217
                var printer = ts.createPrinter({ removeComments: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, entity, /*sourceFile*/ sourceFile, writer);
                return writer;
            }
        }
        function signatureToString(signature, enclosingDeclaration, flags, kind, writer) {
            if (flags === void 0) { flags = 0 /* None */; }
            return writer ? signatureToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(signatureToStringWorker);
            function signatureToStringWorker(writer) {
                var sigOutput;
                if (flags & 262144 /* WriteArrowStyleSignature */) {
                    sigOutput = kind === 1 /* Construct */ ? 171 /* ConstructorType */ : 170 /* FunctionType */;
                }
                else {
                    sigOutput = kind === 1 /* Construct */ ? 166 /* ConstructSignature */ : 165 /* CallSignature */;
                }
                var sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | 512 /* WriteTypeParametersInQualifiedName */);
                var printer = ts.createPrinter({ removeComments: true, omitTrailingSemicolon: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, sig, /*sourceFile*/ sourceFile, ts.getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217
                return writer;
            }
        }
        function typeToString(type, enclosingDeclaration, flags, writer) {
            if (flags === void 0) { flags = 1048576 /* AllowUniqueESSymbolType */ | 16384 /* UseAliasDefinedOutsideCurrentScope */; }
            if (writer === void 0) { writer = ts.createTextWriter(""); }
            var noTruncation = compilerOptions.noErrorTruncation || flags & 1 /* NoTruncation */;
            var typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | (noTruncation ? 1 /* NoTruncation */ : 0), writer);
            if (typeNode === undefined)
                return ts.Debug.fail("should always get typenode");
            var options = { removeComments: true };
            var printer = ts.createPrinter(options);
            var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
            printer.writeNode(4 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer);
            var result = writer.getText();
            var maxLength = noTruncation ? ts.noTruncationMaximumTruncationLength * 2 : ts.defaultMaximumTruncationLength * 2;
            if (maxLength && result && result.length >= maxLength) {
                return result.substr(0, maxLength - "...".length) + "...";
            }
            return result;
        }
        function getTypeNamesForErrorDisplay(left, right) {
            var leftStr = symbolValueDeclarationIsContextSensitive(left.symbol) ? typeToString(left, left.symbol.valueDeclaration) : typeToString(left);
            var rightStr = symbolValueDeclarationIsContextSensitive(right.symbol) ? typeToString(right, right.symbol.valueDeclaration) : typeToString(right);
            if (leftStr === rightStr) {
                leftStr = typeToString(left, /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */);
                rightStr = typeToString(right, /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */);
            }
            return [leftStr, rightStr];
        }
        function symbolValueDeclarationIsContextSensitive(symbol) {
            return symbol && symbol.valueDeclaration && ts.isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration);
        }
        function toNodeBuilderFlags(flags) {
            if (flags === void 0) { flags = 0 /* None */; }
            return flags & 814775659 /* NodeBuilderFlagsMask */;
        }
        function createNodeBuilder() {
            return {
                typeToTypeNode: function (type, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeToTypeNodeHelper(type, context); });
                },
                indexInfoToIndexSignatureDeclaration: function (indexInfo, kind, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context); });
                },
                signatureToSignatureDeclaration: function (signature, kind, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return signatureToSignatureDeclarationHelper(signature, kind, context); });
                },
                symbolToEntityName: function (symbol, meaning, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToName(symbol, context, meaning, /*expectsIdentifier*/ false); });
                },
                symbolToExpression: function (symbol, meaning, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToExpression(symbol, context, meaning); });
                },
                symbolToTypeParameterDeclarations: function (symbol, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeParametersToTypeParameterDeclarations(symbol, context); });
                },
                symbolToParameterDeclaration: function (symbol, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolToParameterDeclaration(symbol, context); });
                },
                typeParameterToDeclaration: function (parameter, enclosingDeclaration, flags, tracker) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return typeParameterToDeclaration(parameter, context); });
                },
                symbolTableToDeclarationStatements: function (symbolTable, enclosingDeclaration, flags, tracker, bundled) {
                    return withContext(enclosingDeclaration, flags, tracker, function (context) { return symbolTableToDeclarationStatements(symbolTable, context, bundled); });
                },
            };
            function withContext(enclosingDeclaration, flags, tracker, cb) {
                ts.Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & 8 /* Synthesized */) === 0);
                var context = {
                    enclosingDeclaration: enclosingDeclaration,
                    flags: flags || 0 /* None */,
                    // If no full tracker is provided, fake up a dummy one with a basic limited-functionality moduleResolverHost
                    tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: ts.noop, moduleResolverHost: flags & 134217728 /* DoNotIncludeSymbolChain */ ? {
                            getCommonSourceDirectory: !!host.getCommonSourceDirectory ? function () { return host.getCommonSourceDirectory(); } : function () { return ""; },
                            getSourceFiles: function () { return host.getSourceFiles(); },
                            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
                            getProbableSymlinks: ts.maybeBind(host, host.getProbableSymlinks),
                            useCaseSensitiveFileNames: ts.maybeBind(host, host.useCaseSensitiveFileNames),
                            redirectTargetsMap: host.redirectTargetsMap,
                            getProjectReferenceRedirect: function (fileName) { return host.getProjectReferenceRedirect(fileName); },
                            isSourceOfProjectReferenceRedirect: function (fileName) { return host.isSourceOfProjectReferenceRedirect(fileName); },
                            fileExists: function (fileName) { return host.fileExists(fileName); },
                        } : undefined },
                    encounteredError: false,
                    visitedTypes: undefined,
                    symbolDepth: undefined,
                    inferTypeParameters: undefined,
                    approximateLength: 0
                };
                var resultingNode = cb(context);
                return context.encounteredError ? undefined : resultingNode;
            }
            function checkTruncationLength(context) {
                if (context.truncating)
                    return context.truncating;
                return context.truncating = context.approximateLength > ((context.flags & 1 /* NoTruncation */) ? ts.noTruncationMaximumTruncationLength : ts.defaultMaximumTruncationLength);
            }
            function typeToTypeNodeHelper(type, context) {
                if (cancellationToken && cancellationToken.throwIfCancellationRequested) {
                    cancellationToken.throwIfCancellationRequested();
                }
                var inTypeAlias = context.flags & 8388608 /* InTypeAlias */;
                context.flags &= ~8388608 /* InTypeAlias */;
                if (!type) {
                    if (!(context.flags & 262144 /* AllowEmptyUnionOrIntersection */)) {
                        context.encounteredError = true;
                        return undefined; // TODO: GH#18217
                    }
                    context.approximateLength += 3;
                    return ts.createKeywordTypeNode(125 /* AnyKeyword */);
                }
                if (!(context.flags & 536870912 /* NoTypeReduction */)) {
                    type = getReducedType(type);
                }
                if (type.flags & 1 /* Any */) {
                    context.approximateLength += 3;
                    return ts.createKeywordTypeNode(125 /* AnyKeyword */);
                }
                if (type.flags & 2 /* Unknown */) {
                    return ts.createKeywordTypeNode(148 /* UnknownKeyword */);
                }
                if (type.flags & 4 /* String */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(143 /* StringKeyword */);
                }
                if (type.flags & 8 /* Number */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(140 /* NumberKeyword */);
                }
                if (type.flags & 64 /* BigInt */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(151 /* BigIntKeyword */);
                }
                if (type.flags & 16 /* Boolean */) {
                    context.approximateLength += 7;
                    return ts.createKeywordTypeNode(128 /* BooleanKeyword */);
                }
                if (type.flags & 1024 /* EnumLiteral */ && !(type.flags & 1048576 /* Union */)) {
                    var parentSymbol = getParentOfSymbol(type.symbol);
                    var parentName = symbolToTypeNode(parentSymbol, context, 788968 /* Type */);
                    var enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type
                        ? parentName
                        : appendReferenceToType(parentName, ts.createTypeReferenceNode(ts.symbolName(type.symbol), /*typeArguments*/ undefined));
                    return enumLiteralName;
                }
                if (type.flags & 1056 /* EnumLike */) {
                    return symbolToTypeNode(type.symbol, context, 788968 /* Type */);
                }
                if (type.flags & 128 /* StringLiteral */) {
                    context.approximateLength += (type.value.length + 2);
                    return ts.createLiteralTypeNode(ts.setEmitFlags(ts.createLiteral(type.value, !!(context.flags & 268435456 /* UseSingleQuotesForStringLiteralType */)), 16777216 /* NoAsciiEscaping */));
                }
                if (type.flags & 256 /* NumberLiteral */) {
                    var value = type.value;
                    context.approximateLength += ("" + value).length;
                    return ts.createLiteralTypeNode(value < 0 ? ts.createPrefix(40 /* MinusToken */, ts.createLiteral(-value)) : ts.createLiteral(value));
                }
                if (type.flags & 2048 /* BigIntLiteral */) {
                    context.approximateLength += (ts.pseudoBigIntToString(type.value).length) + 1;
                    return ts.createLiteralTypeNode((ts.createLiteral(type.value)));
                }
                if (type.flags & 512 /* BooleanLiteral */) {
                    context.approximateLength += type.intrinsicName.length;
                    return type.intrinsicName === "true" ? ts.createTrue() : ts.createFalse();
                }
                if (type.flags & 8192 /* UniqueESSymbol */) {
                    if (!(context.flags & 1048576 /* AllowUniqueESSymbolType */)) {
                        if (isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                            context.approximateLength += 6;
                            return symbolToTypeNode(type.symbol, context, 111551 /* Value */);
                        }
                        if (context.tracker.reportInaccessibleUniqueSymbolError) {
                            context.tracker.reportInaccessibleUniqueSymbolError();
                        }
                    }
                    context.approximateLength += 13;
                    return ts.createTypeOperatorNode(147 /* UniqueKeyword */, ts.createKeywordTypeNode(144 /* SymbolKeyword */));
                }
                if (type.flags & 16384 /* Void */) {
                    context.approximateLength += 4;
                    return ts.createKeywordTypeNode(110 /* VoidKeyword */);
                }
                if (type.flags & 32768 /* Undefined */) {
                    context.approximateLength += 9;
                    return ts.createKeywordTypeNode(146 /* UndefinedKeyword */);
                }
                if (type.flags & 65536 /* Null */) {
                    context.approximateLength += 4;
                    return ts.createKeywordTypeNode(100 /* NullKeyword */);
                }
                if (type.flags & 131072 /* Never */) {
                    context.approximateLength += 5;
                    return ts.createKeywordTypeNode(137 /* NeverKeyword */);
                }
                if (type.flags & 4096 /* ESSymbol */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(144 /* SymbolKeyword */);
                }
                if (type.flags & 67108864 /* NonPrimitive */) {
                    context.approximateLength += 6;
                    return ts.createKeywordTypeNode(141 /* ObjectKeyword */);
                }
                if (isThisTypeParameter(type)) {
                    if (context.flags & 4194304 /* InObjectTypeLiteral */) {
                        if (!context.encounteredError && !(context.flags & 32768 /* AllowThisInObjectLiteral */)) {
                            context.encounteredError = true;
                        }
                        if (context.tracker.reportInaccessibleThisError) {
                            context.tracker.reportInaccessibleThisError();
                        }
                    }
                    context.approximateLength += 4;
                    return ts.createThis();
                }
                if (!inTypeAlias && type.aliasSymbol && (context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */ || isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration))) {
                    var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context);
                    if (isReservedMemberName(type.aliasSymbol.escapedName) && !(type.aliasSymbol.flags & 32 /* Class */))
                        return ts.createTypeReferenceNode(ts.createIdentifier(""), typeArgumentNodes);
                    return symbolToTypeNode(type.aliasSymbol, context, 788968 /* Type */, typeArgumentNodes);
                }
                var objectFlags = ts.getObjectFlags(type);
                if (objectFlags & 4 /* Reference */) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    return type.node ? visitAndTransformType(type, typeReferenceToTypeNode) : typeReferenceToTypeNode(type);
                }
                if (type.flags & 262144 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) {
                    if (type.flags & 262144 /* TypeParameter */ && ts.contains(context.inferTypeParameters, type)) {
                        context.approximateLength += (ts.symbolName(type.symbol).length + 6);
                        return ts.createInferTypeNode(typeParameterToDeclarationWithConstraint(type, context, /*constraintNode*/ undefined));
                    }
                    if (context.flags & 4 /* GenerateNamesForShadowedTypeParams */ &&
                        type.flags & 262144 /* TypeParameter */ &&
                        !isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                        var name = typeParameterToName(type, context);
                        context.approximateLength += ts.idText(name).length;
                        return ts.createTypeReferenceNode(ts.createIdentifier(ts.idText(name)), /*typeArguments*/ undefined);
                    }
                    // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
                    return type.symbol
                        ? symbolToTypeNode(type.symbol, context, 788968 /* Type */)
                        : ts.createTypeReferenceNode(ts.createIdentifier("?"), /*typeArguments*/ undefined);
                }
                if (type.flags & (1048576 /* Union */ | 2097152 /* Intersection */)) {
                    var types = type.flags & 1048576 /* Union */ ? formatUnionTypes(type.types) : type.types;
                    if (ts.length(types) === 1) {
                        return typeToTypeNodeHelper(types[0], context);
                    }
                    var typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true);
                    if (typeNodes && typeNodes.length > 0) {
                        var unionOrIntersectionTypeNode = ts.createUnionOrIntersectionTypeNode(type.flags & 1048576 /* Union */ ? 178 /* UnionType */ : 179 /* IntersectionType */, typeNodes);
                        return unionOrIntersectionTypeNode;
                    }
                    else {
                        if (!context.encounteredError && !(context.flags & 262144 /* AllowEmptyUnionOrIntersection */)) {
                            context.encounteredError = true;
                        }
                        return undefined; // TODO: GH#18217
                    }
                }
                if (objectFlags & (16 /* Anonymous */ | 32 /* Mapped */)) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    // The type is an object literal type.
                    return createAnonymousTypeNode(type);
                }
                if (type.flags & 4194304 /* Index */) {
                    var indexedType = type.type;
                    context.approximateLength += 6;
                    var indexTypeNode = typeToTypeNodeHelper(indexedType, context);
                    return ts.createTypeOperatorNode(indexTypeNode);
                }
                if (type.flags & 8388608 /* IndexedAccess */) {
                    var objectTypeNode = typeToTypeNodeHelper(type.objectType, context);
                    var indexTypeNode = typeToTypeNodeHelper(type.indexType, context);
                    context.approximateLength += 2;
                    return ts.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
                }
                if (type.flags & 16777216 /* Conditional */) {
                    var checkTypeNode = typeToTypeNodeHelper(type.checkType, context);
                    var saveInferTypeParameters = context.inferTypeParameters;
                    context.inferTypeParameters = type.root.inferTypeParameters;
                    var extendsTypeNode = typeToTypeNodeHelper(type.extendsType, context);
                    context.inferTypeParameters = saveInferTypeParameters;
                    var trueTypeNode = typeToTypeNodeOrCircularityElision(getTrueTypeFromConditionalType(type));
                    var falseTypeNode = typeToTypeNodeOrCircularityElision(getFalseTypeFromConditionalType(type));
                    context.approximateLength += 15;
                    return ts.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode);
                }
                if (type.flags & 33554432 /* Substitution */) {
                    return typeToTypeNodeHelper(type.baseType, context);
                }
                return ts.Debug.fail("Should be unreachable.");
                function typeToTypeNodeOrCircularityElision(type) {
                    var _a, _b;
                    if (type.flags & 1048576 /* Union */) {
                        if (context.visitedTypes && context.visitedTypes.has("" + getTypeId(type))) {
                            if (!(context.flags & 131072 /* AllowAnonymousIdentifier */)) {
                                context.encounteredError = true;
                                (_b = (_a = context.tracker) === null || _a === void 0 ? void 0 : _a.reportCyclicStructureError) === null || _b === void 0 ? void 0 : _b.call(_a);
                            }
                            return createElidedInformationPlaceholder(context);
                        }
                        return visitAndTransformType(type, function (type) { return typeToTypeNodeHelper(type, context); });
                    }
                    return typeToTypeNodeHelper(type, context);
                }
                function createMappedTypeNodeFromType(type) {
                    ts.Debug.assert(!!(type.flags & 524288 /* Object */));
                    var readonlyToken = type.declaration.readonlyToken ? ts.createToken(type.declaration.readonlyToken.kind) : undefined;
                    var questionToken = type.declaration.questionToken ? ts.createToken(type.declaration.questionToken.kind) : undefined;
                    var appropriateConstraintTypeNode;
                    if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                        // We have a { [P in keyof T]: X }
                        // We do this to ensure we retain the toplevel keyof-ness of the type which may be lost due to keyof distribution during `getConstraintTypeFromMappedType`
                        appropriateConstraintTypeNode = ts.createTypeOperatorNode(typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context));
                    }
                    else {
                        appropriateConstraintTypeNode = typeToTypeNodeHelper(getConstraintTypeFromMappedType(type), context);
                    }
                    var typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode);
                    var templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context);
                    var mappedTypeNode = ts.createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
                    context.approximateLength += 10;
                    return ts.setEmitFlags(mappedTypeNode, 1 /* SingleLine */);
                }
                function createAnonymousTypeNode(type) {
                    var typeId = "" + type.id;
                    var symbol = type.symbol;
                    if (symbol) {
                        if (isJSConstructor(symbol.valueDeclaration)) {
                            // Instance and static types share the same symbol; only add 'typeof' for the static side.
                            var isInstanceType = type === getDeclaredTypeOfClassOrInterface(symbol) ? 788968 /* Type */ : 111551 /* Value */;
                            return symbolToTypeNode(symbol, context, isInstanceType);
                        }
                        // Always use 'typeof T' for type of class, enum, and module objects
                        else if (symbol.flags & 32 /* Class */ && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === 214 /* ClassExpression */ && context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */) ||
                            symbol.flags & (384 /* Enum */ | 512 /* ValueModule */) ||
                            shouldWriteTypeOfFunctionSymbol()) {
                            return symbolToTypeNode(symbol, context, 111551 /* Value */);
                        }
                        else if (context.visitedTypes && context.visitedTypes.has(typeId)) {
                            // If type is an anonymous type literal in a type alias declaration, use type alias name
                            var typeAlias = getTypeAliasForTypeLiteral(type);
                            if (typeAlias) {
                                // The specified symbol flags need to be reinterpreted as type flags
                                return symbolToTypeNode(typeAlias, context, 788968 /* Type */);
                            }
                            else {
                                return createElidedInformationPlaceholder(context);
                            }
                        }
                        else {
                            return visitAndTransformType(type, createTypeNodeFromObjectType);
                        }
                    }
                    else {
                        // Anonymous types without a symbol are never circular.
                        return createTypeNodeFromObjectType(type);
                    }
                    function shouldWriteTypeOfFunctionSymbol() {
                        var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method
                            ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); });
                        var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) &&
                            (symbol.parent || // is exported function symbol
                                ts.forEach(symbol.declarations, function (declaration) {
                                    return declaration.parent.kind === 290 /* SourceFile */ || declaration.parent.kind === 250 /* ModuleBlock */;
                                }));
                        if (isStaticMethodSymbol || isNonLocalFunctionSymbol) {
                            // typeof is allowed only for static/non local functions
                            return (!!(context.flags & 4096 /* UseTypeOfFunction */) || (context.visitedTypes && context.visitedTypes.has(typeId))) && // it is type of the symbol uses itself recursively
                                (!(context.flags & 8 /* UseStructuralFallback */) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // And the build is going to succeed without visibility error or there is no structural fallback allowed
                        }
                    }
                }
                function visitAndTransformType(type, transform) {
                    var typeId = "" + type.id;
                    var isConstructorObject = ts.getObjectFlags(type) & 16 /* Anonymous */ && type.symbol && type.symbol.flags & 32 /* Class */;
                    var id = ts.getObjectFlags(type) & 4 /* Reference */ && type.node ? "N" + getNodeId(type.node) :
                        type.symbol ? (isConstructorObject ? "+" : "") + getSymbolId(type.symbol) :
                            undefined;
                    // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead
                    // of types allows us to catch circular references to instantiations of the same anonymous type
                    if (!context.visitedTypes) {
                        context.visitedTypes = ts.createMap();
                    }
                    if (id && !context.symbolDepth) {
                        context.symbolDepth = ts.createMap();
                    }
                    var depth;
                    if (id) {
                        depth = context.symbolDepth.get(id) || 0;
                        if (depth > 10) {
                            return createElidedInformationPlaceholder(context);
                        }
                        context.symbolDepth.set(id, depth + 1);
                    }
                    context.visitedTypes.set(typeId, true);
                    var result = transform(type);
                    context.visitedTypes.delete(typeId);
                    if (id) {
                        context.symbolDepth.set(id, depth);
                    }
                    return result;
                }
                function createTypeNodeFromObjectType(type) {
                    if (isGenericMappedType(type)) {
                        return createMappedTypeNodeFromType(type);
                    }
                    var resolved = resolveStructuredTypeMembers(type);
                    if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                        if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
                            context.approximateLength += 2;
                            return ts.setEmitFlags(ts.createTypeLiteralNode(/*members*/ undefined), 1 /* SingleLine */);
                        }
                        if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) {
                            var signature = resolved.callSignatures[0];
                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 170 /* FunctionType */, context);
                            return signatureNode;
                        }
                        if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) {
                            var signature = resolved.constructSignatures[0];
                            var signatureNode = signatureToSignatureDeclarationHelper(signature, 171 /* ConstructorType */, context);
                            return signatureNode;
                        }
                    }
                    var savedFlags = context.flags;
                    context.flags |= 4194304 /* InObjectTypeLiteral */;
                    var members = createTypeNodesFromResolvedType(resolved);
                    context.flags = savedFlags;
                    var typeLiteralNode = ts.createTypeLiteralNode(members);
                    context.approximateLength += 2;
                    return ts.setEmitFlags(typeLiteralNode, (context.flags & 1024 /* MultilineObjectLiterals */) ? 0 : 1 /* SingleLine */);
                }
                function typeReferenceToTypeNode(type) {
                    var typeArguments = getTypeArguments(type);
                    if (type.target === globalArrayType || type.target === globalReadonlyArrayType) {
                        if (context.flags & 2 /* WriteArrayAsGenericType */) {
                            var typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
                            return ts.createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray", [typeArgumentNode]);
                        }
                        var elementType = typeToTypeNodeHelper(typeArguments[0], context);
                        var arrayType = ts.createArrayTypeNode(elementType);
                        return type.target === globalArrayType ? arrayType : ts.createTypeOperatorNode(138 /* ReadonlyKeyword */, arrayType);
                    }
                    else if (type.target.objectFlags & 8 /* Tuple */) {
                        if (typeArguments.length > 0) {
                            var arity = getTypeReferenceArity(type);
                            var tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, arity), context);
                            var hasRestElement = type.target.hasRestElement;
                            if (tupleConstituentNodes) {
                                for (var i = type.target.minLength; i < Math.min(arity, tupleConstituentNodes.length); i++) {
                                    tupleConstituentNodes[i] = hasRestElement && i === arity - 1 ?
                                        ts.createRestTypeNode(ts.createArrayTypeNode(tupleConstituentNodes[i])) :
                                        ts.createOptionalTypeNode(tupleConstituentNodes[i]);
                                }
                                var tupleTypeNode = ts.createTupleTypeNode(tupleConstituentNodes);
                                return type.target.readonly ? ts.createTypeOperatorNode(138 /* ReadonlyKeyword */, tupleTypeNode) : tupleTypeNode;
                            }
                        }
                        if (context.encounteredError || (context.flags & 524288 /* AllowEmptyTuple */)) {
                            var tupleTypeNode = ts.createTupleTypeNode([]);
                            return type.target.readonly ? ts.createTypeOperatorNode(138 /* ReadonlyKeyword */, tupleTypeNode) : tupleTypeNode;
                        }
                        context.encounteredError = true;
                        return undefined; // TODO: GH#18217
                    }
                    else if (context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */ &&
                        type.symbol.valueDeclaration &&
                        ts.isClassLike(type.symbol.valueDeclaration) &&
                        !isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
                        return createAnonymousTypeNode(type);
                    }
                    else {
                        var outerTypeParameters = type.target.outerTypeParameters;
                        var i = 0;
                        var resultType = void 0;
                        if (outerTypeParameters) {
                            var length_2 = outerTypeParameters.length;
                            while (i < length_2) {
                                // Find group of type arguments for type parameters with the same declaring container.
                                var start = i;
                                var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]);
                                do {
                                    i++;
                                } while (i < length_2 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent);
                                // When type parameters are their own type arguments for the whole group (i.e. we have
                                // the default outer type arguments), we don't show the group.
                                if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) {
                                    var typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context);
                                    var flags_2 = context.flags;
                                    context.flags |= 16 /* ForbidIndexedAccessSymbolReferences */;
                                    var ref = symbolToTypeNode(parent, context, 788968 /* Type */, typeArgumentSlice);
                                    context.flags = flags_2;
                                    resultType = !resultType ? ref : appendReferenceToType(resultType, ref);
                                }
                            }
                        }
                        var typeArgumentNodes = void 0;
                        if (typeArguments.length > 0) {
                            var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length;
                            typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context);
                        }
                        var flags = context.flags;
                        context.flags |= 16 /* ForbidIndexedAccessSymbolReferences */;
                        var finalRef = symbolToTypeNode(type.symbol, context, 788968 /* Type */, typeArgumentNodes);
                        context.flags = flags;
                        return !resultType ? finalRef : appendReferenceToType(resultType, finalRef);
                    }
                }
                function appendReferenceToType(root, ref) {
                    if (ts.isImportTypeNode(root)) {
                        // first shift type arguments
                        var innerParams = root.typeArguments;
                        if (root.qualifier) {
                            (ts.isIdentifier(root.qualifier) ? root.qualifier : root.qualifier.right).typeArguments = innerParams;
                        }
                        root.typeArguments = ref.typeArguments;
                        // then move qualifiers
                        var ids = getAccessStack(ref);
                        for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
                            var id = ids_1[_i];
                            root.qualifier = root.qualifier ? ts.createQualifiedName(root.qualifier, id) : id;
                        }
                        return root;
                    }
                    else {
                        // first shift type arguments
                        var innerParams = root.typeArguments;
                        (ts.isIdentifier(root.typeName) ? root.typeName : root.typeName.right).typeArguments = innerParams;
                        root.typeArguments = ref.typeArguments;
                        // then move qualifiers
                        var ids = getAccessStack(ref);
                        for (var _a = 0, ids_2 = ids; _a < ids_2.length; _a++) {
                            var id = ids_2[_a];
                            root.typeName = ts.createQualifiedName(root.typeName, id);
                        }
                        return root;
                    }
                }
                function getAccessStack(ref) {
                    var state = ref.typeName;
                    var ids = [];
                    while (!ts.isIdentifier(state)) {
                        ids.unshift(state.right);
                        state = state.left;
                    }
                    ids.unshift(state);
                    return ids;
                }
                function createTypeNodesFromResolvedType(resolvedType) {
                    if (checkTruncationLength(context)) {
                        return [ts.createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)];
                    }
                    var typeElements = [];
                    for (var _i = 0, _a = resolvedType.callSignatures; _i < _a.length; _i++) {
                        var signature = _a[_i];
                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 165 /* CallSignature */, context));
                    }
                    for (var _b = 0, _c = resolvedType.constructSignatures; _b < _c.length; _b++) {
                        var signature = _c[_b];
                        typeElements.push(signatureToSignatureDeclarationHelper(signature, 166 /* ConstructSignature */, context));
                    }
                    if (resolvedType.stringIndexInfo) {
                        var indexSignature = void 0;
                        if (resolvedType.objectFlags & 2048 /* ReverseMapped */) {
                            indexSignature = indexInfoToIndexSignatureDeclarationHelper(createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration), 0 /* String */, context);
                            indexSignature.type = createElidedInformationPlaceholder(context);
                        }
                        else {
                            indexSignature = indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, 0 /* String */, context);
                        }
                        typeElements.push(indexSignature);
                    }
                    if (resolvedType.numberIndexInfo) {
                        typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, 1 /* Number */, context));
                    }
                    var properties = resolvedType.properties;
                    if (!properties) {
                        return typeElements;
                    }
                    var i = 0;
                    for (var _d = 0, properties_1 = properties; _d < properties_1.length; _d++) {
                        var propertySymbol = properties_1[_d];
                        i++;
                        if (context.flags & 2048 /* WriteClassExpressionAsTypeLiteral */) {
                            if (propertySymbol.flags & 4194304 /* Prototype */) {
                                continue;
                            }
                            if (ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & (8 /* Private */ | 16 /* Protected */) && context.tracker.reportPrivateInBaseOfClassExpression) {
                                context.tracker.reportPrivateInBaseOfClassExpression(ts.unescapeLeadingUnderscores(propertySymbol.escapedName));
                            }
                        }
                        if (checkTruncationLength(context) && (i + 2 < properties.length - 1)) {
                            typeElements.push(ts.createPropertySignature(/*modifiers*/ undefined, "... " + (properties.length - i) + " more ...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined));
                            addPropertyToElementList(properties[properties.length - 1], context, typeElements);
                            break;
                        }
                        addPropertyToElementList(propertySymbol, context, typeElements);
                    }
                    return typeElements.length ? typeElements : undefined;
                }
            }
            function createElidedInformationPlaceholder(context) {
                context.approximateLength += 3;
                if (!(context.flags & 1 /* NoTruncation */)) {
                    return ts.createTypeReferenceNode(ts.createIdentifier("..."), /*typeArguments*/ undefined);
                }
                return ts.createKeywordTypeNode(125 /* AnyKeyword */);
            }
            function addPropertyToElementList(propertySymbol, context, typeElements) {
                var propertyIsReverseMapped = !!(ts.getCheckFlags(propertySymbol) & 8192 /* ReverseMapped */);
                var propertyType = propertyIsReverseMapped && context.flags & 33554432 /* InReverseMappedType */ ?
                    anyType : getTypeOfSymbol(propertySymbol);
                var saveEnclosingDeclaration = context.enclosingDeclaration;
                context.enclosingDeclaration = undefined;
                if (context.tracker.trackSymbol && ts.getCheckFlags(propertySymbol) & 4096 /* Late */) {
                    var decl = ts.first(propertySymbol.declarations);
                    if (hasLateBindableName(decl)) {
                        if (ts.isBinaryExpression(decl)) {
                            var name = ts.getNameOfDeclaration(decl);
                            if (name && ts.isElementAccessExpression(name) && ts.isPropertyAccessEntityNameExpression(name.argumentExpression)) {
                                trackComputedName(name.argumentExpression, saveEnclosingDeclaration, context);
                            }
                        }
                        else {
                            trackComputedName(decl.name.expression, saveEnclosingDeclaration, context);
                        }
                    }
                }
                context.enclosingDeclaration = saveEnclosingDeclaration;
                var propertyName = getPropertyNameNodeForSymbol(propertySymbol, context);
                context.approximateLength += (ts.symbolName(propertySymbol).length + 1);
                var optionalToken = propertySymbol.flags & 16777216 /* Optional */ ? ts.createToken(57 /* QuestionToken */) : undefined;
                if (propertySymbol.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) {
                    var signatures = getSignaturesOfType(filterType(propertyType, function (t) { return !(t.flags & 32768 /* Undefined */); }), 0 /* Call */);
                    for (var _i = 0, signatures_1 = signatures; _i < signatures_1.length; _i++) {
                        var signature = signatures_1[_i];
                        var methodDeclaration = signatureToSignatureDeclarationHelper(signature, 160 /* MethodSignature */, context);
                        methodDeclaration.name = propertyName;
                        methodDeclaration.questionToken = optionalToken;
                        typeElements.push(preserveCommentsOn(methodDeclaration));
                    }
                }
                else {
                    var savedFlags = context.flags;
                    context.flags |= propertyIsReverseMapped ? 33554432 /* InReverseMappedType */ : 0;
                    var propertyTypeNode = void 0;
                    if (propertyIsReverseMapped && !!(savedFlags & 33554432 /* InReverseMappedType */)) {
                        propertyTypeNode = createElidedInformationPlaceholder(context);
                    }
                    else {
                        propertyTypeNode = propertyType ? serializeTypeForDeclaration(context, propertyType, propertySymbol, saveEnclosingDeclaration) : ts.createKeywordTypeNode(125 /* AnyKeyword */);
                    }
                    context.flags = savedFlags;
                    var modifiers = isReadonlySymbol(propertySymbol) ? [ts.createToken(138 /* ReadonlyKeyword */)] : undefined;
                    if (modifiers) {
                        context.approximateLength += 9;
                    }
                    var propertySignature = ts.createPropertySignature(modifiers, propertyName, optionalToken, propertyTypeNode, 
                    /*initializer*/ undefined);
                    typeElements.push(preserveCommentsOn(propertySignature));
                }
                function preserveCommentsOn(node) {
                    if (ts.some(propertySymbol.declarations, function (d) { return d.kind === 323 /* JSDocPropertyTag */; })) {
                        var d = ts.find(propertySymbol.declarations, function (d) { return d.kind === 323 /* JSDocPropertyTag */; });
                        var commentText = d.comment;
                        if (commentText) {
                            ts.setSyntheticLeadingComments(node, [{ kind: 3 /* MultiLineCommentTrivia */, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]);
                        }
                    }
                    else if (propertySymbol.valueDeclaration) {
                        // Copy comments to node for declaration emit
                        ts.setCommentRange(node, propertySymbol.valueDeclaration);
                    }
                    return node;
                }
            }
            function mapToTypeNodes(types, context, isBareList) {
                if (ts.some(types)) {
                    if (checkTruncationLength(context)) {
                        if (!isBareList) {
                            return [ts.createTypeReferenceNode("...", /*typeArguments*/ undefined)];
                        }
                        else if (types.length > 2) {
                            return [
                                typeToTypeNodeHelper(types[0], context),
                                ts.createTypeReferenceNode("... " + (types.length - 2) + " more ...", /*typeArguments*/ undefined),
                                typeToTypeNodeHelper(types[types.length - 1], context)
                            ];
                        }
                    }
                    var mayHaveNameCollisions = !(context.flags & 64 /* UseFullyQualifiedType */);
                    /** Map from type reference identifier text to [type, index in `result` where the type node is] */
                    var seenNames = mayHaveNameCollisions ? ts.createUnderscoreEscapedMultiMap() : undefined;
                    var result_3 = [];
                    var i = 0;
                    for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
                        var type = types_1[_i];
                        i++;
                        if (checkTruncationLength(context) && (i + 2 < types.length - 1)) {
                            result_3.push(ts.createTypeReferenceNode("... " + (types.length - i) + " more ...", /*typeArguments*/ undefined));
                            var typeNode_1 = typeToTypeNodeHelper(types[types.length - 1], context);
                            if (typeNode_1) {
                                result_3.push(typeNode_1);
                            }
                            break;
                        }
                        context.approximateLength += 2; // Account for whitespace + separator
                        var typeNode = typeToTypeNodeHelper(type, context);
                        if (typeNode) {
                            result_3.push(typeNode);
                            if (seenNames && ts.isIdentifierTypeReference(typeNode)) {
                                seenNames.add(typeNode.typeName.escapedText, [type, result_3.length - 1]);
                            }
                        }
                    }
                    if (seenNames) {
                        // To avoid printing types like `[Foo, Foo]` or `Bar & Bar` where
                        // occurrences of the same name actually come from different
                        // namespaces, go through the single-identifier type reference nodes
                        // we just generated, and see if any names were generated more than
                        // once while referring to different types. If so, regenerate the
                        // type node for each entry by that name with the
                        // `UseFullyQualifiedType` flag enabled.
                        var saveContextFlags = context.flags;
                        context.flags |= 64 /* UseFullyQualifiedType */;
                        seenNames.forEach(function (types) {
                            if (!ts.arrayIsHomogeneous(types, function (_a, _b) {
                                var a = _a[0];
                                var b = _b[0];
                                return typesAreSameReference(a, b);
                            })) {
                                for (var _i = 0, types_2 = types; _i < types_2.length; _i++) {
                                    var _a = types_2[_i], type = _a[0], resultIndex = _a[1];
                                    result_3[resultIndex] = typeToTypeNodeHelper(type, context);
                                }
                            }
                        });
                        context.flags = saveContextFlags;
                    }
                    return result_3;
                }
            }
            function typesAreSameReference(a, b) {
                return a === b
                    || !!a.symbol && a.symbol === b.symbol
                    || !!a.aliasSymbol && a.aliasSymbol === b.aliasSymbol;
            }
            function indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context) {
                var name = ts.getNameFromIndexInfo(indexInfo) || "x";
                var indexerTypeNode = ts.createKeywordTypeNode(kind === 0 /* String */ ? 143 /* StringKeyword */ : 140 /* NumberKeyword */);
                var indexingParameter = ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, name, 
                /*questionToken*/ undefined, indexerTypeNode, 
                /*initializer*/ undefined);
                var typeNode = typeToTypeNodeHelper(indexInfo.type || anyType, context);
                if (!indexInfo.type && !(context.flags & 2097152 /* AllowEmptyIndexInfoType */)) {
                    context.encounteredError = true;
                }
                context.approximateLength += (name.length + 4);
                return ts.createIndexSignature(
                /*decorators*/ undefined, indexInfo.isReadonly ? [ts.createToken(138 /* ReadonlyKeyword */)] : undefined, [indexingParameter], typeNode);
            }
            function signatureToSignatureDeclarationHelper(signature, kind, context, privateSymbolVisitor, bundledImports) {
                var suppressAny = context.flags & 256 /* SuppressAnyReturnType */;
                if (suppressAny)
                    context.flags &= ~256 /* SuppressAnyReturnType */; // suppress only toplevel `any`s
                var typeParameters;
                var typeArguments;
                if (context.flags & 32 /* WriteTypeArgumentsOfSignature */ && signature.target && signature.mapper && signature.target.typeParameters) {
                    typeArguments = signature.target.typeParameters.map(function (parameter) { return typeToTypeNodeHelper(instantiateType(parameter, signature.mapper), context); });
                }
                else {
                    typeParameters = signature.typeParameters && signature.typeParameters.map(function (parameter) { return typeParameterToDeclaration(parameter, context); });
                }
                var parameters = getExpandedParameters(signature).map(function (parameter) { return symbolToParameterDeclaration(parameter, context, kind === 162 /* Constructor */, privateSymbolVisitor, bundledImports); });
                if (signature.thisParameter) {
                    var thisParameter = symbolToParameterDeclaration(signature.thisParameter, context);
                    parameters.unshift(thisParameter);
                }
                var returnTypeNode;
                var typePredicate = getTypePredicateOfSignature(signature);
                if (typePredicate) {
                    var assertsModifier = typePredicate.kind === 2 /* AssertsThis */ || typePredicate.kind === 3 /* AssertsIdentifier */ ?
                        ts.createToken(124 /* AssertsKeyword */) :
                        undefined;
                    var parameterName = typePredicate.kind === 1 /* Identifier */ || typePredicate.kind === 3 /* AssertsIdentifier */ ?
                        ts.setEmitFlags(ts.createIdentifier(typePredicate.parameterName), 16777216 /* NoAsciiEscaping */) :
                        ts.createThisTypeNode();
                    var typeNode = typePredicate.type && typeToTypeNodeHelper(typePredicate.type, context);
                    returnTypeNode = ts.createTypePredicateNodeWithModifier(assertsModifier, parameterName, typeNode);
                }
                else {
                    var returnType = getReturnTypeOfSignature(signature);
                    if (returnType && !(suppressAny && isTypeAny(returnType))) {
                        returnTypeNode = serializeReturnTypeForSignature(context, returnType, signature, privateSymbolVisitor, bundledImports);
                    }
                    else if (!suppressAny) {
                        returnTypeNode = ts.createKeywordTypeNode(125 /* AnyKeyword */);
                    }
                }
                context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
                return ts.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments);
            }
            function typeParameterToDeclarationWithConstraint(type, context, constraintNode) {
                var savedContextFlags = context.flags;
                context.flags &= ~512 /* WriteTypeParametersInQualifiedName */; // Avoids potential infinite loop when building for a claimspace with a generic
                var name = typeParameterToName(type, context);
                var defaultParameter = getDefaultFromTypeParameter(type);
                var defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context);
                context.flags = savedContextFlags;
                return ts.createTypeParameterDeclaration(name, constraintNode, defaultParameterNode);
            }
            function typeParameterToDeclaration(type, context, constraint) {
                if (constraint === void 0) { constraint = getConstraintOfTypeParameter(type); }
                var constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
                return typeParameterToDeclarationWithConstraint(type, context, constraintNode);
            }
            function symbolToParameterDeclaration(parameterSymbol, context, preserveModifierFlags, privateSymbolVisitor, bundledImports) {
                var parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 156 /* Parameter */);
                if (!parameterDeclaration && !ts.isTransientSymbol(parameterSymbol)) {
                    parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 317 /* JSDocParameterTag */);
                }
                var parameterType = getTypeOfSymbol(parameterSymbol);
                if (parameterDeclaration && isRequiredInitializedParameter(parameterDeclaration)) {
                    parameterType = getOptionalType(parameterType);
                }
                var parameterTypeNode = serializeTypeForDeclaration(context, parameterType, parameterSymbol, context.enclosingDeclaration, privateSymbolVisitor, bundledImports);
                var modifiers = !(context.flags & 8192 /* OmitParameterModifiers */) && preserveModifierFlags && parameterDeclaration && parameterDeclaration.modifiers ? parameterDeclaration.modifiers.map(ts.getSynthesizedClone) : undefined;
                var isRest = parameterDeclaration && ts.isRestParameter(parameterDeclaration) || ts.getCheckFlags(parameterSymbol) & 32768 /* RestParameter */;
                var dotDotDotToken = isRest ? ts.createToken(25 /* DotDotDotToken */) : undefined;
                var name = parameterDeclaration ? parameterDeclaration.name ?
                    parameterDeclaration.name.kind === 75 /* Identifier */ ? ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name), 16777216 /* NoAsciiEscaping */) :
                        parameterDeclaration.name.kind === 153 /* QualifiedName */ ? ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name.right), 16777216 /* NoAsciiEscaping */) :
                            cloneBindingName(parameterDeclaration.name) :
                    ts.symbolName(parameterSymbol) :
                    ts.symbolName(parameterSymbol);
                var isOptional = parameterDeclaration && isOptionalParameter(parameterDeclaration) || ts.getCheckFlags(parameterSymbol) & 16384 /* OptionalParameter */;
                var questionToken = isOptional ? ts.createToken(57 /* QuestionToken */) : undefined;
                var parameterNode = ts.createParameter(
                /*decorators*/ undefined, modifiers, dotDotDotToken, name, questionToken, parameterTypeNode, 
                /*initializer*/ undefined);
                context.approximateLength += ts.symbolName(parameterSymbol).length + 3;
                return parameterNode;
                function cloneBindingName(node) {
                    return elideInitializerAndSetEmitFlags(node);
                    function elideInitializerAndSetEmitFlags(node) {
                        if (context.tracker.trackSymbol && ts.isComputedPropertyName(node) && isLateBindableName(node)) {
                            trackComputedName(node.expression, context.enclosingDeclaration, context);
                        }
                        var visited = ts.visitEachChild(node, elideInitializerAndSetEmitFlags, ts.nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags);
                        var clone = ts.nodeIsSynthesized(visited) ? visited : ts.getSynthesizedClone(visited);
                        if (clone.kind === 191 /* BindingElement */) {
                            clone.initializer = undefined;
                        }
                        return ts.setEmitFlags(clone, 1 /* SingleLine */ | 16777216 /* NoAsciiEscaping */);
                    }
                }
            }
            function trackComputedName(accessExpression, enclosingDeclaration, context) {
                if (!context.tracker.trackSymbol)
                    return;
                // get symbol of the first identifier of the entityName
                var firstIdentifier = ts.getFirstIdentifier(accessExpression);
                var name = resolveName(firstIdentifier, firstIdentifier.escapedText, 111551 /* Value */ | 1048576 /* ExportValue */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
                if (name) {
                    context.tracker.trackSymbol(name, enclosingDeclaration, 111551 /* Value */);
                }
            }
            function lookupSymbolChain(symbol, context, meaning, yieldModuleSymbol) {
                context.tracker.trackSymbol(symbol, context.enclosingDeclaration, meaning); // TODO: GH#18217
                return lookupSymbolChainWorker(symbol, context, meaning, yieldModuleSymbol);
            }
            function lookupSymbolChainWorker(symbol, context, meaning, yieldModuleSymbol) {
                // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
                var chain;
                var isTypeParameter = symbol.flags & 262144 /* TypeParameter */;
                if (!isTypeParameter && (context.enclosingDeclaration || context.flags & 64 /* UseFullyQualifiedType */) && !(context.flags & 134217728 /* DoNotIncludeSymbolChain */)) {
                    chain = ts.Debug.checkDefined(getSymbolChain(symbol, meaning, /*endOfChain*/ true));
                    ts.Debug.assert(chain && chain.length > 0);
                }
                else {
                    chain = [symbol];
                }
                return chain;
                /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
                function getSymbolChain(symbol, meaning, endOfChain) {
                    var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, !!(context.flags & 128 /* UseOnlyExternalAliasing */));
                    var parentSpecifiers;
                    if (!accessibleSymbolChain ||
                        needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
                        // Go up and add our parent.
                        var parents_1 = getContainersOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol, context.enclosingDeclaration);
                        if (ts.length(parents_1)) {
                            parentSpecifiers = parents_1.map(function (symbol) {
                                return ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)
                                    ? getSpecifierForModuleSymbol(symbol, context)
                                    : undefined;
                            });
                            var indices = parents_1.map(function (_, i) { return i; });
                            indices.sort(sortByBestName);
                            var sortedParents = indices.map(function (i) { return parents_1[i]; });
                            for (var _i = 0, sortedParents_1 = sortedParents; _i < sortedParents_1.length; _i++) {
                                var parent = sortedParents_1[_i];
                                var parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false);
                                if (parentChain) {
                                    if (parent.exports && parent.exports.get("export=" /* ExportEquals */) &&
                                        getSymbolIfSameReference(parent.exports.get("export=" /* ExportEquals */), symbol)) {
                                        // parentChain root _is_ symbol - symbol is a module export=, so it kinda looks like it's own parent
                                        // No need to lookup an alias for the symbol in itself
                                        accessibleSymbolChain = parentChain;
                                        break;
                                    }
                                    accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [getAliasForSymbolInContainer(parent, symbol) || symbol]);
                                    break;
                                }
                            }
                        }
                    }
                    if (accessibleSymbolChain) {
                        return accessibleSymbolChain;
                    }
                    if (
                    // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
                    endOfChain ||
                        // If a parent symbol is an anonymous type, don't write it.
                        !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) {
                        // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
                        if (!endOfChain && !yieldModuleSymbol && !!ts.forEach(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                            return;
                        }
                        return [symbol];
                    }
                    function sortByBestName(a, b) {
                        var specifierA = parentSpecifiers[a];
                        var specifierB = parentSpecifiers[b];
                        if (specifierA && specifierB) {
                            var isBRelative = ts.pathIsRelative(specifierB);
                            if (ts.pathIsRelative(specifierA) === isBRelative) {
                                // Both relative or both non-relative, sort by number of parts
                                return ts.moduleSpecifiers.countPathComponents(specifierA) - ts.moduleSpecifiers.countPathComponents(specifierB);
                            }
                            if (isBRelative) {
                                // A is non-relative, B is relative: prefer A
                                return -1;
                            }
                            // A is relative, B is non-relative: prefer B
                            return 1;
                        }
                        return 0;
                    }
                }
            }
            function typeParametersToTypeParameterDeclarations(symbol, context) {
                var typeParameterNodes;
                var targetSymbol = getTargetSymbol(symbol);
                if (targetSymbol.flags & (32 /* Class */ | 64 /* Interface */ | 524288 /* TypeAlias */)) {
                    typeParameterNodes = ts.createNodeArray(ts.map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), function (tp) { return typeParameterToDeclaration(tp, context); }));
                }
                return typeParameterNodes;
            }
            function lookupTypeParameterNodes(chain, index, context) {
                ts.Debug.assert(chain && 0 <= index && index < chain.length);
                var symbol = chain[index];
                var symbolId = "" + getSymbolId(symbol);
                if (context.typeParameterSymbolList && context.typeParameterSymbolList.get(symbolId)) {
                    return undefined;
                }
                (context.typeParameterSymbolList || (context.typeParameterSymbolList = ts.createMap())).set(symbolId, true);
                var typeParameterNodes;
                if (context.flags & 512 /* WriteTypeParametersInQualifiedName */ && index < (chain.length - 1)) {
                    var parentSymbol = symbol;
                    var nextSymbol_1 = chain[index + 1];
                    if (ts.getCheckFlags(nextSymbol_1) & 1 /* Instantiated */) {
                        var params = getTypeParametersOfClassOrInterface(parentSymbol.flags & 2097152 /* Alias */ ? resolveAlias(parentSymbol) : parentSymbol);
                        typeParameterNodes = mapToTypeNodes(ts.map(params, function (t) { return getMappedType(t, nextSymbol_1.mapper); }), context);
                    }
                    else {
                        typeParameterNodes = typeParametersToTypeParameterDeclarations(symbol, context);
                    }
                }
                return typeParameterNodes;
            }
            /**
             * Given A[B][C][D], finds A[B]
             */
            function getTopmostIndexedAccessType(top) {
                if (ts.isIndexedAccessTypeNode(top.objectType)) {
                    return getTopmostIndexedAccessType(top.objectType);
                }
                return top;
            }
            function getSpecifierForModuleSymbol(symbol, context) {
                var file = ts.getDeclarationOfKind(symbol, 290 /* SourceFile */);
                if (!file) {
                    var equivalentFileSymbol = ts.firstDefined(symbol.declarations, function (d) { return getFileSymbolIfFileSymbolExportEqualsContainer(d, symbol); });
                    if (equivalentFileSymbol) {
                        file = ts.getDeclarationOfKind(equivalentFileSymbol, 290 /* SourceFile */);
                    }
                }
                if (file && file.moduleName !== undefined) {
                    // Use the amd name if it is available
                    return file.moduleName;
                }
                if (!file) {
                    if (context.tracker.trackReferencedAmbientModule) {
                        var ambientDecls = ts.filter(symbol.declarations, ts.isAmbientModule);
                        if (ts.length(ambientDecls)) {
                            for (var _i = 0, ambientDecls_1 = ambientDecls; _i < ambientDecls_1.length; _i++) {
                                var decl = ambientDecls_1[_i];
                                context.tracker.trackReferencedAmbientModule(decl, symbol);
                            }
                        }
                    }
                    if (ambientModuleSymbolRegex.test(symbol.escapedName)) {
                        return symbol.escapedName.substring(1, symbol.escapedName.length - 1);
                    }
                }
                if (!context.enclosingDeclaration || !context.tracker.moduleResolverHost) {
                    // If there's no context declaration, we can't lookup a non-ambient specifier, so we just use the symbol name
                    if (ambientModuleSymbolRegex.test(symbol.escapedName)) {
                        return symbol.escapedName.substring(1, symbol.escapedName.length - 1);
                    }
                    return ts.getSourceFileOfNode(ts.getNonAugmentationDeclaration(symbol)).fileName; // A resolver may not be provided for baselines and errors - in those cases we use the fileName in full
                }
                var contextFile = ts.getSourceFileOfNode(ts.getOriginalNode(context.enclosingDeclaration));
                var links = getSymbolLinks(symbol);
                var specifier = links.specifierCache && links.specifierCache.get(contextFile.path);
                if (!specifier) {
                    var isBundle_1 = (compilerOptions.out || compilerOptions.outFile);
                    // For declaration bundles, we need to generate absolute paths relative to the common source dir for imports,
                    // just like how the declaration emitter does for the ambient module declarations - we can easily accomplish this
                    // using the `baseUrl` compiler option (which we would otherwise never use in declaration emit) and a non-relative
                    // specifier preference
                    var moduleResolverHost = context.tracker.moduleResolverHost;
                    var specifierCompilerOptions = isBundle_1 ? __assign(__assign({}, compilerOptions), { baseUrl: moduleResolverHost.getCommonSourceDirectory() }) : compilerOptions;
                    specifier = ts.first(ts.moduleSpecifiers.getModuleSpecifiers(symbol, specifierCompilerOptions, contextFile, moduleResolverHost, { importModuleSpecifierPreference: isBundle_1 ? "non-relative" : "relative" }));
                    links.specifierCache = links.specifierCache || ts.createMap();
                    links.specifierCache.set(contextFile.path, specifier);
                }
                return specifier;
            }
            function symbolToTypeNode(symbol, context, meaning, overrideTypeArguments) {
                var chain = lookupSymbolChain(symbol, context, meaning, !(context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */)); // If we're using aliases outside the current scope, dont bother with the module
                var isTypeOf = meaning === 111551 /* Value */;
                if (ts.some(chain[0].declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                    // module is root, must use `ImportTypeNode`
                    var nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined;
                    var typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context);
                    var specifier = getSpecifierForModuleSymbol(chain[0], context);
                    if (!(context.flags & 67108864 /* AllowNodeModulesRelativePaths */) && ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs && specifier.indexOf("/node_modules/") >= 0) {
                        // If ultimately we can only name the symbol with a reference that dives into a `node_modules` folder, we should error
                        // since declaration files with these kinds of references are liable to fail when published :(
                        context.encounteredError = true;
                        if (context.tracker.reportLikelyUnsafeImportRequiredError) {
                            context.tracker.reportLikelyUnsafeImportRequiredError(specifier);
                        }
                    }
                    var lit = ts.createLiteralTypeNode(ts.createLiteral(specifier));
                    if (context.tracker.trackExternalModuleSymbolOfImportTypeNode)
                        context.tracker.trackExternalModuleSymbolOfImportTypeNode(chain[0]);
                    context.approximateLength += specifier.length + 10; // specifier + import("")
                    if (!nonRootParts || ts.isEntityName(nonRootParts)) {
                        if (nonRootParts) {
                            var lastId = ts.isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right;
                            lastId.typeArguments = undefined;
                        }
                        return ts.createImportTypeNode(lit, nonRootParts, typeParameterNodes, isTypeOf);
                    }
                    else {
                        var splitNode = getTopmostIndexedAccessType(nonRootParts);
                        var qualifier = splitNode.objectType.typeName;
                        return ts.createIndexedAccessTypeNode(ts.createImportTypeNode(lit, qualifier, typeParameterNodes, isTypeOf), splitNode.indexType);
                    }
                }
                var entityName = createAccessFromSymbolChain(chain, chain.length - 1, 0);
                if (ts.isIndexedAccessTypeNode(entityName)) {
                    return entityName; // Indexed accesses can never be `typeof`
                }
                if (isTypeOf) {
                    return ts.createTypeQueryNode(entityName);
                }
                else {
                    var lastId = ts.isIdentifier(entityName) ? entityName : entityName.right;
                    var lastTypeArgs = lastId.typeArguments;
                    lastId.typeArguments = undefined;
                    return ts.createTypeReferenceNode(entityName, lastTypeArgs);
                }
                function createAccessFromSymbolChain(chain, index, stopper) {
                    var typeParameterNodes = index === (chain.length - 1) ? overrideTypeArguments : lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    var parent = chain[index - 1];
                    var symbolName;
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                        symbolName = getNameOfSymbolAsWritten(symbol, context);
                        context.approximateLength += (symbolName ? symbolName.length : 0) + 1;
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    else {
                        if (parent && getExportsOfSymbol(parent)) {
                            var exports_1 = getExportsOfSymbol(parent);
                            ts.forEachEntry(exports_1, function (ex, name) {
                                if (getSymbolIfSameReference(ex, symbol) && !isLateBoundName(name) && name !== "export=" /* ExportEquals */) {
                                    symbolName = ts.unescapeLeadingUnderscores(name);
                                    return true;
                                }
                            });
                        }
                    }
                    if (!symbolName) {
                        symbolName = getNameOfSymbolAsWritten(symbol, context);
                    }
                    context.approximateLength += symbolName.length + 1;
                    if (!(context.flags & 16 /* ForbidIndexedAccessSymbolReferences */) && parent &&
                        getMembersOfSymbol(parent) && getMembersOfSymbol(parent).get(symbol.escapedName) &&
                        getSymbolIfSameReference(getMembersOfSymbol(parent).get(symbol.escapedName), symbol)) {
                        // Should use an indexed access
                        var LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
                        if (ts.isIndexedAccessTypeNode(LHS)) {
                            return ts.createIndexedAccessTypeNode(LHS, ts.createLiteralTypeNode(ts.createLiteral(symbolName)));
                        }
                        else {
                            return ts.createIndexedAccessTypeNode(ts.createTypeReferenceNode(LHS, typeParameterNodes), ts.createLiteralTypeNode(ts.createLiteral(symbolName)));
                        }
                    }
                    var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                    identifier.symbol = symbol;
                    if (index > stopper) {
                        var LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
                        if (!ts.isEntityName(LHS)) {
                            return ts.Debug.fail("Impossible construct - an export of an indexed access cannot be reachable");
                        }
                        return ts.createQualifiedName(LHS, identifier);
                    }
                    return identifier;
                }
            }
            function typeParameterShadowsNameInScope(escapedName, context, type) {
                var result = resolveName(context.enclosingDeclaration, escapedName, 788968 /* Type */, /*nameNotFoundArg*/ undefined, escapedName, /*isUse*/ false);
                if (result) {
                    if (result.flags & 262144 /* TypeParameter */ && result === type.symbol) {
                        return false;
                    }
                    return true;
                }
                return false;
            }
            function typeParameterToName(type, context) {
                if (context.flags & 4 /* GenerateNamesForShadowedTypeParams */ && context.typeParameterNames) {
                    var cached = context.typeParameterNames.get("" + getTypeId(type));
                    if (cached) {
                        return cached;
                    }
                }
                var result = symbolToName(type.symbol, context, 788968 /* Type */, /*expectsIdentifier*/ true);
                if (!(result.kind & 75 /* Identifier */)) {
                    return ts.createIdentifier("(Missing type parameter)");
                }
                if (context.flags & 4 /* GenerateNamesForShadowedTypeParams */) {
                    var rawtext = result.escapedText;
                    var i = 0;
                    var text = rawtext;
                    while ((context.typeParameterNamesByText && context.typeParameterNamesByText.get(text)) || typeParameterShadowsNameInScope(text, context, type)) {
                        i++;
                        text = rawtext + "_" + i;
                    }
                    if (text !== rawtext) {
                        result = ts.createIdentifier(text, result.typeArguments);
                    }
                    (context.typeParameterNames || (context.typeParameterNames = ts.createMap())).set("" + getTypeId(type), result);
                    (context.typeParameterNamesByText || (context.typeParameterNamesByText = ts.createMap())).set(result.escapedText, true);
                }
                return result;
            }
            function symbolToName(symbol, context, meaning, expectsIdentifier) {
                var chain = lookupSymbolChain(symbol, context, meaning);
                if (expectsIdentifier && chain.length !== 1
                    && !context.encounteredError
                    && !(context.flags & 65536 /* AllowQualifedNameInPlaceOfIdentifier */)) {
                    context.encounteredError = true;
                }
                return createEntityNameFromSymbolChain(chain, chain.length - 1);
                function createEntityNameFromSymbolChain(chain, index) {
                    var typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                    }
                    var symbolName = getNameOfSymbolAsWritten(symbol, context);
                    if (index === 0) {
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                    identifier.symbol = symbol;
                    return index > 0 ? ts.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
                }
            }
            function symbolToExpression(symbol, context, meaning) {
                var chain = lookupSymbolChain(symbol, context, meaning);
                return createExpressionFromSymbolChain(chain, chain.length - 1);
                function createExpressionFromSymbolChain(chain, index) {
                    var typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
                    var symbol = chain[index];
                    if (index === 0) {
                        context.flags |= 16777216 /* InInitialEntityName */;
                    }
                    var symbolName = getNameOfSymbolAsWritten(symbol, context);
                    if (index === 0) {
                        context.flags ^= 16777216 /* InInitialEntityName */;
                    }
                    var firstChar = symbolName.charCodeAt(0);
                    if (ts.isSingleOrDoubleQuote(firstChar) && ts.some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)) {
                        return ts.createLiteral(getSpecifierForModuleSymbol(symbol, context));
                    }
                    var canUsePropertyAccess = firstChar === 35 /* hash */ ?
                        symbolName.length > 1 && ts.isIdentifierStart(symbolName.charCodeAt(1), languageVersion) :
                        ts.isIdentifierStart(firstChar, languageVersion);
                    if (index === 0 || canUsePropertyAccess) {
                        var identifier = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                        identifier.symbol = symbol;
                        return index > 0 ? ts.createPropertyAccess(createExpressionFromSymbolChain(chain, index - 1), identifier) : identifier;
                    }
                    else {
                        if (firstChar === 91 /* openBracket */) {
                            symbolName = symbolName.substring(1, symbolName.length - 1);
                            firstChar = symbolName.charCodeAt(0);
                        }
                        var expression = void 0;
                        if (ts.isSingleOrDoubleQuote(firstChar)) {
                            expression = ts.createLiteral(symbolName.substring(1, symbolName.length - 1).replace(/\\./g, function (s) { return s.substring(1); }));
                            expression.singleQuote = firstChar === 39 /* singleQuote */;
                        }
                        else if (("" + +symbolName) === symbolName) {
                            expression = ts.createLiteral(+symbolName);
                        }
                        if (!expression) {
                            expression = ts.setEmitFlags(ts.createIdentifier(symbolName, typeParameterNodes), 16777216 /* NoAsciiEscaping */);
                            expression.symbol = symbol;
                        }
                        return ts.createElementAccess(createExpressionFromSymbolChain(chain, index - 1), expression);
                    }
                }
            }
            function isSingleQuotedStringNamed(d) {
                var name = ts.getNameOfDeclaration(d);
                if (name && ts.isStringLiteral(name) && (name.singleQuote ||
                    (!ts.nodeIsSynthesized(name) && ts.startsWith(ts.getTextOfNode(name, /*includeTrivia*/ false), "'")))) {
                    return true;
                }
                return false;
            }
            function getPropertyNameNodeForSymbol(symbol, context) {
                var singleQuote = !!ts.length(symbol.declarations) && ts.every(symbol.declarations, isSingleQuotedStringNamed);
                var fromNameType = getPropertyNameNodeForSymbolFromNameType(symbol, context, singleQuote);
                if (fromNameType) {
                    return fromNameType;
                }
                if (ts.isKnownSymbol(symbol)) {
                    return ts.createComputedPropertyName(ts.createPropertyAccess(ts.createIdentifier("Symbol"), symbol.escapedName.substr(3)));
                }
                var rawName = ts.unescapeLeadingUnderscores(symbol.escapedName);
                return createPropertyNameNodeForIdentifierOrLiteral(rawName, singleQuote);
            }
            // See getNameForSymbolFromNameType for a stringy equivalent
            function getPropertyNameNodeForSymbolFromNameType(symbol, context, singleQuote) {
                var nameType = getSymbolLinks(symbol).nameType;
                if (nameType) {
                    if (nameType.flags & 384 /* StringOrNumberLiteral */) {
                        var name = "" + nameType.value;
                        if (!ts.isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) {
                            return ts.createLiteral(name, !!singleQuote);
                        }
                        if (isNumericLiteralName(name) && ts.startsWith(name, "-")) {
                            return ts.createComputedPropertyName(ts.createLiteral(+name));
                        }
                        return createPropertyNameNodeForIdentifierOrLiteral(name);
                    }
                    if (nameType.flags & 8192 /* UniqueESSymbol */) {
                        return ts.createComputedPropertyName(symbolToExpression(nameType.symbol, context, 111551 /* Value */));
                    }
                }
            }
            function createPropertyNameNodeForIdentifierOrLiteral(name, singleQuote) {
                return ts.isIdentifierText(name, compilerOptions.target) ? ts.createIdentifier(name) : ts.createLiteral(isNumericLiteralName(name) && +name >= 0 ? +name : name, !!singleQuote);
            }
            function cloneNodeBuilderContext(context) {
                var initial = __assign({}, context);
                // Make type parameters created within this context not consume the name outside this context
                // The symbol serializer ends up creating many sibling scopes that all need "separate" contexts when
                // it comes to naming things - within a normal `typeToTypeNode` call, the node builder only ever descends
                // through the type tree, so the only cases where we could have used distinct sibling scopes was when there
                // were multiple generic overloads with similar generated type parameter names
                // The effect:
                // When we write out
                // export const x: <T>(x: T) => T
                // export const y: <T>(x: T) => T
                // we write it out like that, rather than as
                // export const x: <T>(x: T) => T
                // export const y: <T_1>(x: T_1) => T_1
                if (initial.typeParameterNames) {
                    initial.typeParameterNames = ts.cloneMap(initial.typeParameterNames);
                }
                if (initial.typeParameterNamesByText) {
                    initial.typeParameterNamesByText = ts.cloneMap(initial.typeParameterNamesByText);
                }
                if (initial.typeParameterSymbolList) {
                    initial.typeParameterSymbolList = ts.cloneMap(initial.typeParameterSymbolList);
                }
                return initial;
            }
            function getDeclarationWithTypeAnnotation(symbol, enclosingDeclaration) {
                return symbol.declarations && ts.find(symbol.declarations, function (s) { return !!ts.getEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!ts.findAncestor(s, function (n) { return n === enclosingDeclaration; })); });
            }
            function existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type) {
                return !(ts.getObjectFlags(type) & 4 /* Reference */) || !ts.isTypeReferenceNode(existing) || ts.length(existing.typeArguments) >= getMinTypeArgumentCount(type.target.typeParameters);
            }
            /**
             * Unlike `typeToTypeNodeHelper`, this handles setting up the `AllowUniqueESSymbolType` flag
             * so a `unique symbol` is returned when appropriate for the input symbol, rather than `typeof sym`
             */
            function serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled) {
                if (type !== errorType && enclosingDeclaration) {
                    var declWithExistingAnnotation = getDeclarationWithTypeAnnotation(symbol, enclosingDeclaration);
                    if (declWithExistingAnnotation && !ts.isFunctionLikeDeclaration(declWithExistingAnnotation)) {
                        // try to reuse the existing annotation
                        var existing = ts.getEffectiveTypeAnnotationNode(declWithExistingAnnotation);
                        if (getTypeFromTypeNode(existing) === type && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)) {
                            var result_4 = serializeExistingTypeNode(context, existing, includePrivateSymbol, bundled);
                            if (result_4) {
                                return result_4;
                            }
                        }
                    }
                }
                var oldFlags = context.flags;
                if (type.flags & 8192 /* UniqueESSymbol */ &&
                    type.symbol === symbol) {
                    context.flags |= 1048576 /* AllowUniqueESSymbolType */;
                }
                var result = typeToTypeNodeHelper(type, context);
                context.flags = oldFlags;
                return result;
            }
            function serializeReturnTypeForSignature(context, type, signature, includePrivateSymbol, bundled) {
                if (type !== errorType && context.enclosingDeclaration) {
                    var annotation = signature.declaration && ts.getEffectiveReturnTypeNode(signature.declaration);
                    if (!!ts.findAncestor(annotation, function (n) { return n === context.enclosingDeclaration; }) && annotation && instantiateType(getTypeFromTypeNode(annotation), signature.mapper) === type && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(annotation, type)) {
                        var result = serializeExistingTypeNode(context, annotation, includePrivateSymbol, bundled);
                        if (result) {
                            return result;
                        }
                    }
                }
                return typeToTypeNodeHelper(type, context);
            }
            function serializeExistingTypeNode(context, existing, includePrivateSymbol, bundled) {
                if (cancellationToken && cancellationToken.throwIfCancellationRequested) {
                    cancellationToken.throwIfCancellationRequested();
                }
                var hadError = false;
                var transformed = ts.visitNode(existing, visitExistingNodeTreeSymbols);
                if (hadError) {
                    return undefined;
                }
                return transformed === existing ? ts.getMutableClone(existing) : transformed;
                function visitExistingNodeTreeSymbols(node) {
                    var _a, _b;
                    // We don't _actually_ support jsdoc namepath types, emit `any` instead
                    if (ts.isJSDocAllType(node) || node.kind === 302 /* JSDocNamepathType */) {
                        return ts.createKeywordTypeNode(125 /* AnyKeyword */);
                    }
                    if (ts.isJSDocUnknownType(node)) {
                        return ts.createKeywordTypeNode(148 /* UnknownKeyword */);
                    }
                    if (ts.isJSDocNullableType(node)) {
                        return ts.createUnionTypeNode([ts.visitNode(node.type, visitExistingNodeTreeSymbols), ts.createKeywordTypeNode(100 /* NullKeyword */)]);
                    }
                    if (ts.isJSDocOptionalType(node)) {
                        return ts.createUnionTypeNode([ts.visitNode(node.type, visitExistingNodeTreeSymbols), ts.createKeywordTypeNode(146 /* UndefinedKeyword */)]);
                    }
                    if (ts.isJSDocNonNullableType(node)) {
                        return ts.visitNode(node.type, visitExistingNodeTreeSymbols);
                    }
                    if (ts.isJSDocVariadicType(node)) {
                        return ts.createArrayTypeNode(ts.visitNode(node.type, visitExistingNodeTreeSymbols));
                    }
                    if (ts.isJSDocTypeLiteral(node)) {
                        return ts.createTypeLiteralNode(ts.map(node.jsDocPropertyTags, function (t) {
                            var name = ts.isIdentifier(t.name) ? t.name : t.name.right;
                            var typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(node), name.escapedText);
                            var overrideTypeNode = typeViaParent && t.typeExpression && getTypeFromTypeNode(t.typeExpression.type) !== typeViaParent ? typeToTypeNodeHelper(typeViaParent, context) : undefined;
                            return ts.createPropertySignature(
                            /*modifiers*/ undefined, name, t.typeExpression && ts.isJSDocOptionalType(t.typeExpression.type) ? ts.createToken(57 /* QuestionToken */) : undefined, overrideTypeNode || (t.typeExpression && ts.visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || ts.createKeywordTypeNode(125 /* AnyKeyword */), 
                            /*initializer*/ undefined);
                        }));
                    }
                    if (ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "") {
                        return ts.setOriginalNode(ts.createKeywordTypeNode(125 /* AnyKeyword */), node);
                    }
                    if ((ts.isExpressionWithTypeArguments(node) || ts.isTypeReferenceNode(node)) && ts.isJSDocIndexSignature(node)) {
                        return ts.createTypeLiteralNode([ts.createIndexSignature(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, [ts.createParameter(
                                /*decorators*/ undefined, 
                                /*modifiers*/ undefined, 
                                /*dotdotdotToken*/ undefined, "x", 
                                /*questionToken*/ undefined, ts.visitNode(node.typeArguments[0], visitExistingNodeTreeSymbols))], ts.visitNode(node.typeArguments[1], visitExistingNodeTreeSymbols))]);
                    }
                    if (ts.isJSDocFunctionType(node)) {
                        if (ts.isJSDocConstructSignature(node)) {
                            var newTypeNode_1;
                            return ts.createConstructorTypeNode(ts.visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), ts.mapDefined(node.parameters, function (p, i) { return p.name && ts.isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode_1 = p.type, undefined) : ts.createParameter(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), p.name || getEffectiveDotDotDotForParameter(p) ? "args" : "arg" + i, p.questionToken, ts.visitNode(p.type, visitExistingNodeTreeSymbols), 
                            /*initializer*/ undefined); }), ts.visitNode(newTypeNode_1 || node.type, visitExistingNodeTreeSymbols));
                        }
                        else {
                            return ts.createFunctionTypeNode(ts.visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), ts.map(node.parameters, function (p, i) { return ts.createParameter(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), p.name || getEffectiveDotDotDotForParameter(p) ? "args" : "arg" + i, p.questionToken, ts.visitNode(p.type, visitExistingNodeTreeSymbols), 
                            /*initializer*/ undefined); }), ts.visitNode(node.type, visitExistingNodeTreeSymbols));
                        }
                    }
                    if (ts.isTypeReferenceNode(node) && ts.isInJSDoc(node) && (getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(getTypeReferenceName(node), 788968 /* Type */, /*ignoreErrors*/ true))) {
                        return ts.setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node);
                    }
                    if (ts.isLiteralImportTypeNode(node)) {
                        return ts.updateImportTypeNode(node, ts.updateLiteralTypeNode(node.argument, rewriteModuleSpecifier(node, node.argument.literal)), node.qualifier, ts.visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, ts.isTypeNode), node.isTypeOf);
                    }
                    if (ts.isEntityName(node) || ts.isEntityNameExpression(node)) {
                        var leftmost = ts.getFirstIdentifier(node);
                        if (ts.isInJSFile(node) && (ts.isExportsIdentifier(leftmost) || ts.isModuleExportsAccessExpression(leftmost.parent) || (ts.isQualifiedName(leftmost.parent) && ts.isModuleIdentifier(leftmost.parent.left) && ts.isExportsIdentifier(leftmost.parent.right)))) {
                            hadError = true;
                            return node;
                        }
                        var sym = resolveEntityName(leftmost, 67108863 /* All */, /*ignoreErrors*/ true, /*dontResolveALias*/ true);
                        if (sym) {
                            if (isSymbolAccessible(sym, context.enclosingDeclaration, 67108863 /* All */, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== 0 /* Accessible */) {
                                hadError = true;
                            }
                            else {
                                (_b = (_a = context.tracker) === null || _a === void 0 ? void 0 : _a.trackSymbol) === null || _b === void 0 ? void 0 : _b.call(_a, sym, context.enclosingDeclaration, 67108863 /* All */);
                                includePrivateSymbol === null || includePrivateSymbol === void 0 ? void 0 : includePrivateSymbol(sym);
                            }
                            if (ts.isIdentifier(node)) {
                                var name = sym.flags & 262144 /* TypeParameter */ ? typeParameterToName(getDeclaredTypeOfSymbol(sym), context) : ts.getMutableClone(node);
                                name.symbol = sym; // for quickinfo, which uses identifier symbol information
                                return ts.setEmitFlags(ts.setOriginalNode(name, node), 16777216 /* NoAsciiEscaping */);
                            }
                        }
                    }
                    return ts.visitEachChild(node, visitExistingNodeTreeSymbols, ts.nullTransformationContext);
                    function getEffectiveDotDotDotForParameter(p) {
                        return p.dotDotDotToken || (p.type && ts.isJSDocVariadicType(p.type) ? ts.createToken(25 /* DotDotDotToken */) : undefined);
                    }
                    function rewriteModuleSpecifier(parent, lit) {
                        if (bundled) {
                            if (context.tracker && context.tracker.moduleResolverHost) {
                                var targetFile = getExternalModuleFileFromDeclaration(parent);
                                if (targetFile) {
                                    var getCanonicalFileName = ts.createGetCanonicalFileName(!!host.useCaseSensitiveFileNames);
                                    var resolverHost = {
                                        getCanonicalFileName: getCanonicalFileName,
                                        getCurrentDirectory: function () { return context.tracker.moduleResolverHost.getCurrentDirectory(); },
                                        getCommonSourceDirectory: function () { return context.tracker.moduleResolverHost.getCommonSourceDirectory(); }
                                    };
                                    var newName = ts.getResolvedExternalModuleName(resolverHost, targetFile);
                                    return ts.createLiteral(newName);
                                }
                            }
                        }
                        else {
                            if (context.tracker && context.tracker.trackExternalModuleSymbolOfImportTypeNode) {
                                var moduleSym = resolveExternalModuleNameWorker(lit, lit, /*moduleNotFoundError*/ undefined);
                                if (moduleSym) {
                                    context.tracker.trackExternalModuleSymbolOfImportTypeNode(moduleSym);
                                }
                            }
                        }
                        return lit;
                    }
                }
            }
            function symbolTableToDeclarationStatements(symbolTable, context, bundled) {
                var serializePropertySymbolForClass = makeSerializePropertySymbol(ts.createProperty, 161 /* MethodDeclaration */, /*useAcessors*/ true);
                var serializePropertySymbolForInterfaceWorker = makeSerializePropertySymbol(function (_decorators, mods, name, question, type, initializer) { return ts.createPropertySignature(mods, name, question, type, initializer); }, 160 /* MethodSignature */, /*useAcessors*/ false);
                // TODO: Use `setOriginalNode` on original declaration names where possible so these declarations see some kind of
                // declaration mapping
                // We save the enclosing declaration off here so it's not adjusted by well-meaning declaration
                // emit codepaths which want to apply more specific contexts (so we can still refer to the root real declaration
                // we're trying to emit from later on)
                var enclosingDeclaration = context.enclosingDeclaration;
                var results = [];
                var visitedSymbols = ts.createMap();
                var deferredPrivates;
                var oldcontext = context;
                context = __assign(__assign({}, oldcontext), { usedSymbolNames: ts.createMap(), remappedSymbolNames: ts.createMap(), tracker: __assign(__assign({}, oldcontext.tracker), { trackSymbol: function (sym, decl, meaning) {
                            var accessibleResult = isSymbolAccessible(sym, decl, meaning, /*computeALiases*/ false);
                            if (accessibleResult.accessibility === 0 /* Accessible */) {
                                // Lookup the root symbol of the chain of refs we'll use to access it and serialize it
                                var chain = lookupSymbolChainWorker(sym, context, meaning);
                                if (!(sym.flags & 4 /* Property */)) {
                                    includePrivateSymbol(chain[0]);
                                }
                            }
                            else if (oldcontext.tracker && oldcontext.tracker.trackSymbol) {
                                oldcontext.tracker.trackSymbol(sym, decl, meaning);
                            }
                        } }) });
                if (oldcontext.usedSymbolNames) {
                    oldcontext.usedSymbolNames.forEach(function (_, name) {
                        context.usedSymbolNames.set(name, true);
                    });
                }
                ts.forEachEntry(symbolTable, function (symbol, name) {
                    var baseName = ts.unescapeLeadingUnderscores(name);
                    void getInternalSymbolName(symbol, baseName); // Called to cache values into `usedSymbolNames` and `remappedSymbolNames`
                });
                var addingDeclare = !bundled;
                var exportEquals = symbolTable.get("export=" /* ExportEquals */);
                if (exportEquals && symbolTable.size > 1 && exportEquals.flags & 2097152 /* Alias */) {
                    symbolTable = ts.createSymbolTable();
                    // Remove extraneous elements from root symbol table (they'll be mixed back in when the target of the `export=` is looked up)
                    symbolTable.set("export=" /* ExportEquals */, exportEquals);
                }
                visitSymbolTable(symbolTable);
                return mergeRedundantStatements(results);
                function isIdentifierAndNotUndefined(node) {
                    return !!node && node.kind === 75 /* Identifier */;
                }
                function getNamesOfDeclaration(statement) {
                    if (ts.isVariableStatement(statement)) {
                        return ts.filter(ts.map(statement.declarationList.declarations, ts.getNameOfDeclaration), isIdentifierAndNotUndefined);
                    }
                    return ts.filter([ts.getNameOfDeclaration(statement)], isIdentifierAndNotUndefined);
                }
                function flattenExportAssignedNamespace(statements) {
                    var exportAssignment = ts.find(statements, ts.isExportAssignment);
                    var ns = ts.find(statements, ts.isModuleDeclaration);
                    if (ns && exportAssignment && exportAssignment.isExportEquals &&
                        ts.isIdentifier(exportAssignment.expression) && ts.isIdentifier(ns.name) && ts.idText(ns.name) === ts.idText(exportAssignment.expression) &&
                        ns.body && ts.isModuleBlock(ns.body)) {
                        // Pass 0: Correct situations where a module has both an `export = ns` and multiple top-level exports by stripping the export modifiers from
                        //  the top-level exports and exporting them in the targeted ns, as can occur when a js file has both typedefs and `module.export` assignments
                        var excessExports = ts.filter(statements, function (s) { return !!(ts.getModifierFlags(s) & 1 /* Export */); });
                        if (ts.length(excessExports)) {
                            ns.body.statements = ts.createNodeArray(__spreadArrays(ns.body.statements, [ts.createExportDeclaration(
                                /*decorators*/ undefined, 
                                /*modifiers*/ undefined, ts.createNamedExports(ts.map(ts.flatMap(excessExports, function (e) { return getNamesOfDeclaration(e); }), function (id) { return ts.createExportSpecifier(/*alias*/ undefined, id); })), 
                                /*moduleSpecifier*/ undefined)]));
                        }
                        // Pass 1: Flatten `export namespace _exports {} export = _exports;` so long as the `export=` only points at a single namespace declaration
                        if (!ts.find(statements, function (s) { return s !== ns && ts.nodeHasName(s, ns.name); })) {
                            results = [];
                            ts.forEach(ns.body.statements, function (s) {
                                addResult(s, 0 /* None */); // Recalculates the ambient (and export, if applicable from above) flag
                            });
                            statements = __spreadArrays(ts.filter(statements, function (s) { return s !== ns && s !== exportAssignment; }), results);
                        }
                    }
                    return statements;
                }
                function mergeExportDeclarations(statements) {
                    // Pass 2: Combine all `export {}` declarations
                    var exports = ts.filter(statements, function (d) { return ts.isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause && ts.isNamedExports(d.exportClause); });
                    if (ts.length(exports) > 1) {
                        var nonExports = ts.filter(statements, function (d) { return !ts.isExportDeclaration(d) || !!d.moduleSpecifier || !d.exportClause; });
                        statements = __spreadArrays(nonExports, [ts.createExportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createNamedExports(ts.flatMap(exports, function (e) { return ts.cast(e.exportClause, ts.isNamedExports).elements; })), 
                            /*moduleSpecifier*/ undefined)]);
                    }
                    // Pass 2b: Also combine all `export {} from "..."` declarations as needed
                    var reexports = ts.filter(statements, function (d) { return ts.isExportDeclaration(d) && !!d.moduleSpecifier && !!d.exportClause && ts.isNamedExports(d.exportClause); });
                    if (ts.length(reexports) > 1) {
                        var groups = ts.group(reexports, function (decl) { return ts.isStringLiteral(decl.moduleSpecifier) ? ">" + decl.moduleSpecifier.text : ">"; });
                        if (groups.length !== reexports.length) {
                            var _loop_8 = function (group_1) {
                                if (group_1.length > 1) {
                                    // remove group members from statements and then merge group members and add back to statements
                                    statements = __spreadArrays(ts.filter(statements, function (s) { return group_1.indexOf(s) === -1; }), [
                                        ts.createExportDeclaration(
                                        /*decorators*/ undefined, 
                                        /*modifiers*/ undefined, ts.createNamedExports(ts.flatMap(group_1, function (e) { return ts.cast(e.exportClause, ts.isNamedExports).elements; })), group_1[0].moduleSpecifier)
                                    ]);
                                }
                            };
                            for (var _i = 0, groups_1 = groups; _i < groups_1.length; _i++) {
                                var group_1 = groups_1[_i];
                                _loop_8(group_1);
                            }
                        }
                    }
                    return statements;
                }
                function inlineExportModifiers(statements) {
                    // Pass 3: Move all `export {}`'s to `export` modifiers where possible
                    var exportDecl = ts.find(statements, function (d) { return ts.isExportDeclaration(d) && !d.moduleSpecifier && !!d.exportClause; });
                    if (exportDecl && exportDecl.exportClause && ts.isNamedExports(exportDecl.exportClause)) {
                        var replacements = ts.mapDefined(exportDecl.exportClause.elements, function (e) {
                            if (!e.propertyName) {
                                // export {name} - look thru `statements` for `name`, and if all results can take an `export` modifier, do so and filter it
                                var associated = ts.filter(statements, function (s) { return ts.nodeHasName(s, e.name); });
                                if (ts.length(associated) && ts.every(associated, canHaveExportModifier)) {
                                    ts.forEach(associated, addExportModifier);
                                    return undefined;
                                }
                            }
                            return e;
                        });
                        if (!ts.length(replacements)) {
                            // all clauses removed, filter the export declaration
                            statements = ts.filter(statements, function (s) { return s !== exportDecl; });
                        }
                        else {
                            // some items filtered, others not - update the export declaration
                            // (mutating because why not, we're building a whole new tree here anyway)
                            exportDecl.exportClause.elements = ts.createNodeArray(replacements);
                        }
                    }
                    return statements;
                }
                function mergeRedundantStatements(statements) {
                    statements = flattenExportAssignedNamespace(statements);
                    statements = mergeExportDeclarations(statements);
                    statements = inlineExportModifiers(statements);
                    // Not a cleanup, but as a final step: If there is a mix of `export` and non-`export` declarations, but no `export =` or `export {}` add a `export {};` so
                    // declaration privacy is respected.
                    if (enclosingDeclaration &&
                        ((ts.isSourceFile(enclosingDeclaration) && ts.isExternalOrCommonJsModule(enclosingDeclaration)) || ts.isModuleDeclaration(enclosingDeclaration)) &&
                        (!ts.some(statements, ts.isExternalModuleIndicator) || (!ts.hasScopeMarker(statements) && ts.some(statements, ts.needsScopeMarker)))) {
                        statements.push(ts.createEmptyExports());
                    }
                    return statements;
                }
                function canHaveExportModifier(node) {
                    return ts.isEnumDeclaration(node) ||
                        ts.isVariableStatement(node) ||
                        ts.isFunctionDeclaration(node) ||
                        ts.isClassDeclaration(node) ||
                        (ts.isModuleDeclaration(node) && !ts.isExternalModuleAugmentation(node) && !ts.isGlobalScopeAugmentation(node)) ||
                        ts.isInterfaceDeclaration(node) ||
                        isTypeDeclaration(node);
                }
                function addExportModifier(statement) {
                    var flags = (ts.getModifierFlags(statement) | 1 /* Export */) & ~2 /* Ambient */;
                    statement.modifiers = ts.createNodeArray(ts.createModifiersFromModifierFlags(flags));
                    statement.modifierFlagsCache = 0;
                }
                function visitSymbolTable(symbolTable, suppressNewPrivateContext, propertyAsAlias) {
                    var oldDeferredPrivates = deferredPrivates;
                    if (!suppressNewPrivateContext) {
                        deferredPrivates = ts.createMap();
                    }
                    symbolTable.forEach(function (symbol) {
                        serializeSymbol(symbol, /*isPrivate*/ false, !!propertyAsAlias);
                    });
                    if (!suppressNewPrivateContext) {
                        // deferredPrivates will be filled up by visiting the symbol table
                        // And will continue to iterate as elements are added while visited `deferredPrivates`
                        // (As that's how a map iterator is defined to work)
                        deferredPrivates.forEach(function (symbol) {
                            serializeSymbol(symbol, /*isPrivate*/ true, !!propertyAsAlias);
                        });
                    }
                    deferredPrivates = oldDeferredPrivates;
                }
                function serializeSymbol(symbol, isPrivate, propertyAsAlias) {
                    // cache visited list based on merged symbol, since we want to use the unmerged top-level symbol, but
                    // still skip reserializing it if we encounter the merged product later on
                    var visitedSym = getMergedSymbol(symbol);
                    if (visitedSymbols.has("" + getSymbolId(visitedSym))) {
                        return; // Already printed
                    }
                    visitedSymbols.set("" + getSymbolId(visitedSym), true);
                    // Only actually serialize symbols within the correct enclosing declaration, otherwise do nothing with the out-of-context symbol
                    var skipMembershipCheck = !isPrivate; // We only call this on exported symbols when we know they're in the correct scope
                    if (skipMembershipCheck || (!!ts.length(symbol.declarations) && ts.some(symbol.declarations, function (d) { return !!ts.findAncestor(d, function (n) { return n === enclosingDeclaration; }); }))) {
                        var oldContext = context;
                        context = cloneNodeBuilderContext(context);
                        var result = serializeSymbolWorker(symbol, isPrivate, propertyAsAlias);
                        context = oldContext;
                        return result;
                    }
                }
                // Synthesize declarations for a symbol - might be an Interface, a Class, a Namespace, a Type, a Variable (const, let, or var), an Alias
                // or a merge of some number of those.
                // An interesting challenge is ensuring that when classes merge with namespaces and interfaces, is keeping
                // each symbol in only one of the representations
                // Also, synthesizing a default export of some kind
                // If it's an alias: emit `export default ref`
                // If it's a property: emit `export default _default` with a `_default` prop
                // If it's a class/interface/function: emit a class/interface/function with a `default` modifier
                // These forms can merge, eg (`export default 12; export default interface A {}`)
                function serializeSymbolWorker(symbol, isPrivate, propertyAsAlias) {
                    var symbolName = ts.unescapeLeadingUnderscores(symbol.escapedName);
                    var isDefault = symbol.escapedName === "default" /* Default */;
                    if (!(context.flags & 131072 /* AllowAnonymousIdentifier */) && ts.isStringANonContextualKeyword(symbolName) && !isDefault) {
                        // Oh no. We cannot use this symbol's name as it's name... It's likely some jsdoc had an invalid name like `export` or `default` :(
                        context.encounteredError = true;
                        // TODO: Issue error via symbol tracker?
                        return; // If we need to emit a private with a keyword name, we're done for, since something else will try to refer to it by that name
                    }
                    var needsPostExportDefault = isDefault && !!(symbol.flags & -113 /* ExportDoesNotSupportDefaultModifier */
                        || (symbol.flags & 16 /* Function */ && ts.length(getPropertiesOfType(getTypeOfSymbol(symbol))))) && !(symbol.flags & 2097152 /* Alias */); // An alias symbol should preclude needing to make an alias ourselves
                    if (needsPostExportDefault) {
                        isPrivate = true;
                    }
                    var modifierFlags = (!isPrivate ? 1 /* Export */ : 0) | (isDefault && !needsPostExportDefault ? 512 /* Default */ : 0);
                    var isConstMergedWithNS = symbol.flags & 1536 /* Module */ &&
                        symbol.flags & (2 /* BlockScopedVariable */ | 1 /* FunctionScopedVariable */ | 4 /* Property */) &&
                        symbol.escapedName !== "export=" /* ExportEquals */;
                    var isConstMergedWithNSPrintableAsSignatureMerge = isConstMergedWithNS && isTypeRepresentableAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol);
                    if (symbol.flags & (16 /* Function */ | 8192 /* Method */) || isConstMergedWithNSPrintableAsSignatureMerge) {
                        serializeAsFunctionNamespaceMerge(getTypeOfSymbol(symbol), symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                    }
                    if (symbol.flags & 524288 /* TypeAlias */) {
                        serializeTypeAlias(symbol, symbolName, modifierFlags);
                    }
                    // Need to skip over export= symbols below - json source files get a single `Property` flagged
                    // symbol of name `export=` which needs to be handled like an alias. It's not great, but it is what it is.
                    if (symbol.flags & (2 /* BlockScopedVariable */ | 1 /* FunctionScopedVariable */ | 4 /* Property */)
                        && symbol.escapedName !== "export=" /* ExportEquals */
                        && !(symbol.flags & 4194304 /* Prototype */)
                        && !(symbol.flags & 32 /* Class */)
                        && !isConstMergedWithNSPrintableAsSignatureMerge) {
                        serializeVariableOrProperty(symbol, symbolName, isPrivate, needsPostExportDefault, propertyAsAlias, modifierFlags);
                    }
                    if (symbol.flags & 384 /* Enum */) {
                        serializeEnum(symbol, symbolName, modifierFlags);
                    }
                    if (symbol.flags & 32 /* Class */) {
                        if (symbol.flags & 4 /* Property */ && ts.isBinaryExpression(symbol.valueDeclaration.parent) && ts.isClassExpression(symbol.valueDeclaration.parent.right)) {
                            // Looks like a `module.exports.Sub = class {}` - if we serialize `symbol` as a class, the result will have no members,
                            // since the classiness is actually from the target of the effective alias the symbol is. yes. A BlockScopedVariable|Class|Property
                            // _really_ acts like an Alias, and none of a BlockScopedVariable, Class, or Property. This is the travesty of JS binding today.
                            serializeAsAlias(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                        }
                        else {
                            serializeAsClass(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                        }
                    }
                    if ((symbol.flags & (512 /* ValueModule */ | 1024 /* NamespaceModule */) && (!isConstMergedWithNS || isTypeOnlyNamespace(symbol))) || isConstMergedWithNSPrintableAsSignatureMerge) {
                        serializeModule(symbol, symbolName, modifierFlags);
                    }
                    if (symbol.flags & 64 /* Interface */) {
                        serializeInterface(symbol, symbolName, modifierFlags);
                    }
                    if (symbol.flags & 2097152 /* Alias */) {
                        serializeAsAlias(symbol, getInternalSymbolName(symbol, symbolName), modifierFlags);
                    }
                    if (symbol.flags & 4 /* Property */ && symbol.escapedName === "export=" /* ExportEquals */) {
                        serializeMaybeAliasAssignment(symbol);
                    }
                    if (symbol.flags & 8388608 /* ExportStar */) {
                        // synthesize export * from "moduleReference"
                        // Straightforward - only one thing to do - make an export declaration
                        for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                            var node = _a[_i];
                            var resolvedModule = resolveExternalModuleName(node, node.moduleSpecifier);
                            if (!resolvedModule)
                                continue;
                            addResult(ts.createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*exportClause*/ undefined, ts.createLiteral(getSpecifierForModuleSymbol(resolvedModule, context))), 0 /* None */);
                        }
                    }
                    if (needsPostExportDefault) {
                        addResult(ts.createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportAssignment*/ false, ts.createIdentifier(getInternalSymbolName(symbol, symbolName))), 0 /* None */);
                    }
                }
                function includePrivateSymbol(symbol) {
                    if (ts.some(symbol.declarations, ts.isParameterDeclaration))
                        return;
                    ts.Debug.assertIsDefined(deferredPrivates);
                    getUnusedName(ts.unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol
                    deferredPrivates.set("" + getSymbolId(symbol), symbol);
                }
                function isExportingScope(enclosingDeclaration) {
                    return ((ts.isSourceFile(enclosingDeclaration) && (ts.isExternalOrCommonJsModule(enclosingDeclaration) || ts.isJsonSourceFile(enclosingDeclaration))) ||
                        (ts.isAmbientModule(enclosingDeclaration) && !ts.isGlobalScopeAugmentation(enclosingDeclaration)));
                }
                // Prepends a `declare` and/or `export` modifier if the context requires it, and then adds `node` to `result` and returns `node`
                // Note: This _mutates_ `node` without using `updateNode` - the assumption being that all nodes should be manufactured fresh by the node builder
                function addResult(node, additionalModifierFlags) {
                    var newModifierFlags = 0 /* None */;
                    if (additionalModifierFlags & 1 /* Export */ &&
                        enclosingDeclaration &&
                        isExportingScope(enclosingDeclaration) &&
                        canHaveExportModifier(node)) {
                        // Classes, namespaces, variables, functions, interfaces, and types should all be `export`ed in a module context if not private
                        newModifierFlags |= 1 /* Export */;
                    }
                    if (addingDeclare && !(newModifierFlags & 1 /* Export */) &&
                        (!enclosingDeclaration || !(enclosingDeclaration.flags & 8388608 /* Ambient */)) &&
                        (ts.isEnumDeclaration(node) || ts.isVariableStatement(node) || ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isModuleDeclaration(node))) {
                        // Classes, namespaces, variables, enums, and functions all need `declare` modifiers to be valid in a declaration file top-level scope
                        newModifierFlags |= 2 /* Ambient */;
                    }
                    if ((additionalModifierFlags & 512 /* Default */) && (ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isFunctionDeclaration(node))) {
                        newModifierFlags |= 512 /* Default */;
                    }
                    if (newModifierFlags) {
                        node.modifiers = ts.createNodeArray(ts.createModifiersFromModifierFlags(newModifierFlags | ts.getModifierFlags(node)));
                        node.modifierFlagsCache = 0; // Reset computed flags cache
                    }
                    results.push(node);
                }
                function serializeTypeAlias(symbol, symbolName, modifierFlags) {
                    var aliasType = getDeclaredTypeOfTypeAlias(symbol);
                    var typeParams = getSymbolLinks(symbol).typeParameters;
                    var typeParamDecls = ts.map(typeParams, function (p) { return typeParameterToDeclaration(p, context); });
                    var jsdocAliasDecl = ts.find(symbol.declarations, ts.isJSDocTypeAlias);
                    var commentText = jsdocAliasDecl ? jsdocAliasDecl.comment || jsdocAliasDecl.parent.comment : undefined;
                    var oldFlags = context.flags;
                    context.flags |= 8388608 /* InTypeAlias */;
                    addResult(ts.setSyntheticLeadingComments(ts.createTypeAliasDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, typeToTypeNodeHelper(aliasType, context)), !commentText ? [] : [{ kind: 3 /* MultiLineCommentTrivia */, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]), modifierFlags);
                    context.flags = oldFlags;
                }
                function serializeInterface(symbol, symbolName, modifierFlags) {
                    var interfaceType = getDeclaredTypeOfClassOrInterface(symbol);
                    var localParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    var typeParamDecls = ts.map(localParams, function (p) { return typeParameterToDeclaration(p, context); });
                    var baseTypes = getBaseTypes(interfaceType);
                    var baseType = ts.length(baseTypes) ? getIntersectionType(baseTypes) : undefined;
                    var members = ts.flatMap(getPropertiesOfType(interfaceType), function (p) { return serializePropertySymbolForInterface(p, baseType); });
                    var callSignatures = serializeSignatures(0 /* Call */, interfaceType, baseType, 165 /* CallSignature */);
                    var constructSignatures = serializeSignatures(1 /* Construct */, interfaceType, baseType, 166 /* ConstructSignature */);
                    var indexSignatures = serializeIndexSignatures(interfaceType, baseType);
                    var heritageClauses = !ts.length(baseTypes) ? undefined : [ts.createHeritageClause(90 /* ExtendsKeyword */, ts.mapDefined(baseTypes, function (b) { return trySerializeAsTypeReference(b); }))];
                    addResult(ts.createInterfaceDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, getInternalSymbolName(symbol, symbolName), typeParamDecls, heritageClauses, __spreadArrays(indexSignatures, constructSignatures, callSignatures, members)), modifierFlags);
                }
                function getNamespaceMembersForSerialization(symbol) {
                    return !symbol.exports ? [] : ts.filter(ts.arrayFrom(symbol.exports.values()), isNamespaceMember);
                }
                function isTypeOnlyNamespace(symbol) {
                    return ts.every(getNamespaceMembersForSerialization(symbol), function (m) { return !(resolveSymbol(m).flags & 111551 /* Value */); });
                }
                function serializeModule(symbol, symbolName, modifierFlags) {
                    var members = getNamespaceMembersForSerialization(symbol);
                    // Split NS members up by declaration - members whose parent symbol is the ns symbol vs those whose is not (but were added in later via merging)
                    var locationMap = ts.arrayToMultiMap(members, function (m) { return m.parent && m.parent === symbol ? "real" : "merged"; });
                    var realMembers = locationMap.get("real") || ts.emptyArray;
                    var mergedMembers = locationMap.get("merged") || ts.emptyArray;
                    // TODO: `suppressNewPrivateContext` is questionable -we need to simply be emitting privates in whatever scope they were declared in, rather
                    // than whatever scope we traverse to them in. That's a bit of a complex rewrite, since we're not _actually_ tracking privates at all in advance,
                    // so we don't even have placeholders to fill in.
                    if (ts.length(realMembers)) {
                        var localName = getInternalSymbolName(symbol, symbolName);
                        serializeAsNamespaceDeclaration(realMembers, localName, modifierFlags, !!(symbol.flags & (16 /* Function */ | 67108864 /* Assignment */)));
                    }
                    if (ts.length(mergedMembers)) {
                        var containingFile_1 = ts.getSourceFileOfNode(context.enclosingDeclaration);
                        var localName = getInternalSymbolName(symbol, symbolName);
                        var nsBody = ts.createModuleBlock([ts.createExportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createNamedExports(ts.mapDefined(ts.filter(mergedMembers, function (n) { return n.escapedName !== "export=" /* ExportEquals */; }), function (s) {
                                var _a, _b;
                                var name = ts.unescapeLeadingUnderscores(s.escapedName);
                                var localName = getInternalSymbolName(s, name);
                                var aliasDecl = s.declarations && getDeclarationOfAliasSymbol(s);
                                if (containingFile_1 && (aliasDecl ? containingFile_1 !== ts.getSourceFileOfNode(aliasDecl) : !ts.some(s.declarations, function (d) { return ts.getSourceFileOfNode(d) === containingFile_1; }))) {
                                    (_b = (_a = context.tracker) === null || _a === void 0 ? void 0 : _a.reportNonlocalAugmentation) === null || _b === void 0 ? void 0 : _b.call(_a, containingFile_1, symbol, s);
                                    return undefined;
                                }
                                var target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true);
                                includePrivateSymbol(target || s);
                                var targetName = target ? getInternalSymbolName(target, ts.unescapeLeadingUnderscores(target.escapedName)) : localName;
                                return ts.createExportSpecifier(name === targetName ? undefined : targetName, name);
                            })))]);
                        addResult(ts.createModuleDeclaration(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, ts.createIdentifier(localName), nsBody, 16 /* Namespace */), 0 /* None */);
                    }
                }
                function serializeEnum(symbol, symbolName, modifierFlags) {
                    addResult(ts.createEnumDeclaration(
                    /*decorators*/ undefined, ts.createModifiersFromModifierFlags(isConstEnumSymbol(symbol) ? 2048 /* Const */ : 0), getInternalSymbolName(symbol, symbolName), ts.map(ts.filter(getPropertiesOfType(getTypeOfSymbol(symbol)), function (p) { return !!(p.flags & 8 /* EnumMember */); }), function (p) {
                        // TODO: Handle computed names
                        // I hate that to get the initialized value we need to walk back to the declarations here; but there's no
                        // other way to get the possible const value of an enum member that I'm aware of, as the value is cached
                        // _on the declaration_, not on the declaration's symbol...
                        var initializedValue = p.declarations && p.declarations[0] && ts.isEnumMember(p.declarations[0]) && getConstantValue(p.declarations[0]);
                        return ts.createEnumMember(ts.unescapeLeadingUnderscores(p.escapedName), initializedValue === undefined ? undefined : ts.createLiteral(initializedValue));
                    })), modifierFlags);
                }
                function serializeVariableOrProperty(symbol, symbolName, isPrivate, needsPostExportDefault, propertyAsAlias, modifierFlags) {
                    if (propertyAsAlias) {
                        serializeMaybeAliasAssignment(symbol);
                    }
                    else {
                        var type = getTypeOfSymbol(symbol);
                        var localName = getInternalSymbolName(symbol, symbolName);
                        if (!(symbol.flags & 16 /* Function */) && isTypeRepresentableAsFunctionNamespaceMerge(type, symbol)) {
                            // If the type looks like a function declaration + ns could represent it, and it's type is sourced locally, rewrite it into a function declaration + ns
                            serializeAsFunctionNamespaceMerge(type, symbol, localName, modifierFlags);
                        }
                        else {
                            // A Class + Property merge is made for a `module.exports.Member = class {}`, and it doesn't serialize well as either a class _or_ a property symbol - in fact, _it behaves like an alias!_
                            // `var` is `FunctionScopedVariable`, `const` and `let` are `BlockScopedVariable`, and `module.exports.thing =` is `Property`
                            var flags = !(symbol.flags & 2 /* BlockScopedVariable */) ? undefined
                                : isConstVariable(symbol) ? 2 /* Const */
                                    : 1 /* Let */;
                            var name = (needsPostExportDefault || !(symbol.flags & 4 /* Property */)) ? localName : getUnusedName(localName, symbol);
                            var textRange = symbol.declarations && ts.find(symbol.declarations, function (d) { return ts.isVariableDeclaration(d); });
                            if (textRange && ts.isVariableDeclarationList(textRange.parent) && textRange.parent.declarations.length === 1) {
                                textRange = textRange.parent.parent;
                            }
                            var statement = ts.setTextRange(ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([
                                ts.createVariableDeclaration(name, serializeTypeForDeclaration(context, type, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
                            ], flags)), textRange);
                            addResult(statement, name !== localName ? modifierFlags & ~1 /* Export */ : modifierFlags);
                            if (name !== localName && !isPrivate) {
                                // We rename the variable declaration we generate for Property symbols since they may have a name which
                                // conflicts with a local declaration. For example, given input:
                                // ```
                                // function g() {}
                                // module.exports.g = g
                                // ```
                                // In such a situation, we have a local variable named `g`, and a separate exported variable named `g`.
                                // Naively, we would emit
                                // ```
                                // function g() {}
                                // export const g: typeof g;
                                // ```
                                // That's obviously incorrect - the `g` in the type annotation needs to refer to the local `g`, but
                                // the export declaration shadows it.
                                // To work around that, we instead write
                                // ```
                                // function g() {}
                                // const g_1: typeof g;
                                // export { g_1 as g };
                                // ```
                                // To create an export named `g` that does _not_ shadow the local `g`
                                addResult(ts.createExportDeclaration(
                                /*decorators*/ undefined, 
                                /*modifiers*/ undefined, ts.createNamedExports([ts.createExportSpecifier(name, localName)])), 0 /* None */);
                            }
                        }
                    }
                }
                function serializeAsFunctionNamespaceMerge(type, symbol, localName, modifierFlags) {
                    var signatures = getSignaturesOfType(type, 0 /* Call */);
                    for (var _i = 0, signatures_2 = signatures; _i < signatures_2.length; _i++) {
                        var sig = signatures_2[_i];
                        // Each overload becomes a separate function declaration, in order
                        var decl = signatureToSignatureDeclarationHelper(sig, 244 /* FunctionDeclaration */, context, includePrivateSymbol, bundled);
                        decl.name = ts.createIdentifier(localName);
                        // for expressions assigned to `var`s, use the `var` as the text range
                        addResult(ts.setTextRange(decl, sig.declaration && ts.isVariableDeclaration(sig.declaration.parent) && sig.declaration.parent.parent || sig.declaration), modifierFlags);
                    }
                    // Module symbol emit will take care of module-y members, provided it has exports
                    if (!(symbol.flags & (512 /* ValueModule */ | 1024 /* NamespaceModule */) && !!symbol.exports && !!symbol.exports.size)) {
                        var props = ts.filter(getPropertiesOfType(type), isNamespaceMember);
                        serializeAsNamespaceDeclaration(props, localName, modifierFlags, /*suppressNewPrivateContext*/ true);
                    }
                }
                function serializeAsNamespaceDeclaration(props, localName, modifierFlags, suppressNewPrivateContext) {
                    if (ts.length(props)) {
                        var localVsRemoteMap = ts.arrayToMultiMap(props, function (p) {
                            return !ts.length(p.declarations) || ts.some(p.declarations, function (d) {
                                return ts.getSourceFileOfNode(d) === ts.getSourceFileOfNode(context.enclosingDeclaration);
                            }) ? "local" : "remote";
                        });
                        var localProps = localVsRemoteMap.get("local") || ts.emptyArray;
                        // handle remote props first - we need to make an `import` declaration that points at the module containing each remote
                        // prop in the outermost scope (TODO: a namespace within a namespace would need to be appropriately handled by this)
                        // Example:
                        // import Foo_1 = require("./exporter");
                        // export namespace ns {
                        //     import Foo = Foo_1.Foo;
                        //     export { Foo };
                        //     export const c: number;
                        // }
                        // This is needed because in JS, statements like `const x = require("./f")` support both type and value lookup, even if they're
                        // normally just value lookup (so it functions kinda like an alias even when it's not an alias)
                        // _Usually_, we'll simply print the top-level as an alias instead of a `var` in such situations, however is is theoretically
                        // possible to encounter a situation where a type has members from both the current file and other files - in those situations,
                        // emit akin to the above would be needed.
                        // Add a namespace
                        var fakespace = ts.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, ts.createIdentifier(localName), ts.createModuleBlock([]), 16 /* Namespace */);
                        fakespace.flags ^= 8 /* Synthesized */; // unset synthesized so it is usable as an enclosing declaration
                        fakespace.parent = enclosingDeclaration;
                        fakespace.locals = ts.createSymbolTable(props);
                        fakespace.symbol = props[0].parent;
                        var oldResults = results;
                        results = [];
                        var oldAddingDeclare = addingDeclare;
                        addingDeclare = false;
                        var subcontext = __assign(__assign({}, context), { enclosingDeclaration: fakespace });
                        var oldContext = context;
                        context = subcontext;
                        // TODO: implement handling for the localVsRemoteMap.get("remote") - should be difficult to trigger (see comment above), as only interesting cross-file js merges should make this possible
                        visitSymbolTable(ts.createSymbolTable(localProps), suppressNewPrivateContext, /*propertyAsAlias*/ true);
                        context = oldContext;
                        addingDeclare = oldAddingDeclare;
                        var declarations = results;
                        results = oldResults;
                        fakespace.flags ^= 8 /* Synthesized */; // reset synthesized
                        fakespace.parent = undefined;
                        fakespace.locals = undefined;
                        fakespace.symbol = undefined;
                        fakespace.body = ts.createModuleBlock(declarations);
                        addResult(fakespace, modifierFlags); // namespaces can never be default exported
                    }
                }
                function isNamespaceMember(p) {
                    return !(p.flags & 4194304 /* Prototype */ || p.escapedName === "prototype" || p.valueDeclaration && ts.isClassLike(p.valueDeclaration.parent));
                }
                function serializeAsClass(symbol, localName, modifierFlags) {
                    var localParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    var typeParamDecls = ts.map(localParams, function (p) { return typeParameterToDeclaration(p, context); });
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    var baseTypes = getBaseTypes(classType);
                    var implementsTypes = getImplementsTypes(classType);
                    var staticType = getTypeOfSymbol(symbol);
                    var staticBaseType = getBaseConstructorTypeOfClass(staticType);
                    var heritageClauses = __spreadArrays(!ts.length(baseTypes) ? [] : [ts.createHeritageClause(90 /* ExtendsKeyword */, ts.map(baseTypes, function (b) { return serializeBaseType(b, staticBaseType, localName); }))], !ts.length(implementsTypes) ? [] : [ts.createHeritageClause(113 /* ImplementsKeyword */, ts.map(implementsTypes, function (b) { return serializeBaseType(b, staticBaseType, localName); }))]);
                    var symbolProps = getNonInterhitedProperties(classType, baseTypes, getPropertiesOfType(classType));
                    var publicSymbolProps = ts.filter(symbolProps, function (s) {
                        // `valueDeclaration` could be undefined if inherited from
                        // a union/intersection base type, but inherited properties
                        // don't matter here.
                        var valueDecl = s.valueDeclaration;
                        return valueDecl && !(ts.isNamedDeclaration(valueDecl) && ts.isPrivateIdentifier(valueDecl.name));
                    });
                    var hasPrivateIdentifier = ts.some(symbolProps, function (s) {
                        // `valueDeclaration` could be undefined if inherited from
                        // a union/intersection base type, but inherited properties
                        // don't matter here.
                        var valueDecl = s.valueDeclaration;
                        return valueDecl && ts.isNamedDeclaration(valueDecl) && ts.isPrivateIdentifier(valueDecl.name);
                    });
                    // Boil down all private properties into a single one.
                    var privateProperties = hasPrivateIdentifier ?
                        [ts.createProperty(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createPrivateIdentifier("#private"), 
                            /*questionOrExclamationToken*/ undefined, 
                            /*type*/ undefined, 
                            /*initializer*/ undefined)] :
                        ts.emptyArray;
                    var publicProperties = ts.flatMap(publicSymbolProps, function (p) { return serializePropertySymbolForClass(p, /*isStatic*/ false, baseTypes[0]); });
                    // Consider static members empty if symbol also has function or module meaning - function namespacey emit will handle statics
                    var staticMembers = ts.flatMap(ts.filter(getPropertiesOfType(staticType), function (p) { return !(p.flags & 4194304 /* Prototype */) && p.escapedName !== "prototype" && !isNamespaceMember(p); }), function (p) { return serializePropertySymbolForClass(p, /*isStatic*/ true, staticBaseType); });
                    var constructors = serializeSignatures(1 /* Construct */, staticType, baseTypes[0], 162 /* Constructor */);
                    for (var _i = 0, constructors_1 = constructors; _i < constructors_1.length; _i++) {
                        var c = constructors_1[_i];
                        // A constructor's return type and type parameters are supposed to be controlled by the enclosing class declaration
                        // `signatureToSignatureDeclarationHelper` appends them regardless, so for now we delete them here
                        c.type = undefined;
                        c.typeParameters = undefined;
                    }
                    var indexSignatures = serializeIndexSignatures(classType, baseTypes[0]);
                    addResult(ts.setTextRange(ts.createClassDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, localName, typeParamDecls, heritageClauses, __spreadArrays(indexSignatures, staticMembers, constructors, publicProperties, privateProperties)), symbol.declarations && ts.filter(symbol.declarations, function (d) { return ts.isClassDeclaration(d) || ts.isClassExpression(d); })[0]), modifierFlags);
                }
                function serializeAsAlias(symbol, localName, modifierFlags) {
                    // synthesize an alias, eg `export { symbolName as Name }`
                    // need to mark the alias `symbol` points at
                    // as something we need to serialize as a private declaration as well
                    var node = getDeclarationOfAliasSymbol(symbol);
                    if (!node)
                        return ts.Debug.fail();
                    var target = getMergedSymbol(getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true));
                    if (!target) {
                        return;
                    }
                    var verbatimTargetName = ts.unescapeLeadingUnderscores(target.escapedName);
                    if (verbatimTargetName === "export=" /* ExportEquals */ && (compilerOptions.esModuleInterop || compilerOptions.allowSyntheticDefaultImports)) {
                        // target refers to an `export=` symbol that was hoisted into a synthetic default - rename here to match
                        verbatimTargetName = "default" /* Default */;
                    }
                    var targetName = getInternalSymbolName(target, verbatimTargetName);
                    includePrivateSymbol(target); // the target may be within the same scope - attempt to serialize it first
                    switch (node.kind) {
                        case 253 /* ImportEqualsDeclaration */:
                            // Could be a local `import localName = ns.member` or
                            // an external `import localName = require("whatever")`
                            var isLocalImport = !(target.flags & 512 /* ValueModule */);
                            addResult(ts.createImportEqualsDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createIdentifier(localName), isLocalImport
                                ? symbolToName(target, context, 67108863 /* All */, /*expectsIdentifier*/ false)
                                : ts.createExternalModuleReference(ts.createLiteral(getSpecifierForModuleSymbol(symbol, context)))), isLocalImport ? modifierFlags : 0 /* None */);
                            break;
                        case 252 /* NamespaceExportDeclaration */:
                            // export as namespace foo
                            // TODO: Not part of a file's local or export symbol tables
                            // Is bound into file.symbol.globalExports instead, which we don't currently traverse
                            addResult(ts.createNamespaceExportDeclaration(ts.idText(node.name)), 0 /* None */);
                            break;
                        case 255 /* ImportClause */:
                            addResult(ts.createImportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createImportClause(ts.createIdentifier(localName), /*namedBindings*/ undefined), 
                            // We use `target.parent || target` below as `target.parent` is unset when the target is a module which has been export assigned
                            // And then made into a default by the `esModuleInterop` or `allowSyntheticDefaultImports` flag
                            // In such cases, the `target` refers to the module itself already
                            ts.createLiteral(getSpecifierForModuleSymbol(target.parent || target, context))), 0 /* None */);
                            break;
                        case 256 /* NamespaceImport */:
                            addResult(ts.createImportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createImportClause(/*importClause*/ undefined, ts.createNamespaceImport(ts.createIdentifier(localName))), ts.createLiteral(getSpecifierForModuleSymbol(target, context))), 0 /* None */);
                            break;
                        case 262 /* NamespaceExport */:
                            addResult(ts.createExportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createNamespaceExport(ts.createIdentifier(localName)), ts.createLiteral(getSpecifierForModuleSymbol(target, context))), 0 /* None */);
                            break;
                        case 258 /* ImportSpecifier */:
                            addResult(ts.createImportDeclaration(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, ts.createImportClause(/*importClause*/ undefined, ts.createNamedImports([
                                ts.createImportSpecifier(localName !== verbatimTargetName ? ts.createIdentifier(verbatimTargetName) : undefined, ts.createIdentifier(localName))
                            ])), ts.createLiteral(getSpecifierForModuleSymbol(target.parent || target, context))), 0 /* None */);
                            break;
                        case 263 /* ExportSpecifier */:
                            // does not use localName because the symbol name in this case refers to the name in the exports table,
                            // which we must exactly preserve
                            var specifier = node.parent.parent.moduleSpecifier;
                            // targetName is only used when the target is local, as otherwise the target is an alias that points at
                            // another file
                            serializeExportSpecifier(ts.unescapeLeadingUnderscores(symbol.escapedName), specifier ? verbatimTargetName : targetName, specifier && ts.isStringLiteralLike(specifier) ? ts.createLiteral(specifier.text) : undefined);
                            break;
                        case 259 /* ExportAssignment */:
                            serializeMaybeAliasAssignment(symbol);
                            break;
                        case 209 /* BinaryExpression */:
                        case 194 /* PropertyAccessExpression */:
                            // Could be best encoded as though an export specifier or as though an export assignment
                            // If name is default or export=, do an export assignment
                            // Otherwise do an export specifier
                            if (symbol.escapedName === "default" /* Default */ || symbol.escapedName === "export=" /* ExportEquals */) {
                                serializeMaybeAliasAssignment(symbol);
                            }
                            else {
                                serializeExportSpecifier(localName, targetName);
                            }
                            break;
                        default:
                            return ts.Debug.failBadSyntaxKind(node, "Unhandled alias declaration kind in symbol serializer!");
                    }
                }
                function serializeExportSpecifier(localName, targetName, specifier) {
                    addResult(ts.createExportDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, ts.createNamedExports([ts.createExportSpecifier(localName !== targetName ? targetName : undefined, localName)]), specifier), 0 /* None */);
                }
                function serializeMaybeAliasAssignment(symbol) {
                    if (symbol.flags & 4194304 /* Prototype */) {
                        return;
                    }
                    var name = ts.unescapeLeadingUnderscores(symbol.escapedName);
                    var isExportEquals = name === "export=" /* ExportEquals */;
                    var isDefault = name === "default" /* Default */;
                    var isExportAssignment = isExportEquals || isDefault;
                    // synthesize export = ref
                    // ref should refer to either be a locally scoped symbol which we need to emit, or
                    // a reference to another namespace/module which we may need to emit an `import` statement for
                    var aliasDecl = symbol.declarations && getDeclarationOfAliasSymbol(symbol);
                    // serialize what the alias points to, preserve the declaration's initializer
                    var target = aliasDecl && getTargetOfAliasDeclaration(aliasDecl, /*dontRecursivelyResolve*/ true);
                    // If the target resolves and resolves to a thing defined in this file, emit as an alias, otherwise emit as a const
                    if (target && ts.length(target.declarations) && ts.some(target.declarations, function (d) { return ts.getSourceFileOfNode(d) === ts.getSourceFileOfNode(enclosingDeclaration); })) {
                        // In case `target` refers to a namespace member, look at the declaration and serialize the leftmost symbol in it
                        // eg, `namespace A { export class B {} }; exports = A.B;`
                        // Technically, this is all that's required in the case where the assignment is an entity name expression
                        var expr = isExportAssignment ? ts.getExportAssignmentExpression(aliasDecl) : ts.getPropertyAssignmentAliasLikeExpression(aliasDecl);
                        var first_1 = ts.isEntityNameExpression(expr) ? getFirstNonModuleExportsIdentifier(expr) : undefined;
                        var referenced = first_1 && resolveEntityName(first_1, 67108863 /* All */, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, enclosingDeclaration);
                        if (referenced || target) {
                            includePrivateSymbol(referenced || target);
                        }
                        // We disable the context's symbol tracker for the duration of this name serialization
                        // as, by virtue of being here, the name is required to print something, and we don't want to
                        // issue a visibility error on it. Only anonymous classes that an alias points at _would_ issue
                        // a visibility error here (as they're not visible within any scope), but we want to hoist them
                        // into the containing scope anyway, so we want to skip the visibility checks.
                        var oldTrack = context.tracker.trackSymbol;
                        context.tracker.trackSymbol = ts.noop;
                        if (isExportAssignment) {
                            results.push(ts.createExportAssignment(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, isExportEquals, symbolToExpression(target, context, 67108863 /* All */)));
                        }
                        else {
                            if (first_1 === expr) {
                                // serialize as `export {target as name}`
                                serializeExportSpecifier(name, ts.idText(first_1));
                            }
                            else if (ts.isClassExpression(expr)) {
                                serializeExportSpecifier(name, getInternalSymbolName(target, ts.symbolName(target)));
                            }
                            else {
                                // serialize as `import _Ref = t.arg.et; export { _Ref as name }`
                                var varName = getUnusedName(name, symbol);
                                addResult(ts.createImportEqualsDeclaration(
                                /*decorators*/ undefined, 
                                /*modifiers*/ undefined, ts.createIdentifier(varName), symbolToName(target, context, 67108863 /* All */, /*expectsIdentifier*/ false)), 0 /* None */);
                                serializeExportSpecifier(name, varName);
                            }
                        }
                        context.tracker.trackSymbol = oldTrack;
                    }
                    else {
                        // serialize as an anonymous property declaration
                        var varName = getUnusedName(name, symbol);
                        // We have to use `getWidenedType` here since the object within a json file is unwidened within the file
                        // (Unwidened types can only exist in expression contexts and should never be serialized)
                        var typeToSerialize = getWidenedType(getTypeOfSymbol(getMergedSymbol(symbol)));
                        if (isTypeRepresentableAsFunctionNamespaceMerge(typeToSerialize, symbol)) {
                            // If there are no index signatures and `typeToSerialize` is an object type, emit as a namespace instead of a const
                            serializeAsFunctionNamespaceMerge(typeToSerialize, symbol, varName, isExportAssignment ? 0 /* None */ : 1 /* Export */);
                        }
                        else {
                            var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([
                                ts.createVariableDeclaration(varName, serializeTypeForDeclaration(context, typeToSerialize, symbol, enclosingDeclaration, includePrivateSymbol, bundled))
                            ], 2 /* Const */));
                            addResult(statement, name === varName ? 1 /* Export */ : 0 /* None */);
                        }
                        if (isExportAssignment) {
                            results.push(ts.createExportAssignment(
                            /*decorators*/ undefined, 
                            /*modifiers*/ undefined, isExportEquals, ts.createIdentifier(varName)));
                        }
                        else if (name !== varName) {
                            serializeExportSpecifier(name, varName);
                        }
                    }
                }
                function isTypeRepresentableAsFunctionNamespaceMerge(typeToSerialize, hostSymbol) {
                    // Only object types which are not constructable, or indexable, whose members all come from the
                    // context source file, and whose property names are all valid identifiers and not late-bound, _and_
                    // whose input is not type annotated (if the input symbol has an annotation we can reuse, we should prefer it)
                    var ctxSrc = ts.getSourceFileOfNode(context.enclosingDeclaration);
                    return ts.getObjectFlags(typeToSerialize) & (16 /* Anonymous */ | 32 /* Mapped */) &&
                        !getIndexInfoOfType(typeToSerialize, 0 /* String */) &&
                        !getIndexInfoOfType(typeToSerialize, 1 /* Number */) &&
                        !!(ts.length(getPropertiesOfType(typeToSerialize)) || ts.length(getSignaturesOfType(typeToSerialize, 0 /* Call */))) &&
                        !ts.length(getSignaturesOfType(typeToSerialize, 1 /* Construct */)) && // TODO: could probably serialize as function + ns + class, now that that's OK
                        !getDeclarationWithTypeAnnotation(hostSymbol, enclosingDeclaration) &&
                        !(typeToSerialize.symbol && ts.some(typeToSerialize.symbol.declarations, function (d) { return ts.getSourceFileOfNode(d) !== ctxSrc; })) &&
                        !ts.some(getPropertiesOfType(typeToSerialize), function (p) { return isLateBoundName(p.escapedName); }) &&
                        !ts.some(getPropertiesOfType(typeToSerialize), function (p) { return ts.some(p.declarations, function (d) { return ts.getSourceFileOfNode(d) !== ctxSrc; }); }) &&
                        ts.every(getPropertiesOfType(typeToSerialize), function (p) { return ts.isIdentifierText(ts.symbolName(p), languageVersion) && !ts.isStringAKeyword(ts.symbolName(p)); });
                }
                function makeSerializePropertySymbol(createProperty, methodKind, useAccessors) {
                    return function serializePropertySymbol(p, isStatic, baseType) {
                        var modifierFlags = ts.getDeclarationModifierFlagsFromSymbol(p);
                        var isPrivate = !!(modifierFlags & 8 /* Private */);
                        if (isStatic && (p.flags & (788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */))) {
                            // Only value-only-meaning symbols can be correctly encoded as class statics, type/namespace/alias meaning symbols
                            // need to be merged namespace members
                            return [];
                        }
                        if (p.flags & 4194304 /* Prototype */ ||
                            (baseType && getPropertyOfType(baseType, p.escapedName)
                                && isReadonlySymbol(getPropertyOfType(baseType, p.escapedName)) === isReadonlySymbol(p)
                                && (p.flags & 16777216 /* Optional */) === (getPropertyOfType(baseType, p.escapedName).flags & 16777216 /* Optional */)
                                && isTypeIdenticalTo(getTypeOfSymbol(p), getTypeOfPropertyOfType(baseType, p.escapedName)))) {
                            return [];
                        }
                        var flag = (modifierFlags & ~256 /* Async */) | (isStatic ? 32 /* Static */ : 0);
                        var name = getPropertyNameNodeForSymbol(p, context);
                        var firstPropertyLikeDecl = ts.find(p.declarations, ts.or(ts.isPropertyDeclaration, ts.isAccessor, ts.isVariableDeclaration, ts.isPropertySignature, ts.isBinaryExpression, ts.isPropertyAccessExpression));
                        if (p.flags & 98304 /* Accessor */ && useAccessors) {
                            var result = [];
                            if (p.flags & 65536 /* SetAccessor */) {
                                result.push(ts.setTextRange(ts.createSetAccessor(
                                /*decorators*/ undefined, ts.createModifiersFromModifierFlags(flag), name, [ts.createParameter(
                                    /*decorators*/ undefined, 
                                    /*modifiers*/ undefined, 
                                    /*dotDotDotToken*/ undefined, "arg", 
                                    /*questionToken*/ undefined, isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled))], 
                                /*body*/ undefined), ts.find(p.declarations, ts.isSetAccessor) || firstPropertyLikeDecl));
                            }
                            if (p.flags & 32768 /* GetAccessor */) {
                                var isPrivate_1 = modifierFlags & 8 /* Private */;
                                result.push(ts.setTextRange(ts.createGetAccessor(
                                /*decorators*/ undefined, ts.createModifiersFromModifierFlags(flag), name, [], isPrivate_1 ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), 
                                /*body*/ undefined), ts.find(p.declarations, ts.isGetAccessor) || firstPropertyLikeDecl));
                            }
                            return result;
                        }
                        // This is an else/if as accessors and properties can't merge in TS, but might in JS
                        // If this happens, we assume the accessor takes priority, as it imposes more constraints
                        else if (p.flags & (4 /* Property */ | 3 /* Variable */)) {
                            return ts.setTextRange(createProperty(
                            /*decorators*/ undefined, ts.createModifiersFromModifierFlags((isReadonlySymbol(p) ? 64 /* Readonly */ : 0) | flag), name, p.flags & 16777216 /* Optional */ ? ts.createToken(57 /* QuestionToken */) : undefined, isPrivate ? undefined : serializeTypeForDeclaration(context, getTypeOfSymbol(p), p, enclosingDeclaration, includePrivateSymbol, bundled), 
                            // TODO: https://github.com/microsoft/TypeScript/pull/32372#discussion_r328386357
                            // interface members can't have initializers, however class members _can_
                            /*initializer*/ undefined), ts.find(p.declarations, ts.or(ts.isPropertyDeclaration, ts.isVariableDeclaration)) || firstPropertyLikeDecl);
                        }
                        if (p.flags & (8192 /* Method */ | 16 /* Function */)) {
                            var type = getTypeOfSymbol(p);
                            var signatures = getSignaturesOfType(type, 0 /* Call */);
                            if (flag & 8 /* Private */) {
                                return ts.setTextRange(createProperty(
                                /*decorators*/ undefined, ts.createModifiersFromModifierFlags((isReadonlySymbol(p) ? 64 /* Readonly */ : 0) | flag), name, p.flags & 16777216 /* Optional */ ? ts.createToken(57 /* QuestionToken */) : undefined, 
                                /*type*/ undefined, 
                                /*initializer*/ undefined), ts.find(p.declarations, ts.isFunctionLikeDeclaration) || signatures[0] && signatures[0].declaration || p.declarations[0]);
                            }
                            var results_1 = [];
                            for (var _i = 0, signatures_3 = signatures; _i < signatures_3.length; _i++) {
                                var sig = signatures_3[_i];
                                // Each overload becomes a separate method declaration, in order
                                var decl = signatureToSignatureDeclarationHelper(sig, methodKind, context);
                                decl.name = name; // TODO: Clone
                                if (flag) {
                                    decl.modifiers = ts.createNodeArray(ts.createModifiersFromModifierFlags(flag));
                                }
                                if (p.flags & 16777216 /* Optional */) {
                                    decl.questionToken = ts.createToken(57 /* QuestionToken */);
                                }
                                results_1.push(ts.setTextRange(decl, sig.declaration));
                            }
                            return results_1;
                        }
                        // The `Constructor`'s symbol isn't in the class's properties lists, obviously, since it's a signature on the static
                        return ts.Debug.fail("Unhandled class member kind! " + (p.__debugFlags || p.flags));
                    };
                }
                function serializePropertySymbolForInterface(p, baseType) {
                    return serializePropertySymbolForInterfaceWorker(p, /*isStatic*/ false, baseType);
                }
                function serializeSignatures(kind, input, baseType, outputKind) {
                    var signatures = getSignaturesOfType(input, kind);
                    if (kind === 1 /* Construct */) {
                        if (!baseType && ts.every(signatures, function (s) { return ts.length(s.parameters) === 0; })) {
                            return []; // No base type, every constructor is empty - elide the extraneous `constructor()`
                        }
                        if (baseType) {
                            // If there is a base type, if every signature in the class is identical to a signature in the baseType, elide all the declarations
                            var baseSigs = getSignaturesOfType(baseType, 1 /* Construct */);
                            if (!ts.length(baseSigs) && ts.every(signatures, function (s) { return ts.length(s.parameters) === 0; })) {
                                return []; // Base had no explicit signatures, if all our signatures are also implicit, return an empty list
                            }
                            if (baseSigs.length === signatures.length) {
                                var failed = false;
                                for (var i = 0; i < baseSigs.length; i++) {
                                    if (!compareSignaturesIdentical(signatures[i], baseSigs[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
                                        failed = true;
                                        break;
                                    }
                                }
                                if (!failed) {
                                    return []; // Every signature was identical - elide constructor list as it is inherited
                                }
                            }
                        }
                        var privateProtected = 0;
                        for (var _i = 0, signatures_4 = signatures; _i < signatures_4.length; _i++) {
                            var s = signatures_4[_i];
                            if (s.declaration) {
                                privateProtected |= ts.getSelectedModifierFlags(s.declaration, 8 /* Private */ | 16 /* Protected */);
                            }
                        }
                        if (privateProtected) {
                            return [ts.setTextRange(ts.createConstructor(
                                /*decorators*/ undefined, ts.createModifiersFromModifierFlags(privateProtected), 
                                /*parameters*/ [], 
                                /*body*/ undefined), signatures[0].declaration)];
                        }
                    }
                    var results = [];
                    for (var _a = 0, signatures_5 = signatures; _a < signatures_5.length; _a++) {
                        var sig = signatures_5[_a];
                        // Each overload becomes a separate constructor declaration, in order
                        var decl = signatureToSignatureDeclarationHelper(sig, outputKind, context);
                        results.push(ts.setTextRange(decl, sig.declaration));
                    }
                    return results;
                }
                function serializeIndexSignatures(input, baseType) {
                    var results = [];
                    for (var _i = 0, _a = [0 /* String */, 1 /* Number */]; _i < _a.length; _i++) {
                        var type = _a[_i];
                        var info = getIndexInfoOfType(input, type);
                        if (info) {
                            if (baseType) {
                                var baseInfo = getIndexInfoOfType(baseType, type);
                                if (baseInfo) {
                                    if (isTypeIdenticalTo(info.type, baseInfo.type)) {
                                        continue; // elide identical index signatures
                                    }
                                }
                            }
                            results.push(indexInfoToIndexSignatureDeclarationHelper(info, type, context));
                        }
                    }
                    return results;
                }
                function serializeBaseType(t, staticType, rootName) {
                    var ref = trySerializeAsTypeReference(t);
                    if (ref) {
                        return ref;
                    }
                    var tempName = getUnusedName(rootName + "_base");
                    var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(tempName, typeToTypeNodeHelper(staticType, context))
                    ], 2 /* Const */));
                    addResult(statement, 0 /* None */);
                    return ts.createExpressionWithTypeArguments(/*typeArgs*/ undefined, ts.createIdentifier(tempName));
                }
                function trySerializeAsTypeReference(t) {
                    var typeArgs;
                    var reference;
                    // We don't use `isValueSymbolAccessible` below. since that considers alternative containers (like modules)
                    // which we can't write out in a syntactically valid way as an expression
                    if (t.target && getAccessibleSymbolChain(t.target.symbol, enclosingDeclaration, 111551 /* Value */, /*useOnlyExternalAliasing*/ false)) {
                        typeArgs = ts.map(getTypeArguments(t), function (t) { return typeToTypeNodeHelper(t, context); });
                        reference = symbolToExpression(t.target.symbol, context, 788968 /* Type */);
                    }
                    else if (t.symbol && getAccessibleSymbolChain(t.symbol, enclosingDeclaration, 111551 /* Value */, /*useOnlyExternalAliasing*/ false)) {
                        reference = symbolToExpression(t.symbol, context, 788968 /* Type */);
                    }
                    if (reference) {
                        return ts.createExpressionWithTypeArguments(typeArgs, reference);
                    }
                }
                function getUnusedName(input, symbol) {
                    if (symbol) {
                        if (context.remappedSymbolNames.has("" + getSymbolId(symbol))) {
                            return context.remappedSymbolNames.get("" + getSymbolId(symbol));
                        }
                    }
                    if (symbol) {
                        input = getNameCandidateWorker(symbol, input);
                    }
                    var i = 0;
                    var original = input;
                    while (context.usedSymbolNames.has(input)) {
                        i++;
                        input = original + "_" + i;
                    }
                    context.usedSymbolNames.set(input, true);
                    if (symbol) {
                        context.remappedSymbolNames.set("" + getSymbolId(symbol), input);
                    }
                    return input;
                }
                function getNameCandidateWorker(symbol, localName) {
                    if (localName === "default" /* Default */ || localName === "__class" /* Class */ || localName === "__function" /* Function */) {
                        var flags = context.flags;
                        context.flags |= 16777216 /* InInitialEntityName */;
                        var nameCandidate = getNameOfSymbolAsWritten(symbol, context);
                        context.flags = flags;
                        localName = nameCandidate.length > 0 && ts.isSingleOrDoubleQuote(nameCandidate.charCodeAt(0)) ? ts.stripQuotes(nameCandidate) : nameCandidate;
                    }
                    if (localName === "default" /* Default */) {
                        localName = "_default";
                    }
                    else if (localName === "export=" /* ExportEquals */) {
                        localName = "_exports";
                    }
                    localName = ts.isIdentifierText(localName, languageVersion) && !ts.isStringANonContextualKeyword(localName) ? localName : "_" + localName.replace(/[^a-zA-Z0-9]/g, "_");
                    return localName;
                }
                function getInternalSymbolName(symbol, localName) {
                    if (context.remappedSymbolNames.has("" + getSymbolId(symbol))) {
                        return context.remappedSymbolNames.get("" + getSymbolId(symbol));
                    }
                    localName = getNameCandidateWorker(symbol, localName);
                    // The result of this is going to be used as the symbol's name - lock it in, so `getUnusedName` will also pick it up
                    context.remappedSymbolNames.set("" + getSymbolId(symbol), localName);
                    return localName;
                }
            }
        }
        function typePredicateToString(typePredicate, enclosingDeclaration, flags, writer) {
            if (flags === void 0) { flags = 16384 /* UseAliasDefinedOutsideCurrentScope */; }
            return writer ? typePredicateToStringWorker(writer).getText() : ts.usingSingleLineStringWriter(typePredicateToStringWorker);
            function typePredicateToStringWorker(writer) {
                var predicate = ts.createTypePredicateNodeWithModifier(typePredicate.kind === 2 /* AssertsThis */ || typePredicate.kind === 3 /* AssertsIdentifier */ ? ts.createToken(124 /* AssertsKeyword */) : undefined, typePredicate.kind === 1 /* Identifier */ || typePredicate.kind === 3 /* AssertsIdentifier */ ? ts.createIdentifier(typePredicate.parameterName) : ts.createThisTypeNode(), typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | 70221824 /* IgnoreErrors */ | 512 /* WriteTypeParametersInQualifiedName */) // TODO: GH#18217
                );
                var printer = ts.createPrinter({ removeComments: true });
                var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration);
                printer.writeNode(4 /* Unspecified */, predicate, /*sourceFile*/ sourceFile, writer);
                return writer;
            }
        }
        function formatUnionTypes(types) {
            var result = [];
            var flags = 0;
            for (var i = 0; i < types.length; i++) {
                var t = types[i];
                flags |= t.flags;
                if (!(t.flags & 98304 /* Nullable */)) {
                    if (t.flags & (512 /* BooleanLiteral */ | 1024 /* EnumLiteral */)) {
                        var baseType = t.flags & 512 /* BooleanLiteral */ ? booleanType : getBaseTypeOfEnumLiteralType(t);
                        if (baseType.flags & 1048576 /* Union */) {
                            var count = baseType.types.length;
                            if (i + count <= types.length && getRegularTypeOfLiteralType(types[i + count - 1]) === getRegularTypeOfLiteralType(baseType.types[count - 1])) {
                                result.push(baseType);
                                i += count - 1;
                                continue;
                            }
                        }
                    }
                    result.push(t);
                }
            }
            if (flags & 65536 /* Null */)
                result.push(nullType);
            if (flags & 32768 /* Undefined */)
                result.push(undefinedType);
            return result || types;
        }
        function visibilityToString(flags) {
            if (flags === 8 /* Private */) {
                return "private";
            }
            if (flags === 16 /* Protected */) {
                return "protected";
            }
            return "public";
        }
        function getTypeAliasForTypeLiteral(type) {
            if (type.symbol && type.symbol.flags & 2048 /* TypeLiteral */) {
                var node = ts.findAncestor(type.symbol.declarations[0].parent, function (n) { return n.kind !== 182 /* ParenthesizedType */; });
                if (node.kind === 247 /* TypeAliasDeclaration */) {
                    return getSymbolOfNode(node);
                }
            }
            return undefined;
        }
        function isTopLevelInExternalModuleAugmentation(node) {
            return node && node.parent &&
                node.parent.kind === 250 /* ModuleBlock */ &&
                ts.isExternalModuleAugmentation(node.parent.parent);
        }
        function isDefaultBindingContext(location) {
            return location.kind === 290 /* SourceFile */ || ts.isAmbientModule(location);
        }
        function getNameOfSymbolFromNameType(symbol, context) {
            var nameType = getSymbolLinks(symbol).nameType;
            if (nameType) {
                if (nameType.flags & 384 /* StringOrNumberLiteral */) {
                    var name = "" + nameType.value;
                    if (!ts.isIdentifierText(name, compilerOptions.target) && !isNumericLiteralName(name)) {
                        return "\"" + ts.escapeString(name, 34 /* doubleQuote */) + "\"";
                    }
                    if (isNumericLiteralName(name) && ts.startsWith(name, "-")) {
                        return "[" + name + "]";
                    }
                    return name;
                }
                if (nameType.flags & 8192 /* UniqueESSymbol */) {
                    return "[" + getNameOfSymbolAsWritten(nameType.symbol, context) + "]";
                }
            }
        }
        /**
         * Gets a human-readable name for a symbol.
         * Should *not* be used for the right-hand side of a `.` -- use `symbolName(symbol)` for that instead.
         *
         * Unlike `symbolName(symbol)`, this will include quotes if the name is from a string literal.
         * It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`.
         */
        function getNameOfSymbolAsWritten(symbol, context) {
            if (context && symbol.escapedName === "default" /* Default */ && !(context.flags & 16384 /* UseAliasDefinedOutsideCurrentScope */) &&
                // If it's not the first part of an entity name, it must print as `default`
                (!(context.flags & 16777216 /* InInitialEntityName */) ||
                    // if the symbol is synthesized, it will only be referenced externally it must print as `default`
                    !symbol.declarations ||
                    // if not in the same binding context (source file, module declaration), it must print as `default`
                    (context.enclosingDeclaration && ts.findAncestor(symbol.declarations[0], isDefaultBindingContext) !== ts.findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) {
                return "default";
            }
            if (symbol.declarations && symbol.declarations.length) {
                var declaration = ts.firstDefined(symbol.declarations, function (d) { return ts.getNameOfDeclaration(d) ? d : undefined; }); // Try using a declaration with a name, first
                var name_2 = declaration && ts.getNameOfDeclaration(declaration);
                if (declaration && name_2) {
                    if (ts.isCallExpression(declaration) && ts.isBindableObjectDefinePropertyCall(declaration)) {
                        return ts.symbolName(symbol);
                    }
                    if (ts.isComputedPropertyName(name_2) && !(ts.getCheckFlags(symbol) & 4096 /* Late */)) {
                        var nameType = getSymbolLinks(symbol).nameType;
                        if (nameType && nameType.flags & 384 /* StringOrNumberLiteral */) {
                            // Computed property name isn't late bound, but has a well-known name type - use name type to generate a symbol name
                            var result = getNameOfSymbolFromNameType(symbol, context);
                            if (result !== undefined) {
                                return result;
                            }
                        }
                    }
                    return ts.declarationNameToString(name_2);
                }
                if (!declaration) {
                    declaration = symbol.declarations[0]; // Declaration may be nameless, but we'll try anyway
                }
                if (declaration.parent && declaration.parent.kind === 242 /* VariableDeclaration */) {
                    return ts.declarationNameToString(declaration.parent.name);
                }
                switch (declaration.kind) {
                    case 214 /* ClassExpression */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                        if (context && !context.encounteredError && !(context.flags & 131072 /* AllowAnonymousIdentifier */)) {
                            context.encounteredError = true;
                        }
                        return declaration.kind === 214 /* ClassExpression */ ? "(Anonymous class)" : "(Anonymous function)";
                }
            }
            var name = getNameOfSymbolFromNameType(symbol, context);
            return name !== undefined ? name : ts.symbolName(symbol);
        }
        function isDeclarationVisible(node) {
            if (node) {
                var links = getNodeLinks(node);
                if (links.isVisible === undefined) {
                    links.isVisible = !!determineIfDeclarationIsVisible();
                }
                return links.isVisible;
            }
            return false;
            function determineIfDeclarationIsVisible() {
                switch (node.kind) {
                    case 315 /* JSDocCallbackTag */:
                    case 322 /* JSDocTypedefTag */:
                    case 316 /* JSDocEnumTag */:
                        // Top-level jsdoc type aliases are considered exported
                        // First parent is comment node, second is hosting declaration or token; we only care about those tokens or declarations whose parent is a source file
                        return !!(node.parent && node.parent.parent && node.parent.parent.parent && ts.isSourceFile(node.parent.parent.parent));
                    case 191 /* BindingElement */:
                        return isDeclarationVisible(node.parent.parent);
                    case 242 /* VariableDeclaration */:
                        if (ts.isBindingPattern(node.name) &&
                            !node.name.elements.length) {
                            // If the binding pattern is empty, this variable declaration is not visible
                            return false;
                        }
                    // falls through
                    case 249 /* ModuleDeclaration */:
                    case 245 /* ClassDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                    case 244 /* FunctionDeclaration */:
                    case 248 /* EnumDeclaration */:
                    case 253 /* ImportEqualsDeclaration */:
                        // external module augmentation is always visible
                        if (ts.isExternalModuleAugmentation(node)) {
                            return true;
                        }
                        var parent = getDeclarationContainer(node);
                        // If the node is not exported or it is not ambient module element (except import declaration)
                        if (!(ts.getCombinedModifierFlags(node) & 1 /* Export */) &&
                            !(node.kind !== 253 /* ImportEqualsDeclaration */ && parent.kind !== 290 /* SourceFile */ && parent.flags & 8388608 /* Ambient */)) {
                            return isGlobalSourceFile(parent);
                        }
                        // Exported members/ambient module elements (exception import declaration) are visible if parent is visible
                        return isDeclarationVisible(parent);
                    case 159 /* PropertyDeclaration */:
                    case 158 /* PropertySignature */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 161 /* MethodDeclaration */:
                    case 160 /* MethodSignature */:
                        if (ts.hasModifier(node, 8 /* Private */ | 16 /* Protected */)) {
                            // Private/protected properties/methods are not visible
                            return false;
                        }
                    // Public properties/methods are visible if its parents are visible, so:
                    // falls through
                    case 162 /* Constructor */:
                    case 166 /* ConstructSignature */:
                    case 165 /* CallSignature */:
                    case 167 /* IndexSignature */:
                    case 156 /* Parameter */:
                    case 250 /* ModuleBlock */:
                    case 170 /* FunctionType */:
                    case 171 /* ConstructorType */:
                    case 173 /* TypeLiteral */:
                    case 169 /* TypeReference */:
                    case 174 /* ArrayType */:
                    case 175 /* TupleType */:
                    case 178 /* UnionType */:
                    case 179 /* IntersectionType */:
                    case 182 /* ParenthesizedType */:
                        return isDeclarationVisible(node.parent);
                    // Default binding, import specifier and namespace import is visible
                    // only on demand so by default it is not visible
                    case 255 /* ImportClause */:
                    case 256 /* NamespaceImport */:
                    case 258 /* ImportSpecifier */:
                        return false;
                    // Type parameters are always visible
                    case 155 /* TypeParameter */:
                    // Source file and namespace export are always visible
                    // falls through
                    case 290 /* SourceFile */:
                    case 252 /* NamespaceExportDeclaration */:
                        return true;
                    // Export assignments do not create name bindings outside the module
                    case 259 /* ExportAssignment */:
                        return false;
                    default:
                        return false;
                }
            }
        }
        function collectLinkedAliases(node, setVisibility) {
            var exportSymbol;
            if (node.parent && node.parent.kind === 259 /* ExportAssignment */) {
                exportSymbol = resolveName(node, node.escapedText, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, /*nameNotFoundMessage*/ undefined, node, /*isUse*/ false);
            }
            else if (node.parent.kind === 263 /* ExportSpecifier */) {
                exportSymbol = getTargetOfExportSpecifier(node.parent, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
            }
            var result;
            var visited;
            if (exportSymbol) {
                visited = ts.createMap();
                visited.set("" + getSymbolId(exportSymbol), true);
                buildVisibleNodeList(exportSymbol.declarations);
            }
            return result;
            function buildVisibleNodeList(declarations) {
                ts.forEach(declarations, function (declaration) {
                    var resultNode = getAnyImportSyntax(declaration) || declaration;
                    if (setVisibility) {
                        getNodeLinks(declaration).isVisible = true;
                    }
                    else {
                        result = result || [];
                        ts.pushIfUnique(result, resultNode);
                    }
                    if (ts.isInternalModuleImportEqualsDeclaration(declaration)) {
                        // Add the referenced top container visible
                        var internalModuleReference = declaration.moduleReference;
                        var firstIdentifier = ts.getFirstIdentifier(internalModuleReference);
                        var importSymbol = resolveName(declaration, firstIdentifier.escapedText, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */, undefined, undefined, /*isUse*/ false);
                        var id = importSymbol && "" + getSymbolId(importSymbol);
                        if (importSymbol && !visited.has(id)) {
                            visited.set(id, true);
                            buildVisibleNodeList(importSymbol.declarations);
                        }
                    }
                });
            }
        }
        /**
         * Push an entry on the type resolution stack. If an entry with the given target and the given property name
         * is already on the stack, and no entries in between already have a type, then a circularity has occurred.
         * In this case, the result values of the existing entry and all entries pushed after it are changed to false,
         * and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
         * In order to see if the same query has already been done before, the target object and the propertyName both
         * must match the one passed in.
         *
         * @param target The symbol, type, or signature whose type is being queried
         * @param propertyName The property name that should be used to query the target for its type
         */
        function pushTypeResolution(target, propertyName) {
            var resolutionCycleStartIndex = findResolutionCycleStartIndex(target, propertyName);
            if (resolutionCycleStartIndex >= 0) {
                // A cycle was found
                var length_3 = resolutionTargets.length;
                for (var i = resolutionCycleStartIndex; i < length_3; i++) {
                    resolutionResults[i] = false;
                }
                return false;
            }
            resolutionTargets.push(target);
            resolutionResults.push(/*items*/ true);
            resolutionPropertyNames.push(propertyName);
            return true;
        }
        function findResolutionCycleStartIndex(target, propertyName) {
            for (var i = resolutionTargets.length - 1; i >= 0; i--) {
                if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) {
                    return -1;
                }
                if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) {
                    return i;
                }
            }
            return -1;
        }
        function hasType(target, propertyName) {
            switch (propertyName) {
                case 0 /* Type */:
                    return !!getSymbolLinks(target).type;
                case 5 /* EnumTagType */:
                    return !!(getNodeLinks(target).resolvedEnumType);
                case 2 /* DeclaredType */:
                    return !!getSymbolLinks(target).declaredType;
                case 1 /* ResolvedBaseConstructorType */:
                    return !!target.resolvedBaseConstructorType;
                case 3 /* ResolvedReturnType */:
                    return !!target.resolvedReturnType;
                case 4 /* ImmediateBaseConstraint */:
                    return !!target.immediateBaseConstraint;
                case 6 /* ResolvedTypeArguments */:
                    return !!target.resolvedTypeArguments;
            }
            return ts.Debug.assertNever(propertyName);
        }
        /**
         * Pop an entry from the type resolution stack and return its associated result value. The result value will
         * be true if no circularities were detected, or false if a circularity was found.
         */
        function popTypeResolution() {
            resolutionTargets.pop();
            resolutionPropertyNames.pop();
            return resolutionResults.pop();
        }
        function getDeclarationContainer(node) {
            return ts.findAncestor(ts.getRootDeclaration(node), function (node) {
                switch (node.kind) {
                    case 242 /* VariableDeclaration */:
                    case 243 /* VariableDeclarationList */:
                    case 258 /* ImportSpecifier */:
                    case 257 /* NamedImports */:
                    case 256 /* NamespaceImport */:
                    case 255 /* ImportClause */:
                        return false;
                    default:
                        return true;
                }
            }).parent;
        }
        function getTypeOfPrototypeProperty(prototype) {
            // TypeScript 1.0 spec (April 2014): 8.4
            // Every class automatically contains a static property member named 'prototype',
            // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter.
            // It is an error to explicitly declare a static property member with the name 'prototype'.
            var classType = getDeclaredTypeOfSymbol(getParentOfSymbol(prototype));
            return classType.typeParameters ? createTypeReference(classType, ts.map(classType.typeParameters, function (_) { return anyType; })) : classType;
        }
        // Return the type of the given property in the given type, or undefined if no such property exists
        function getTypeOfPropertyOfType(type, name) {
            var prop = getPropertyOfType(type, name);
            return prop ? getTypeOfSymbol(prop) : undefined;
        }
        function getTypeOfPropertyOrIndexSignature(type, name) {
            return getTypeOfPropertyOfType(type, name) || isNumericLiteralName(name) && getIndexTypeOfType(type, 1 /* Number */) || getIndexTypeOfType(type, 0 /* String */) || unknownType;
        }
        function isTypeAny(type) {
            return type && (type.flags & 1 /* Any */) !== 0;
        }
        // Return the type of a binding element parent. We check SymbolLinks first to see if a type has been
        // assigned by contextual typing.
        function getTypeForBindingElementParent(node) {
            var symbol = getSymbolOfNode(node);
            return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false);
        }
        function getRestType(source, properties, symbol) {
            source = filterType(source, function (t) { return !(t.flags & 98304 /* Nullable */); });
            if (source.flags & 131072 /* Never */) {
                return emptyObjectType;
            }
            if (source.flags & 1048576 /* Union */) {
                return mapType(source, function (t) { return getRestType(t, properties, symbol); });
            }
            var omitKeyType = getUnionType(ts.map(properties, getLiteralTypeFromPropertyName));
            if (isGenericObjectType(source) || isGenericIndexType(omitKeyType)) {
                if (omitKeyType.flags & 131072 /* Never */) {
                    return source;
                }
                var omitTypeAlias = getGlobalOmitSymbol();
                if (!omitTypeAlias) {
                    return errorType;
                }
                return getTypeAliasInstantiation(omitTypeAlias, [source, omitKeyType]);
            }
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                var prop = _a[_i];
                if (!isTypeAssignableTo(getLiteralTypeFromProperty(prop, 8576 /* StringOrNumberLiteralOrUnique */), omitKeyType)
                    && !(ts.getDeclarationModifierFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */))
                    && isSpreadableProperty(prop)) {
                    members.set(prop.escapedName, getSpreadSymbol(prop, /*readonly*/ false));
                }
            }
            var stringIndexInfo = getIndexInfoOfType(source, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(source, 1 /* Number */);
            var result = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
            result.objectFlags |= 131072 /* ObjectRestType */;
            return result;
        }
        // Determine the control flow type associated with a destructuring declaration or assignment. The following
        // forms of destructuring are possible:
        //   let { x } = obj;  // BindingElement
        //   let [ x ] = obj;  // BindingElement
        //   { x } = obj;      // ShorthandPropertyAssignment
        //   { x: v } = obj;   // PropertyAssignment
        //   [ x ] = obj;      // Expression
        // We construct a synthetic element access expression corresponding to 'obj.x' such that the control
        // flow analyzer doesn't have to handle all the different syntactic forms.
        function getFlowTypeOfDestructuring(node, declaredType) {
            var reference = getSyntheticElementAccess(node);
            return reference ? getFlowTypeOfReference(reference, declaredType) : declaredType;
        }
        function getSyntheticElementAccess(node) {
            var parentAccess = getParentElementAccess(node);
            if (parentAccess && parentAccess.flowNode) {
                var propName = getDestructuringPropertyName(node);
                if (propName) {
                    var result = ts.createNode(195 /* ElementAccessExpression */, node.pos, node.end);
                    result.parent = node;
                    result.expression = parentAccess;
                    var literal = ts.createNode(10 /* StringLiteral */, node.pos, node.end);
                    literal.parent = result;
                    literal.text = propName;
                    result.argumentExpression = literal;
                    result.flowNode = parentAccess.flowNode;
                    return result;
                }
            }
        }
        function getParentElementAccess(node) {
            var ancestor = node.parent.parent;
            switch (ancestor.kind) {
                case 191 /* BindingElement */:
                case 281 /* PropertyAssignment */:
                    return getSyntheticElementAccess(ancestor);
                case 192 /* ArrayLiteralExpression */:
                    return getSyntheticElementAccess(node.parent);
                case 242 /* VariableDeclaration */:
                    return ancestor.initializer;
                case 209 /* BinaryExpression */:
                    return ancestor.right;
            }
        }
        function getDestructuringPropertyName(node) {
            var parent = node.parent;
            if (node.kind === 191 /* BindingElement */ && parent.kind === 189 /* ObjectBindingPattern */) {
                return getLiteralPropertyNameText(node.propertyName || node.name);
            }
            if (node.kind === 281 /* PropertyAssignment */ || node.kind === 282 /* ShorthandPropertyAssignment */) {
                return getLiteralPropertyNameText(node.name);
            }
            return "" + parent.elements.indexOf(node);
        }
        function getLiteralPropertyNameText(name) {
            var type = getLiteralTypeFromPropertyName(name);
            return type.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */) ? "" + type.value : undefined;
        }
        /** Return the inferred type for a binding element */
        function getTypeForBindingElement(declaration) {
            var pattern = declaration.parent;
            var parentType = getTypeForBindingElementParent(pattern.parent);
            // If no type or an any type was inferred for parent, infer that for the binding element
            if (!parentType || isTypeAny(parentType)) {
                return parentType;
            }
            // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
            if (strictNullChecks && declaration.flags & 8388608 /* Ambient */ && ts.isParameterDeclaration(declaration)) {
                parentType = getNonNullableType(parentType);
            }
            // Filter `undefined` from the type we check against if the parent has an initializer and that initializer is not possibly `undefined`
            else if (strictNullChecks && pattern.parent.initializer && !(getTypeFacts(getTypeOfInitializer(pattern.parent.initializer)) & 65536 /* EQUndefined */)) {
                parentType = getTypeWithFacts(parentType, 524288 /* NEUndefined */);
            }
            var type;
            if (pattern.kind === 189 /* ObjectBindingPattern */) {
                if (declaration.dotDotDotToken) {
                    parentType = getReducedType(parentType);
                    if (parentType.flags & 2 /* Unknown */ || !isValidSpreadType(parentType)) {
                        error(declaration, ts.Diagnostics.Rest_types_may_only_be_created_from_object_types);
                        return errorType;
                    }
                    var literalMembers = [];
                    for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                        var element = _a[_i];
                        if (!element.dotDotDotToken) {
                            literalMembers.push(element.propertyName || element.name);
                        }
                    }
                    type = getRestType(parentType, literalMembers, declaration.symbol);
                }
                else {
                    // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form)
                    var name = declaration.propertyName || declaration.name;
                    var indexType = getLiteralTypeFromPropertyName(name);
                    var declaredType = getConstraintForLocation(getIndexedAccessType(parentType, indexType, name), declaration.name);
                    type = getFlowTypeOfDestructuring(declaration, declaredType);
                }
            }
            else {
                // This elementType will be used if the specific property corresponding to this index is not
                // present (aka the tuple element property). This call also checks that the parentType is in
                // fact an iterable or array (depending on target language).
                var elementType = checkIteratedTypeOrElementType(65 /* Destructuring */, parentType, undefinedType, pattern);
                var index_1 = pattern.elements.indexOf(declaration);
                if (declaration.dotDotDotToken) {
                    // If the parent is a tuple type, the rest element has a tuple type of the
                    // remaining tuple element types. Otherwise, the rest element has an array type with same
                    // element type as the parent type.
                    type = everyType(parentType, isTupleType) ?
                        mapType(parentType, function (t) { return sliceTupleType(t, index_1); }) :
                        createArrayType(elementType);
                }
                else if (isArrayLikeType(parentType)) {
                    var indexType = getLiteralType(index_1);
                    var accessFlags = hasDefaultValue(declaration) ? 8 /* NoTupleBoundsCheck */ : 0;
                    var declaredType = getConstraintForLocation(getIndexedAccessTypeOrUndefined(parentType, indexType, declaration.name, accessFlags) || errorType, declaration.name);
                    type = getFlowTypeOfDestructuring(declaration, declaredType);
                }
                else {
                    type = elementType;
                }
            }
            if (!declaration.initializer) {
                return type;
            }
            if (ts.getEffectiveTypeAnnotationNode(ts.walkUpBindingElementsAndPatterns(declaration))) {
                // In strict null checking mode, if a default value of a non-undefined type is specified, remove
                // undefined from the final type.
                return strictNullChecks && !(getFalsyFlags(checkDeclarationInitializer(declaration)) & 32768 /* Undefined */) ?
                    getTypeWithFacts(type, 524288 /* NEUndefined */) :
                    type;
            }
            return widenTypeInferredFromInitializer(declaration, getUnionType([getTypeWithFacts(type, 524288 /* NEUndefined */), checkDeclarationInitializer(declaration)], 2 /* Subtype */));
        }
        function getTypeForDeclarationFromJSDocComment(declaration) {
            var jsdocType = ts.getJSDocType(declaration);
            if (jsdocType) {
                return getTypeFromTypeNode(jsdocType);
            }
            return undefined;
        }
        function isNullOrUndefined(node) {
            var expr = ts.skipParentheses(node);
            return expr.kind === 100 /* NullKeyword */ || expr.kind === 75 /* Identifier */ && getResolvedSymbol(expr) === undefinedSymbol;
        }
        function isEmptyArrayLiteral(node) {
            var expr = ts.skipParentheses(node);
            return expr.kind === 192 /* ArrayLiteralExpression */ && expr.elements.length === 0;
        }
        function addOptionality(type, optional) {
            if (optional === void 0) { optional = true; }
            return strictNullChecks && optional ? getOptionalType(type) : type;
        }
        // Return the inferred type for a variable, parameter, or property declaration
        function getTypeForVariableLikeDeclaration(declaration, includeOptionality) {
            // A variable declared in a for..in statement is of type string, or of type keyof T when the
            // right hand expression is of a type parameter type.
            if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === 231 /* ForInStatement */) {
                var indexType = getIndexType(getNonNullableTypeIfNeeded(checkExpression(declaration.parent.parent.expression)));
                return indexType.flags & (262144 /* TypeParameter */ | 4194304 /* Index */) ? getExtractStringType(indexType) : stringType;
            }
            if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === 232 /* ForOfStatement */) {
                // checkRightHandSideOfForOf will return undefined if the for-of expression type was
                // missing properties/signatures required to get its iteratedType (like
                // [Symbol.iterator] or next). This may be because we accessed properties from anyType,
                // or it may have led to an error inside getElementTypeOfIterable.
                var forOfStatement = declaration.parent.parent;
                return checkRightHandSideOfForOf(forOfStatement) || anyType;
            }
            if (ts.isBindingPattern(declaration.parent)) {
                return getTypeForBindingElement(declaration);
            }
            var isOptional = includeOptionality && (ts.isParameter(declaration) && isJSDocOptionalParameter(declaration)
                || !ts.isBindingElement(declaration) && !ts.isVariableDeclaration(declaration) && !!declaration.questionToken);
            // Use type from type annotation if one is present
            var declaredType = tryGetTypeFromEffectiveTypeNode(declaration);
            if (declaredType) {
                return addOptionality(declaredType, isOptional);
            }
            if ((noImplicitAny || ts.isInJSFile(declaration)) &&
                declaration.kind === 242 /* VariableDeclaration */ && !ts.isBindingPattern(declaration.name) &&
                !(ts.getCombinedModifierFlags(declaration) & 1 /* Export */) && !(declaration.flags & 8388608 /* Ambient */)) {
                // If --noImplicitAny is on or the declaration is in a Javascript file,
                // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no
                // initializer or a 'null' or 'undefined' initializer.
                if (!(ts.getCombinedNodeFlags(declaration) & 2 /* Const */) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) {
                    return autoType;
                }
                // Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array
                // literal initializer.
                if (declaration.initializer && isEmptyArrayLiteral(declaration.initializer)) {
                    return autoArrayType;
                }
            }
            if (declaration.kind === 156 /* Parameter */) {
                var func = declaration.parent;
                // For a parameter of a set accessor, use the type of the get accessor if one is present
                if (func.kind === 164 /* SetAccessor */ && !hasNonBindableDynamicName(func)) {
                    var getter = ts.getDeclarationOfKind(getSymbolOfNode(declaration.parent), 163 /* GetAccessor */);
                    if (getter) {
                        var getterSignature = getSignatureFromDeclaration(getter);
                        var thisParameter = getAccessorThisParameter(func);
                        if (thisParameter && declaration === thisParameter) {
                            // Use the type from the *getter*
                            ts.Debug.assert(!thisParameter.type);
                            return getTypeOfSymbol(getterSignature.thisParameter);
                        }
                        return getReturnTypeOfSignature(getterSignature);
                    }
                }
                if (ts.isInJSFile(declaration)) {
                    var typeTag = ts.getJSDocType(func);
                    if (typeTag && ts.isFunctionTypeNode(typeTag)) {
                        return getTypeAtPosition(getSignatureFromDeclaration(typeTag), func.parameters.indexOf(declaration));
                    }
                }
                // Use contextual parameter type if one is available
                var type = declaration.symbol.escapedName === "this" /* This */ ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
                if (type) {
                    return addOptionality(type, isOptional);
                }
            }
            else if (ts.isInJSFile(declaration)) {
                var containerObjectType = getJSContainerObjectType(declaration, getSymbolOfNode(declaration), ts.getDeclaredExpandoInitializer(declaration));
                if (containerObjectType) {
                    return containerObjectType;
                }
            }
            // Use the type of the initializer expression if one is present and the declaration is
            // not a parameter of a contextually typed function
            if (declaration.initializer) {
                var type = widenTypeInferredFromInitializer(declaration, checkDeclarationInitializer(declaration));
                return addOptionality(type, isOptional);
            }
            if (ts.isJsxAttribute(declaration)) {
                // if JSX attribute doesn't have initializer, by default the attribute will have boolean value of true.
                // I.e <Elem attr /> is sugar for <Elem attr={true} />
                return trueType;
            }
            // If the declaration specifies a binding pattern and is not a parameter of a contextually
            // typed function, use the type implied by the binding pattern
            if (ts.isBindingPattern(declaration.name)) {
                return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
            }
            // No type specified and nothing can be inferred
            return undefined;
        }
        function getWidenedTypeForAssignmentDeclaration(symbol, resolvedSymbol) {
            // function/class/{} initializers are themselves containers, so they won't merge in the same way as other initializers
            var container = ts.getAssignedExpandoInitializer(symbol.valueDeclaration);
            if (container) {
                var tag = ts.getJSDocTypeTag(container);
                if (tag && tag.typeExpression) {
                    return getTypeFromTypeNode(tag.typeExpression);
                }
                var containerObjectType = getJSContainerObjectType(symbol.valueDeclaration, symbol, container);
                return containerObjectType || getWidenedLiteralType(checkExpressionCached(container));
            }
            var definedInConstructor = false;
            var definedInMethod = false;
            var jsdocType;
            var types;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                var expression = (ts.isBinaryExpression(declaration) || ts.isCallExpression(declaration)) ? declaration :
                    ts.isAccessExpression(declaration) ? ts.isBinaryExpression(declaration.parent) ? declaration.parent : declaration :
                        undefined;
                if (!expression) {
                    continue; // Non-assignment declaration merged in (eg, an Identifier to mark the thing as a namespace) - skip over it and pull type info from elsewhere
                }
                var kind = ts.isAccessExpression(expression)
                    ? ts.getAssignmentDeclarationPropertyAccessKind(expression)
                    : ts.getAssignmentDeclarationKind(expression);
                if (kind === 4 /* ThisProperty */) {
                    if (isDeclarationInConstructor(expression)) {
                        definedInConstructor = true;
                    }
                    else {
                        definedInMethod = true;
                    }
                }
                if (!ts.isCallExpression(expression)) {
                    jsdocType = getAnnotatedTypeForAssignmentDeclaration(jsdocType, expression, symbol, declaration);
                }
                if (!jsdocType) {
                    (types || (types = [])).push((ts.isBinaryExpression(expression) || ts.isCallExpression(expression)) ? getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) : neverType);
                }
            }
            var type = jsdocType;
            if (!type) {
                if (!ts.length(types)) {
                    return errorType; // No types from any declarations :(
                }
                var constructorTypes = definedInConstructor ? getConstructorDefinedThisAssignmentTypes(types, symbol.declarations) : undefined;
                // use only the constructor types unless they were only assigned null | undefined (including widening variants)
                if (definedInMethod) {
                    var propType = getTypeOfAssignmentDeclarationPropertyOfBaseType(symbol);
                    if (propType) {
                        (constructorTypes || (constructorTypes = [])).push(propType);
                        definedInConstructor = true;
                    }
                }
                var sourceTypes = ts.some(constructorTypes, function (t) { return !!(t.flags & ~98304 /* Nullable */); }) ? constructorTypes : types; // TODO: GH#18217
                type = getUnionType(sourceTypes, 2 /* Subtype */);
            }
            var widened = getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor));
            if (filterType(widened, function (t) { return !!(t.flags & ~98304 /* Nullable */); }) === neverType) {
                reportImplicitAny(symbol.valueDeclaration, anyType);
                return anyType;
            }
            return widened;
        }
        function getJSContainerObjectType(decl, symbol, init) {
            if (!ts.isInJSFile(decl) || !init || !ts.isObjectLiteralExpression(init) || init.properties.length) {
                return undefined;
            }
            var exports = ts.createSymbolTable();
            while (ts.isBinaryExpression(decl) || ts.isPropertyAccessExpression(decl)) {
                var s_2 = getSymbolOfNode(decl);
                if (s_2 && ts.hasEntries(s_2.exports)) {
                    mergeSymbolTable(exports, s_2.exports);
                }
                decl = ts.isBinaryExpression(decl) ? decl.parent : decl.parent.parent;
            }
            var s = getSymbolOfNode(decl);
            if (s && ts.hasEntries(s.exports)) {
                mergeSymbolTable(exports, s.exports);
            }
            var type = createAnonymousType(symbol, exports, ts.emptyArray, ts.emptyArray, undefined, undefined);
            type.objectFlags |= 16384 /* JSLiteral */;
            return type;
        }
        function getAnnotatedTypeForAssignmentDeclaration(declaredType, expression, symbol, declaration) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(expression.parent);
            if (typeNode) {
                var type = getWidenedType(getTypeFromTypeNode(typeNode));
                if (!declaredType) {
                    return type;
                }
                else if (declaredType !== errorType && type !== errorType && !isTypeIdenticalTo(declaredType, type)) {
                    errorNextVariableOrPropertyDeclarationMustHaveSameType(/*firstDeclaration*/ undefined, declaredType, declaration, type);
                }
            }
            if (symbol.parent) {
                var typeNode_2 = ts.getEffectiveTypeAnnotationNode(symbol.parent.valueDeclaration);
                if (typeNode_2) {
                    return getTypeOfPropertyOfType(getTypeFromTypeNode(typeNode_2), symbol.escapedName);
                }
            }
            return declaredType;
        }
        /** If we don't have an explicit JSDoc type, get the type from the initializer. */
        function getInitializerTypeFromAssignmentDeclaration(symbol, resolvedSymbol, expression, kind) {
            if (ts.isCallExpression(expression)) {
                if (resolvedSymbol) {
                    return getTypeOfSymbol(resolvedSymbol); // This shouldn't happen except under some hopefully forbidden merges of export assignments and object define assignments
                }
                var objectLitType = checkExpressionCached(expression.arguments[2]);
                var valueType = getTypeOfPropertyOfType(objectLitType, "value");
                if (valueType) {
                    return valueType;
                }
                var getFunc = getTypeOfPropertyOfType(objectLitType, "get");
                if (getFunc) {
                    var getSig = getSingleCallSignature(getFunc);
                    if (getSig) {
                        return getReturnTypeOfSignature(getSig);
                    }
                }
                var setFunc = getTypeOfPropertyOfType(objectLitType, "set");
                if (setFunc) {
                    var setSig = getSingleCallSignature(setFunc);
                    if (setSig) {
                        return getTypeOfFirstParameterOfSignature(setSig);
                    }
                }
                return anyType;
            }
            if (containsSameNamedThisProperty(expression.left, expression.right)) {
                return anyType;
            }
            var type = resolvedSymbol ? getTypeOfSymbol(resolvedSymbol) : getWidenedLiteralType(checkExpressionCached(expression.right));
            if (type.flags & 524288 /* Object */ &&
                kind === 2 /* ModuleExports */ &&
                symbol.escapedName === "export=" /* ExportEquals */) {
                var exportedType = resolveStructuredTypeMembers(type);
                var members_4 = ts.createSymbolTable();
                ts.copyEntries(exportedType.members, members_4);
                if (resolvedSymbol && !resolvedSymbol.exports) {
                    resolvedSymbol.exports = ts.createSymbolTable();
                }
                (resolvedSymbol || symbol).exports.forEach(function (s, name) {
                    var _a;
                    var exportedMember = members_4.get(name);
                    if (exportedMember && exportedMember !== s) {
                        if (s.flags & 111551 /* Value */) {
                            // If the member has an additional value-like declaration, union the types from the two declarations,
                            // but issue an error if they occurred in two different files. The purpose is to support a JS file with
                            // a pattern like:
                            //
                            // module.exports = { a: true };
                            // module.exports.a = 3;
                            //
                            // but we may have a JS file with `module.exports = { a: true }` along with a TypeScript module augmentation
                            // declaring an `export const a: number`. In that case, we issue a duplicate identifier error, because
                            // it's unclear what that's supposed to mean, so it's probably a mistake.
                            if (ts.getSourceFileOfNode(s.valueDeclaration) !== ts.getSourceFileOfNode(exportedMember.valueDeclaration)) {
                                var unescapedName = ts.unescapeLeadingUnderscores(s.escapedName);
                                var exportedMemberName = ((_a = ts.tryCast(exportedMember.valueDeclaration, ts.isNamedDeclaration)) === null || _a === void 0 ? void 0 : _a.name) || exportedMember.valueDeclaration;
                                ts.addRelatedInfo(error(s.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0, unescapedName), ts.createDiagnosticForNode(exportedMemberName, ts.Diagnostics._0_was_also_declared_here, unescapedName));
                                ts.addRelatedInfo(error(exportedMemberName, ts.Diagnostics.Duplicate_identifier_0, unescapedName), ts.createDiagnosticForNode(s.valueDeclaration, ts.Diagnostics._0_was_also_declared_here, unescapedName));
                            }
                            var union = createSymbol(s.flags | exportedMember.flags, name);
                            union.type = getUnionType([getTypeOfSymbol(s), getTypeOfSymbol(exportedMember)]);
                            union.valueDeclaration = exportedMember.valueDeclaration;
                            union.declarations = ts.concatenate(exportedMember.declarations, s.declarations);
                            members_4.set(name, union);
                        }
                        else {
                            members_4.set(name, mergeSymbol(s, exportedMember));
                        }
                    }
                    else {
                        members_4.set(name, s);
                    }
                });
                var result = createAnonymousType(exportedType.symbol, members_4, exportedType.callSignatures, exportedType.constructSignatures, exportedType.stringIndexInfo, exportedType.numberIndexInfo);
                result.objectFlags |= (ts.getObjectFlags(type) & 16384 /* JSLiteral */); // Propagate JSLiteral flag
                return result;
            }
            if (isEmptyArrayLiteralType(type)) {
                reportImplicitAny(expression, anyArrayType);
                return anyArrayType;
            }
            return type;
        }
        function containsSameNamedThisProperty(thisProperty, expression) {
            return ts.isPropertyAccessExpression(thisProperty)
                && thisProperty.expression.kind === 104 /* ThisKeyword */
                && ts.forEachChildRecursively(expression, function (n) { return isMatchingReference(thisProperty, n); });
        }
        function isDeclarationInConstructor(expression) {
            var thisContainer = ts.getThisContainer(expression, /*includeArrowFunctions*/ false);
            // Properties defined in a constructor (or base constructor, or javascript constructor function) don't get undefined added.
            // Function expressions that are assigned to the prototype count as methods.
            return thisContainer.kind === 162 /* Constructor */ ||
                thisContainer.kind === 244 /* FunctionDeclaration */ ||
                (thisContainer.kind === 201 /* FunctionExpression */ && !ts.isPrototypePropertyAssignment(thisContainer.parent));
        }
        function getConstructorDefinedThisAssignmentTypes(types, declarations) {
            ts.Debug.assert(types.length === declarations.length);
            return types.filter(function (_, i) {
                var declaration = declarations[i];
                var expression = ts.isBinaryExpression(declaration) ? declaration :
                    ts.isBinaryExpression(declaration.parent) ? declaration.parent : undefined;
                return expression && isDeclarationInConstructor(expression);
            });
        }
        /** check for definition in base class if any declaration is in a class */
        function getTypeOfAssignmentDeclarationPropertyOfBaseType(property) {
            var parentDeclaration = ts.forEach(property.declarations, function (d) {
                var parent = ts.getThisContainer(d, /*includeArrowFunctions*/ false).parent;
                return ts.isClassLike(parent) && parent;
            });
            if (parentDeclaration) {
                var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(parentDeclaration));
                var baseClassType = classType && getBaseTypes(classType)[0];
                if (baseClassType) {
                    return getTypeOfPropertyOfType(baseClassType, property.escapedName);
                }
            }
        }
        // Return the type implied by a binding pattern element. This is the type of the initializer of the element if
        // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
        // pattern. Otherwise, it is the type any.
        function getTypeFromBindingElement(element, includePatternInType, reportErrors) {
            if (element.initializer) {
                // The type implied by a binding pattern is independent of context, so we check the initializer with no
                // contextual type or, if the element itself is a binding pattern, with the type implied by that binding
                // pattern.
                var contextualType = ts.isBindingPattern(element.name) ? getTypeFromBindingPattern(element.name, /*includePatternInType*/ true, /*reportErrors*/ false) : unknownType;
                return addOptionality(widenTypeInferredFromInitializer(element, checkDeclarationInitializer(element, contextualType)));
            }
            if (ts.isBindingPattern(element.name)) {
                return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors);
            }
            if (reportErrors && !declarationBelongsToPrivateAmbientMember(element)) {
                reportImplicitAny(element, anyType);
            }
            // When we're including the pattern in the type (an indication we're obtaining a contextual type), we
            // use the non-inferrable any type. Inference will never directly infer this type, but it is possible
            // to infer a type that contains it, e.g. for a binding pattern like [foo] or { foo }. In such cases,
            // widening of the binding pattern type substitutes a regular any for the non-inferrable any.
            return includePatternInType ? nonInferrableAnyType : anyType;
        }
        // Return the type implied by an object binding pattern
        function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) {
            var members = ts.createSymbolTable();
            var stringIndexInfo;
            var objectFlags = 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
            ts.forEach(pattern.elements, function (e) {
                var name = e.propertyName || e.name;
                if (e.dotDotDotToken) {
                    stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
                    return;
                }
                var exprType = getLiteralTypeFromPropertyName(name);
                if (!isTypeUsableAsPropertyName(exprType)) {
                    // do not include computed properties in the implied type
                    objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
                    return;
                }
                var text = getPropertyNameFromType(exprType);
                var flags = 4 /* Property */ | (e.initializer ? 16777216 /* Optional */ : 0);
                var symbol = createSymbol(flags, text);
                symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors);
                symbol.bindingElement = e;
                members.set(symbol.escapedName, symbol);
            });
            var result = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
            result.objectFlags |= objectFlags;
            if (includePatternInType) {
                result.pattern = pattern;
                result.objectFlags |= 1048576 /* ContainsObjectOrArrayLiteral */;
            }
            return result;
        }
        // Return the type implied by an array binding pattern
        function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) {
            var elements = pattern.elements;
            var lastElement = ts.lastOrUndefined(elements);
            var hasRestElement = !!(lastElement && lastElement.kind === 191 /* BindingElement */ && lastElement.dotDotDotToken);
            if (elements.length === 0 || elements.length === 1 && hasRestElement) {
                return languageVersion >= 2 /* ES2015 */ ? createIterableType(anyType) : anyArrayType;
            }
            var elementTypes = ts.map(elements, function (e) { return ts.isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); });
            var minLength = ts.findLastIndex(elements, function (e) { return !ts.isOmittedExpression(e) && !hasDefaultValue(e); }, elements.length - (hasRestElement ? 2 : 1)) + 1;
            var result = createTupleType(elementTypes, minLength, hasRestElement);
            if (includePatternInType) {
                result = cloneTypeReference(result);
                result.pattern = pattern;
                result.objectFlags |= 1048576 /* ContainsObjectOrArrayLiteral */;
            }
            return result;
        }
        // Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself
        // and without regard to its context (i.e. without regard any type annotation or initializer associated with the
        // declaration in which the binding pattern is contained). For example, the implied type of [x, y] is [any, any]
        // and the implied type of { x, y: z = 1 } is { x: any; y: number; }. The type implied by a binding pattern is
        // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring
        // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of
        // the parameter.
        function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) {
            if (includePatternInType === void 0) { includePatternInType = false; }
            if (reportErrors === void 0) { reportErrors = false; }
            return pattern.kind === 189 /* ObjectBindingPattern */
                ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors)
                : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors);
        }
        // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type
        // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it
        // is a bit more involved. For example:
        //
        //   var [x, s = ""] = [1, "one"];
        //
        // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the
        // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the
        // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string.
        function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) {
            return widenTypeForVariableLikeDeclaration(getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true), declaration, reportErrors);
        }
        function widenTypeForVariableLikeDeclaration(type, declaration, reportErrors) {
            if (type) {
                if (reportErrors) {
                    reportErrorsFromWidening(declaration, type);
                }
                // always widen a 'unique symbol' type if the type was created for a different declaration.
                if (type.flags & 8192 /* UniqueESSymbol */ && (ts.isBindingElement(declaration) || !declaration.type) && type.symbol !== getSymbolOfNode(declaration)) {
                    type = esSymbolType;
                }
                return getWidenedType(type);
            }
            // Rest parameters default to type any[], other parameters default to type any
            type = ts.isParameter(declaration) && declaration.dotDotDotToken ? anyArrayType : anyType;
            // Report implicit any errors unless this is a private property within an ambient declaration
            if (reportErrors) {
                if (!declarationBelongsToPrivateAmbientMember(declaration)) {
                    reportImplicitAny(declaration, type);
                }
            }
            return type;
        }
        function declarationBelongsToPrivateAmbientMember(declaration) {
            var root = ts.getRootDeclaration(declaration);
            var memberDeclaration = root.kind === 156 /* Parameter */ ? root.parent : root;
            return isPrivateWithinAmbient(memberDeclaration);
        }
        function tryGetTypeFromEffectiveTypeNode(declaration) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
        }
        function getTypeOfVariableOrParameterOrProperty(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                var type = getTypeOfVariableOrParameterOrPropertyWorker(symbol);
                // For a contextually typed parameter it is possible that a type has already
                // been assigned (in assignTypeToParameterAndFixTypeParameters), and we want
                // to preserve this type.
                if (!links.type) {
                    links.type = type;
                }
            }
            return links.type;
        }
        function getTypeOfVariableOrParameterOrPropertyWorker(symbol) {
            // Handle prototype property
            if (symbol.flags & 4194304 /* Prototype */) {
                return getTypeOfPrototypeProperty(symbol);
            }
            // CommonsJS require and module both have type any.
            if (symbol === requireSymbol) {
                return anyType;
            }
            if (symbol.flags & 134217728 /* ModuleExports */) {
                var fileSymbol = getSymbolOfNode(ts.getSourceFileOfNode(symbol.valueDeclaration));
                var members = ts.createSymbolTable();
                members.set("exports", fileSymbol);
                return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, undefined, undefined);
            }
            // Handle catch clause variables
            var declaration = symbol.valueDeclaration;
            if (ts.isCatchClauseVariableDeclarationOrBindingElement(declaration)) {
                return anyType;
            }
            // Handle export default expressions
            if (ts.isSourceFile(declaration) && ts.isJsonSourceFile(declaration)) {
                if (!declaration.statements.length) {
                    return emptyObjectType;
                }
                return getWidenedType(getWidenedLiteralType(checkExpression(declaration.statements[0].expression)));
            }
            // Handle variable, parameter or property
            if (!pushTypeResolution(symbol, 0 /* Type */)) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & 512 /* ValueModule */ && !(symbol.flags & 67108864 /* Assignment */)) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                return reportCircularityError(symbol);
            }
            var type;
            if (declaration.kind === 259 /* ExportAssignment */) {
                type = widenTypeForVariableLikeDeclaration(checkExpressionCached(declaration.expression), declaration);
            }
            else if (ts.isBinaryExpression(declaration) ||
                (ts.isInJSFile(declaration) &&
                    (ts.isCallExpression(declaration) || (ts.isPropertyAccessExpression(declaration) || ts.isBindableStaticElementAccessExpression(declaration)) && ts.isBinaryExpression(declaration.parent)))) {
                type = getWidenedTypeForAssignmentDeclaration(symbol);
            }
            else if (ts.isJSDocPropertyLikeTag(declaration)
                || ts.isPropertyAccessExpression(declaration)
                || ts.isElementAccessExpression(declaration)
                || ts.isIdentifier(declaration)
                || ts.isStringLiteralLike(declaration)
                || ts.isNumericLiteral(declaration)
                || ts.isClassDeclaration(declaration)
                || ts.isFunctionDeclaration(declaration)
                || (ts.isMethodDeclaration(declaration) && !ts.isObjectLiteralMethod(declaration))
                || ts.isMethodSignature(declaration)
                || ts.isSourceFile(declaration)) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                type = ts.isBinaryExpression(declaration.parent) ?
                    getWidenedTypeForAssignmentDeclaration(symbol) :
                    tryGetTypeFromEffectiveTypeNode(declaration) || anyType;
            }
            else if (ts.isPropertyAssignment(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkPropertyAssignment(declaration);
            }
            else if (ts.isJsxAttribute(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkJsxAttribute(declaration);
            }
            else if (ts.isShorthandPropertyAssignment(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkExpressionForMutableLocation(declaration.name, 0 /* Normal */);
            }
            else if (ts.isObjectLiteralMethod(declaration)) {
                type = tryGetTypeFromEffectiveTypeNode(declaration) || checkObjectLiteralMethod(declaration, 0 /* Normal */);
            }
            else if (ts.isParameter(declaration)
                || ts.isPropertyDeclaration(declaration)
                || ts.isPropertySignature(declaration)
                || ts.isVariableDeclaration(declaration)
                || ts.isBindingElement(declaration)) {
                type = getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true);
            }
            // getTypeOfSymbol dispatches some JS merges incorrectly because their symbol flags are not mutually exclusive.
            // Re-dispatch based on valueDeclaration.kind instead.
            else if (ts.isEnumDeclaration(declaration)) {
                type = getTypeOfFuncClassEnumModule(symbol);
            }
            else if (ts.isEnumMember(declaration)) {
                type = getTypeOfEnumMember(symbol);
            }
            else if (ts.isAccessor(declaration)) {
                type = resolveTypeOfAccessors(symbol);
            }
            else {
                return ts.Debug.fail("Unhandled declaration kind! " + ts.Debug.formatSyntaxKind(declaration.kind) + " for " + ts.Debug.formatSymbol(symbol));
            }
            if (!popTypeResolution()) {
                // Symbol is property of some kind that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                if (symbol.flags & 512 /* ValueModule */ && !(symbol.flags & 67108864 /* Assignment */)) {
                    return getTypeOfFuncClassEnumModule(symbol);
                }
                return reportCircularityError(symbol);
            }
            return type;
        }
        function getAnnotatedAccessorTypeNode(accessor) {
            if (accessor) {
                if (accessor.kind === 163 /* GetAccessor */) {
                    var getterTypeAnnotation = ts.getEffectiveReturnTypeNode(accessor);
                    return getterTypeAnnotation;
                }
                else {
                    var setterTypeAnnotation = ts.getEffectiveSetAccessorTypeAnnotationNode(accessor);
                    return setterTypeAnnotation;
                }
            }
            return undefined;
        }
        function getAnnotatedAccessorType(accessor) {
            var node = getAnnotatedAccessorTypeNode(accessor);
            return node && getTypeFromTypeNode(node);
        }
        function getAnnotatedAccessorThisParameter(accessor) {
            var parameter = getAccessorThisParameter(accessor);
            return parameter && parameter.symbol;
        }
        function getThisTypeOfDeclaration(declaration) {
            return getThisTypeOfSignature(getSignatureFromDeclaration(declaration));
        }
        function getTypeOfAccessors(symbol) {
            var links = getSymbolLinks(symbol);
            return links.type || (links.type = getTypeOfAccessorsWorker(symbol));
        }
        function getTypeOfAccessorsWorker(symbol) {
            if (!pushTypeResolution(symbol, 0 /* Type */)) {
                return errorType;
            }
            var type = resolveTypeOfAccessors(symbol);
            if (!popTypeResolution()) {
                type = anyType;
                if (noImplicitAny) {
                    var getter = ts.getDeclarationOfKind(symbol, 163 /* GetAccessor */);
                    error(getter, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
                }
            }
            return type;
        }
        function resolveTypeOfAccessors(symbol) {
            var getter = ts.getDeclarationOfKind(symbol, 163 /* GetAccessor */);
            var setter = ts.getDeclarationOfKind(symbol, 164 /* SetAccessor */);
            if (getter && ts.isInJSFile(getter)) {
                var jsDocType = getTypeForDeclarationFromJSDocComment(getter);
                if (jsDocType) {
                    return jsDocType;
                }
            }
            // First try to see if the user specified a return type on the get-accessor.
            var getterReturnType = getAnnotatedAccessorType(getter);
            if (getterReturnType) {
                return getterReturnType;
            }
            else {
                // If the user didn't specify a return type, try to use the set-accessor's parameter type.
                var setterParameterType = getAnnotatedAccessorType(setter);
                if (setterParameterType) {
                    return setterParameterType;
                }
                else {
                    // If there are no specified types, try to infer it from the body of the get accessor if it exists.
                    if (getter && getter.body) {
                        return getReturnTypeFromBody(getter);
                    }
                    // Otherwise, fall back to 'any'.
                    else {
                        if (setter) {
                            if (!isPrivateWithinAmbient(setter)) {
                                errorOrSuggestion(noImplicitAny, setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol));
                            }
                        }
                        else {
                            ts.Debug.assert(!!getter, "there must exist a getter as we are current checking either setter or getter in this function");
                            if (!isPrivateWithinAmbient(getter)) {
                                errorOrSuggestion(noImplicitAny, getter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol));
                            }
                        }
                        return anyType;
                    }
                }
            }
        }
        function getBaseTypeVariableOfClass(symbol) {
            var baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol));
            return baseConstructorType.flags & 8650752 /* TypeVariable */ ? baseConstructorType :
                baseConstructorType.flags & 2097152 /* Intersection */ ? ts.find(baseConstructorType.types, function (t) { return !!(t.flags & 8650752 /* TypeVariable */); }) :
                    undefined;
        }
        function getTypeOfFuncClassEnumModule(symbol) {
            var links = getSymbolLinks(symbol);
            var originalLinks = links;
            if (!links.type) {
                var jsDeclaration = symbol.valueDeclaration && ts.getDeclarationOfExpando(symbol.valueDeclaration);
                if (jsDeclaration) {
                    var merged = mergeJSSymbols(symbol, getSymbolOfNode(jsDeclaration));
                    if (merged) {
                        // note:we overwrite links because we just cloned the symbol
                        symbol = links = merged;
                    }
                }
                originalLinks.type = links.type = getTypeOfFuncClassEnumModuleWorker(symbol);
            }
            return links.type;
        }
        function getTypeOfFuncClassEnumModuleWorker(symbol) {
            var declaration = symbol.valueDeclaration;
            if (symbol.flags & 1536 /* Module */ && ts.isShorthandAmbientModuleSymbol(symbol)) {
                return anyType;
            }
            else if (declaration && (declaration.kind === 209 /* BinaryExpression */ ||
                ts.isAccessExpression(declaration) &&
                    declaration.parent.kind === 209 /* BinaryExpression */)) {
                return getWidenedTypeForAssignmentDeclaration(symbol);
            }
            else if (symbol.flags & 512 /* ValueModule */ && declaration && ts.isSourceFile(declaration) && declaration.commonJsModuleIndicator) {
                var resolvedModule = resolveExternalModuleSymbol(symbol);
                if (resolvedModule !== symbol) {
                    if (!pushTypeResolution(symbol, 0 /* Type */)) {
                        return errorType;
                    }
                    var exportEquals = getMergedSymbol(symbol.exports.get("export=" /* ExportEquals */));
                    var type_1 = getWidenedTypeForAssignmentDeclaration(exportEquals, exportEquals === resolvedModule ? undefined : resolvedModule);
                    if (!popTypeResolution()) {
                        return reportCircularityError(symbol);
                    }
                    return type_1;
                }
            }
            var type = createObjectType(16 /* Anonymous */, symbol);
            if (symbol.flags & 32 /* Class */) {
                var baseTypeVariable = getBaseTypeVariableOfClass(symbol);
                return baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type;
            }
            else {
                return strictNullChecks && symbol.flags & 16777216 /* Optional */ ? getOptionalType(type) : type;
            }
        }
        function getTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            return links.type || (links.type = getDeclaredTypeOfEnumMember(symbol));
        }
        function getTypeOfAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                var targetSymbol = resolveAlias(symbol);
                // It only makes sense to get the type of a value symbol. If the result of resolving
                // the alias is not a value, then it has no type. To get the type associated with a
                // type symbol, call getDeclaredTypeOfSymbol.
                // This check is important because without it, a call to getTypeOfSymbol could end
                // up recursively calling getTypeOfAlias, causing a stack overflow.
                links.type = targetSymbol.flags & 111551 /* Value */
                    ? getTypeOfSymbol(targetSymbol)
                    : errorType;
            }
            return links.type;
        }
        function getTypeOfInstantiatedSymbol(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                if (!pushTypeResolution(symbol, 0 /* Type */)) {
                    return links.type = errorType;
                }
                var type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
                if (!popTypeResolution()) {
                    type = reportCircularityError(symbol);
                }
                links.type = type;
            }
            return links.type;
        }
        function reportCircularityError(symbol) {
            var declaration = symbol.valueDeclaration;
            // Check if variable has type annotation that circularly references the variable itself
            if (ts.getEffectiveTypeAnnotationNode(declaration)) {
                error(symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol));
                return errorType;
            }
            // Check if variable has initializer that circularly references the variable itself
            if (noImplicitAny && (declaration.kind !== 156 /* Parameter */ || declaration.initializer)) {
                error(symbol.valueDeclaration, ts.Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol));
            }
            // Circularities could also result from parameters in function expressions that end up
            // having themselves as contextual types following type argument inference. In those cases
            // we have already reported an implicit any error so we don't report anything here.
            return anyType;
        }
        function getTypeOfSymbolWithDeferredType(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.type) {
                ts.Debug.assertIsDefined(links.deferralParent);
                ts.Debug.assertIsDefined(links.deferralConstituents);
                links.type = links.deferralParent.flags & 1048576 /* Union */ ? getUnionType(links.deferralConstituents) : getIntersectionType(links.deferralConstituents);
            }
            return links.type;
        }
        function getTypeOfSymbol(symbol) {
            var checkFlags = ts.getCheckFlags(symbol);
            if (checkFlags & 65536 /* DeferredType */) {
                return getTypeOfSymbolWithDeferredType(symbol);
            }
            if (checkFlags & 1 /* Instantiated */) {
                return getTypeOfInstantiatedSymbol(symbol);
            }
            if (checkFlags & 262144 /* Mapped */) {
                return getTypeOfMappedSymbol(symbol);
            }
            if (checkFlags & 8192 /* ReverseMapped */) {
                return getTypeOfReverseMappedSymbol(symbol);
            }
            if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) {
                return getTypeOfVariableOrParameterOrProperty(symbol);
            }
            if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) {
                return getTypeOfFuncClassEnumModule(symbol);
            }
            if (symbol.flags & 8 /* EnumMember */) {
                return getTypeOfEnumMember(symbol);
            }
            if (symbol.flags & 98304 /* Accessor */) {
                return getTypeOfAccessors(symbol);
            }
            if (symbol.flags & 2097152 /* Alias */) {
                return getTypeOfAlias(symbol);
            }
            return errorType;
        }
        function isReferenceToType(type, target) {
            return type !== undefined
                && target !== undefined
                && (ts.getObjectFlags(type) & 4 /* Reference */) !== 0
                && type.target === target;
        }
        function getTargetType(type) {
            return ts.getObjectFlags(type) & 4 /* Reference */ ? type.target : type;
        }
        // TODO: GH#18217 If `checkBase` is undefined, we should not call this because this will always return false.
        function hasBaseType(type, checkBase) {
            return check(type);
            function check(type) {
                if (ts.getObjectFlags(type) & (3 /* ClassOrInterface */ | 4 /* Reference */)) {
                    var target = getTargetType(type);
                    return target === checkBase || ts.some(getBaseTypes(target), check);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    return ts.some(type.types, check);
                }
                return false;
            }
        }
        // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set.
        // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set
        // in-place and returns the same array.
        function appendTypeParameters(typeParameters, declarations) {
            for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) {
                var declaration = declarations_2[_i];
                typeParameters = ts.appendIfUnique(typeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)));
            }
            return typeParameters;
        }
        // Return the outer type parameters of a node or undefined if the node has no outer type parameters.
        function getOuterTypeParameters(node, includeThisTypes) {
            while (true) {
                node = node.parent; // TODO: GH#18217 Use SourceFile kind check instead
                if (node && ts.isBinaryExpression(node)) {
                    // prototype assignments get the outer type parameters of their constructor function
                    var assignmentKind = ts.getAssignmentDeclarationKind(node);
                    if (assignmentKind === 6 /* Prototype */ || assignmentKind === 3 /* PrototypeProperty */) {
                        var symbol = getSymbolOfNode(node.left);
                        if (symbol && symbol.parent && !ts.findAncestor(symbol.parent.valueDeclaration, function (d) { return node === d; })) {
                            node = symbol.parent.valueDeclaration;
                        }
                    }
                }
                if (!node) {
                    return undefined;
                }
                switch (node.kind) {
                    case 225 /* VariableStatement */:
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                    case 246 /* InterfaceDeclaration */:
                    case 165 /* CallSignature */:
                    case 166 /* ConstructSignature */:
                    case 160 /* MethodSignature */:
                    case 170 /* FunctionType */:
                    case 171 /* ConstructorType */:
                    case 300 /* JSDocFunctionType */:
                    case 244 /* FunctionDeclaration */:
                    case 161 /* MethodDeclaration */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                    case 247 /* TypeAliasDeclaration */:
                    case 321 /* JSDocTemplateTag */:
                    case 322 /* JSDocTypedefTag */:
                    case 316 /* JSDocEnumTag */:
                    case 315 /* JSDocCallbackTag */:
                    case 186 /* MappedType */:
                    case 180 /* ConditionalType */:
                        var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes);
                        if (node.kind === 186 /* MappedType */) {
                            return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)));
                        }
                        else if (node.kind === 180 /* ConditionalType */) {
                            return ts.concatenate(outerTypeParameters, getInferTypeParameters(node));
                        }
                        else if (node.kind === 225 /* VariableStatement */ && !ts.isInJSFile(node)) {
                            break;
                        }
                        var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node));
                        var thisType = includeThisTypes &&
                            (node.kind === 245 /* ClassDeclaration */ || node.kind === 214 /* ClassExpression */ || node.kind === 246 /* InterfaceDeclaration */ || isJSConstructor(node)) &&
                            getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType;
                        return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters;
                }
            }
        }
        // The outer type parameters are those defined by enclosing generic classes, methods, or functions.
        function getOuterTypeParametersOfClassOrInterface(symbol) {
            var declaration = symbol.flags & 32 /* Class */ ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 246 /* InterfaceDeclaration */);
            ts.Debug.assert(!!declaration, "Class was missing valueDeclaration -OR- non-class had no interface declarations");
            return getOuterTypeParameters(declaration);
        }
        // The local type parameters are the combined set of type parameters from all declarations of the class,
        // interface, or type alias.
        function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) {
            var result;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var node = _a[_i];
                if (node.kind === 246 /* InterfaceDeclaration */ ||
                    node.kind === 245 /* ClassDeclaration */ ||
                    node.kind === 214 /* ClassExpression */ ||
                    isJSConstructor(node) ||
                    ts.isTypeAlias(node)) {
                    var declaration = node;
                    result = appendTypeParameters(result, ts.getEffectiveTypeParameterDeclarations(declaration));
                }
            }
            return result;
        }
        // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus
        // its locally declared type parameters.
        function getTypeParametersOfClassOrInterface(symbol) {
            return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol));
        }
        // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single
        // rest parameter of type any[].
        function isMixinConstructorType(type) {
            var signatures = getSignaturesOfType(type, 1 /* Construct */);
            if (signatures.length === 1) {
                var s = signatures[0];
                return !s.typeParameters && s.parameters.length === 1 && signatureHasRestParameter(s) && getElementTypeOfArrayType(getTypeOfParameter(s.parameters[0])) === anyType;
            }
            return false;
        }
        function isConstructorType(type) {
            if (getSignaturesOfType(type, 1 /* Construct */).length > 0) {
                return true;
            }
            if (type.flags & 8650752 /* TypeVariable */) {
                var constraint = getBaseConstraintOfType(type);
                return !!constraint && isMixinConstructorType(constraint);
            }
            return false;
        }
        function getBaseTypeNodeOfClass(type) {
            return ts.getEffectiveBaseTypeNode(type.symbol.valueDeclaration);
        }
        function getConstructorsForTypeArguments(type, typeArgumentNodes, location) {
            var typeArgCount = ts.length(typeArgumentNodes);
            var isJavascript = ts.isInJSFile(location);
            return ts.filter(getSignaturesOfType(type, 1 /* Construct */), function (sig) { return (isJavascript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= ts.length(sig.typeParameters); });
        }
        function getInstantiatedConstructorsForTypeArguments(type, typeArgumentNodes, location) {
            var signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location);
            var typeArguments = ts.map(typeArgumentNodes, getTypeFromTypeNode);
            return ts.sameMap(signatures, function (sig) { return ts.some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, ts.isInJSFile(location)) : sig; });
        }
        /**
         * The base constructor of a class can resolve to
         * * undefinedType if the class has no extends clause,
         * * unknownType if an error occurred during resolution of the extends expression,
         * * nullType if the extends expression is the null value,
         * * anyType if the extends expression has type any, or
         * * an object type with at least one construct signature.
         */
        function getBaseConstructorTypeOfClass(type) {
            if (!type.resolvedBaseConstructorType) {
                var decl = type.symbol.valueDeclaration;
                var extended = ts.getEffectiveBaseTypeNode(decl);
                var baseTypeNode = getBaseTypeNodeOfClass(type);
                if (!baseTypeNode) {
                    return type.resolvedBaseConstructorType = undefinedType;
                }
                if (!pushTypeResolution(type, 1 /* ResolvedBaseConstructorType */)) {
                    return errorType;
                }
                var baseConstructorType = checkExpression(baseTypeNode.expression);
                if (extended && baseTypeNode !== extended) {
                    ts.Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag
                    checkExpression(extended.expression);
                }
                if (baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */)) {
                    // Resolving the members of a class requires us to resolve the base class of that class.
                    // We force resolution here such that we catch circularities now.
                    resolveStructuredTypeMembers(baseConstructorType);
                }
                if (!popTypeResolution()) {
                    error(type.symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol));
                    return type.resolvedBaseConstructorType = errorType;
                }
                if (!(baseConstructorType.flags & 1 /* Any */) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) {
                    var err = error(baseTypeNode.expression, ts.Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType));
                    if (baseConstructorType.flags & 262144 /* TypeParameter */) {
                        var constraint = getConstraintFromTypeParameter(baseConstructorType);
                        var ctorReturn = unknownType;
                        if (constraint) {
                            var ctorSig = getSignaturesOfType(constraint, 1 /* Construct */);
                            if (ctorSig[0]) {
                                ctorReturn = getReturnTypeOfSignature(ctorSig[0]);
                            }
                        }
                        ts.addRelatedInfo(err, ts.createDiagnosticForNode(baseConstructorType.symbol.declarations[0], ts.Diagnostics.Did_you_mean_for_0_to_be_constrained_to_type_new_args_Colon_any_1, symbolToString(baseConstructorType.symbol), typeToString(ctorReturn)));
                    }
                    return type.resolvedBaseConstructorType = errorType;
                }
                type.resolvedBaseConstructorType = baseConstructorType;
            }
            return type.resolvedBaseConstructorType;
        }
        function getImplementsTypes(type) {
            var resolvedImplementsTypes = ts.emptyArray;
            for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                var implementsTypeNodes = ts.getEffectiveImplementsTypeNodes(declaration);
                if (!implementsTypeNodes)
                    continue;
                for (var _b = 0, implementsTypeNodes_1 = implementsTypeNodes; _b < implementsTypeNodes_1.length; _b++) {
                    var node = implementsTypeNodes_1[_b];
                    var implementsType = getTypeFromTypeNode(node);
                    if (implementsType !== errorType) {
                        if (resolvedImplementsTypes === ts.emptyArray) {
                            resolvedImplementsTypes = [implementsType];
                        }
                        else {
                            resolvedImplementsTypes.push(implementsType);
                        }
                    }
                }
            }
            return resolvedImplementsTypes;
        }
        function getBaseTypes(type) {
            if (!type.resolvedBaseTypes) {
                if (type.objectFlags & 8 /* Tuple */) {
                    type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters || ts.emptyArray), type.readonly)];
                }
                else if (type.symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                    if (type.symbol.flags & 32 /* Class */) {
                        resolveBaseTypesOfClass(type);
                    }
                    if (type.symbol.flags & 64 /* Interface */) {
                        resolveBaseTypesOfInterface(type);
                    }
                }
                else {
                    ts.Debug.fail("type must be class or interface");
                }
            }
            return type.resolvedBaseTypes;
        }
        function resolveBaseTypesOfClass(type) {
            type.resolvedBaseTypes = ts.resolvingEmptyArray;
            var baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type));
            if (!(baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */ | 1 /* Any */))) {
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            var baseTypeNode = getBaseTypeNodeOfClass(type);
            var baseType;
            var originalBaseType = baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined;
            if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 /* Class */ &&
                areAllOuterTypeParametersApplied(originalBaseType)) {
                // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the
                // class and all return the instance type of the class. There is no need for further checks and we can apply the
                // type arguments in the same manner as a type reference to get the same error reporting experience.
                baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol);
            }
            else if (baseConstructorType.flags & 1 /* Any */) {
                baseType = baseConstructorType;
            }
            else {
                // The class derives from a "class-like" constructor function, check that we have at least one construct signature
                // with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere
                // we check that all instantiated signatures return the same type.
                var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode);
                if (!constructors.length) {
                    error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments);
                    return type.resolvedBaseTypes = ts.emptyArray;
                }
                baseType = getReturnTypeOfSignature(constructors[0]);
            }
            if (baseType === errorType) {
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            var reducedBaseType = getReducedType(baseType);
            if (!isValidBaseType(reducedBaseType)) {
                var elaboration = elaborateNeverIntersection(/*errorInfo*/ undefined, baseType);
                var diagnostic = ts.chainDiagnosticMessages(elaboration, ts.Diagnostics.Base_constructor_return_type_0_is_not_an_object_type_or_intersection_of_object_types_with_statically_known_members, typeToString(reducedBaseType));
                diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(baseTypeNode.expression, diagnostic));
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            if (type === reducedBaseType || hasBaseType(reducedBaseType, type)) {
                error(type.symbol.valueDeclaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */));
                return type.resolvedBaseTypes = ts.emptyArray;
            }
            if (type.resolvedBaseTypes === ts.resolvingEmptyArray) {
                // Circular reference, likely through instantiation of default parameters
                // (otherwise there'd be an error from hasBaseType) - this is fine, but `.members` should be reset
                // as `getIndexedAccessType` via `instantiateType` via `getTypeFromClassOrInterfaceReference` forces a
                // partial instantiation of the members without the base types fully resolved
                type.members = undefined;
            }
            return type.resolvedBaseTypes = [reducedBaseType];
        }
        function areAllOuterTypeParametersApplied(type) {
            // An unapplied type parameter has its symbol still the same as the matching argument symbol.
            // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked.
            var outerTypeParameters = type.outerTypeParameters;
            if (outerTypeParameters) {
                var last_1 = outerTypeParameters.length - 1;
                var typeArguments = getTypeArguments(type);
                return outerTypeParameters[last_1].symbol !== typeArguments[last_1].symbol;
            }
            return true;
        }
        // A valid base type is `any`, an object type or intersection of object types.
        function isValidBaseType(type) {
            if (type.flags & 262144 /* TypeParameter */) {
                var constraint = getBaseConstraintOfType(type);
                if (constraint) {
                    return isValidBaseType(constraint);
                }
            }
            // TODO: Given that we allow type parmeters here now, is this `!isGenericMappedType(type)` check really needed?
            // There's no reason a `T` should be allowed while a `Readonly<T>` should not.
            return !!(type.flags & (524288 /* Object */ | 67108864 /* NonPrimitive */ | 1 /* Any */) && !isGenericMappedType(type) ||
                type.flags & 2097152 /* Intersection */ && ts.every(type.types, isValidBaseType));
        }
        function resolveBaseTypesOfInterface(type) {
            type.resolvedBaseTypes = type.resolvedBaseTypes || ts.emptyArray;
            for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 246 /* InterfaceDeclaration */ && ts.getInterfaceBaseTypeNodes(declaration)) {
                    for (var _b = 0, _c = ts.getInterfaceBaseTypeNodes(declaration); _b < _c.length; _b++) {
                        var node = _c[_b];
                        var baseType = getReducedType(getTypeFromTypeNode(node));
                        if (baseType !== errorType) {
                            if (isValidBaseType(baseType)) {
                                if (type !== baseType && !hasBaseType(baseType, type)) {
                                    if (type.resolvedBaseTypes === ts.emptyArray) {
                                        type.resolvedBaseTypes = [baseType];
                                    }
                                    else {
                                        type.resolvedBaseTypes.push(baseType);
                                    }
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */));
                                }
                            }
                            else {
                                error(node, ts.Diagnostics.An_interface_can_only_extend_an_object_type_or_intersection_of_object_types_with_statically_known_members);
                            }
                        }
                    }
                }
            }
        }
        /**
         * Returns true if the interface given by the symbol is free of "this" references.
         *
         * Specifically, the result is true if the interface itself contains no references
         * to "this" in its body, if all base types are interfaces,
         * and if none of the base interfaces have a "this" type.
         */
        function isThislessInterface(symbol) {
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 246 /* InterfaceDeclaration */) {
                    if (declaration.flags & 128 /* ContainsThis */) {
                        return false;
                    }
                    var baseTypeNodes = ts.getInterfaceBaseTypeNodes(declaration);
                    if (baseTypeNodes) {
                        for (var _b = 0, baseTypeNodes_1 = baseTypeNodes; _b < baseTypeNodes_1.length; _b++) {
                            var node = baseTypeNodes_1[_b];
                            if (ts.isEntityNameExpression(node.expression)) {
                                var baseSymbol = resolveEntityName(node.expression, 788968 /* Type */, /*ignoreErrors*/ true);
                                if (!baseSymbol || !(baseSymbol.flags & 64 /* Interface */) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) {
                                    return false;
                                }
                            }
                        }
                    }
                }
            }
            return true;
        }
        function getDeclaredTypeOfClassOrInterface(symbol) {
            var links = getSymbolLinks(symbol);
            var originalLinks = links;
            if (!links.declaredType) {
                var kind = symbol.flags & 32 /* Class */ ? 1 /* Class */ : 2 /* Interface */;
                var merged = mergeJSSymbols(symbol, getAssignedClassSymbol(symbol.valueDeclaration));
                if (merged) {
                    // note:we overwrite links because we just cloned the symbol
                    symbol = links = merged;
                }
                var type = originalLinks.declaredType = links.declaredType = createObjectType(kind, symbol);
                var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol);
                var localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                // A class or interface is generic if it has type parameters or a "this" type. We always give classes a "this" type
                // because it is not feasible to analyze all members to determine if the "this" type escapes the class (in particular,
                // property types inferred from initializers and method return types inferred from return statements are very hard
                // to exhaustively analyze). We give interfaces a "this" type if we can't definitely determine that they are free of
                // "this" references.
                if (outerTypeParameters || localTypeParameters || kind === 1 /* Class */ || !isThislessInterface(symbol)) {
                    type.objectFlags |= 4 /* Reference */;
                    type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters);
                    type.outerTypeParameters = outerTypeParameters;
                    type.localTypeParameters = localTypeParameters;
                    type.instantiations = ts.createMap();
                    type.instantiations.set(getTypeListId(type.typeParameters), type);
                    type.target = type;
                    type.resolvedTypeArguments = type.typeParameters;
                    type.thisType = createTypeParameter(symbol);
                    type.thisType.isThisType = true;
                    type.thisType.constraint = type;
                }
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeAlias(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                // Note that we use the links object as the target here because the symbol object is used as the unique
                // identity for resolution of the 'type' property in SymbolLinks.
                if (!pushTypeResolution(symbol, 2 /* DeclaredType */)) {
                    return errorType;
                }
                var declaration = ts.Debug.checkDefined(ts.find(symbol.declarations, ts.isTypeAlias), "Type alias symbol with no valid declaration found");
                var typeNode = ts.isJSDocTypeAlias(declaration) ? declaration.typeExpression : declaration.type;
                // If typeNode is missing, we will error in checkJSDocTypedefTag.
                var type = typeNode ? getTypeFromTypeNode(typeNode) : errorType;
                if (popTypeResolution()) {
                    var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol);
                    if (typeParameters) {
                        // Initialize the instantiation cache for generic type aliases. The declared type corresponds to
                        // an instantiation of the type alias with the type parameters supplied as type arguments.
                        links.typeParameters = typeParameters;
                        links.instantiations = ts.createMap();
                        links.instantiations.set(getTypeListId(typeParameters), type);
                    }
                }
                else {
                    type = errorType;
                    error(ts.isNamedDeclaration(declaration) ? declaration.name : declaration || declaration, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol));
                }
                links.declaredType = type;
            }
            return links.declaredType;
        }
        function isStringConcatExpression(expr) {
            if (ts.isStringLiteralLike(expr)) {
                return true;
            }
            else if (expr.kind === 209 /* BinaryExpression */) {
                return isStringConcatExpression(expr.left) && isStringConcatExpression(expr.right);
            }
            return false;
        }
        function isLiteralEnumMember(member) {
            var expr = member.initializer;
            if (!expr) {
                return !(member.flags & 8388608 /* Ambient */);
            }
            switch (expr.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    return true;
                case 207 /* PrefixUnaryExpression */:
                    return expr.operator === 40 /* MinusToken */ &&
                        expr.operand.kind === 8 /* NumericLiteral */;
                case 75 /* Identifier */:
                    return ts.nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports.get(expr.escapedText);
                case 209 /* BinaryExpression */:
                    return isStringConcatExpression(expr);
                default:
                    return false;
            }
        }
        function getEnumKind(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.enumKind !== undefined) {
                return links.enumKind;
            }
            var hasNonLiteralMember = false;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var declaration = _a[_i];
                if (declaration.kind === 248 /* EnumDeclaration */) {
                    for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
                        var member = _c[_b];
                        if (member.initializer && ts.isStringLiteralLike(member.initializer)) {
                            return links.enumKind = 1 /* Literal */;
                        }
                        if (!isLiteralEnumMember(member)) {
                            hasNonLiteralMember = true;
                        }
                    }
                }
            }
            return links.enumKind = hasNonLiteralMember ? 0 /* Numeric */ : 1 /* Literal */;
        }
        function getBaseTypeOfEnumLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ && !(type.flags & 1048576 /* Union */) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)) : type;
        }
        function getDeclaredTypeOfEnum(symbol) {
            var links = getSymbolLinks(symbol);
            if (links.declaredType) {
                return links.declaredType;
            }
            if (getEnumKind(symbol) === 1 /* Literal */) {
                enumCount++;
                var memberTypeList = [];
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (declaration.kind === 248 /* EnumDeclaration */) {
                        for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) {
                            var member = _c[_b];
                            var value = getEnumMemberValue(member);
                            var memberType = getFreshTypeOfLiteralType(getLiteralType(value !== undefined ? value : 0, enumCount, getSymbolOfNode(member)));
                            getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType;
                            memberTypeList.push(getRegularTypeOfLiteralType(memberType));
                        }
                    }
                }
                if (memberTypeList.length) {
                    var enumType_1 = getUnionType(memberTypeList, 1 /* Literal */, symbol, /*aliasTypeArguments*/ undefined);
                    if (enumType_1.flags & 1048576 /* Union */) {
                        enumType_1.flags |= 1024 /* EnumLiteral */;
                        enumType_1.symbol = symbol;
                    }
                    return links.declaredType = enumType_1;
                }
            }
            var enumType = createType(32 /* Enum */);
            enumType.symbol = symbol;
            return links.declaredType = enumType;
        }
        function getDeclaredTypeOfEnumMember(symbol) {
            var links = getSymbolLinks(symbol);
            if (!links.declaredType) {
                var enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol));
                if (!links.declaredType) {
                    links.declaredType = enumType;
                }
            }
            return links.declaredType;
        }
        function getDeclaredTypeOfTypeParameter(symbol) {
            var links = getSymbolLinks(symbol);
            return links.declaredType || (links.declaredType = createTypeParameter(symbol));
        }
        function getDeclaredTypeOfAlias(symbol) {
            var links = getSymbolLinks(symbol);
            return links.declaredType || (links.declaredType = getDeclaredTypeOfSymbol(resolveAlias(symbol)));
        }
        function getDeclaredTypeOfSymbol(symbol) {
            return tryGetDeclaredTypeOfSymbol(symbol) || errorType;
        }
        function tryGetDeclaredTypeOfSymbol(symbol) {
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getDeclaredTypeOfClassOrInterface(symbol);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getDeclaredTypeOfTypeAlias(symbol);
            }
            if (symbol.flags & 262144 /* TypeParameter */) {
                return getDeclaredTypeOfTypeParameter(symbol);
            }
            if (symbol.flags & 384 /* Enum */) {
                return getDeclaredTypeOfEnum(symbol);
            }
            if (symbol.flags & 8 /* EnumMember */) {
                return getDeclaredTypeOfEnumMember(symbol);
            }
            if (symbol.flags & 2097152 /* Alias */) {
                return getDeclaredTypeOfAlias(symbol);
            }
            return undefined;
        }
        /**
         * A type is free of this references if it's the any, string, number, boolean, symbol, or void keyword, a string
         * literal type, an array with an element type that is free of this references, or a type reference that is
         * free of this references.
         */
        function isThislessType(node) {
            switch (node.kind) {
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 143 /* StringKeyword */:
                case 140 /* NumberKeyword */:
                case 151 /* BigIntKeyword */:
                case 128 /* BooleanKeyword */:
                case 144 /* SymbolKeyword */:
                case 141 /* ObjectKeyword */:
                case 110 /* VoidKeyword */:
                case 146 /* UndefinedKeyword */:
                case 100 /* NullKeyword */:
                case 137 /* NeverKeyword */:
                case 187 /* LiteralType */:
                    return true;
                case 174 /* ArrayType */:
                    return isThislessType(node.elementType);
                case 169 /* TypeReference */:
                    return !node.typeArguments || node.typeArguments.every(isThislessType);
            }
            return false;
        }
        /** A type parameter is thisless if its constraint is thisless, or if it has no constraint. */
        function isThislessTypeParameter(node) {
            var constraint = ts.getEffectiveConstraintOfTypeParameter(node);
            return !constraint || isThislessType(constraint);
        }
        /**
         * A variable-like declaration is free of this references if it has a type annotation
         * that is thisless, or if it has no type annotation and no initializer (and is thus of type any).
         */
        function isThislessVariableLikeDeclaration(node) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
            return typeNode ? isThislessType(typeNode) : !ts.hasInitializer(node);
        }
        /**
         * A function-like declaration is considered free of `this` references if it has a return type
         * annotation that is free of this references and if each parameter is thisless and if
         * each type parameter (if present) is thisless.
         */
        function isThislessFunctionLikeDeclaration(node) {
            var returnType = ts.getEffectiveReturnTypeNode(node);
            var typeParameters = ts.getEffectiveTypeParameterDeclarations(node);
            return (node.kind === 162 /* Constructor */ || (!!returnType && isThislessType(returnType))) &&
                node.parameters.every(isThislessVariableLikeDeclaration) &&
                typeParameters.every(isThislessTypeParameter);
        }
        /**
         * Returns true if the class or interface member given by the symbol is free of "this" references. The
         * function may return false for symbols that are actually free of "this" references because it is not
         * feasible to perform a complete analysis in all cases. In particular, property members with types
         * inferred from their initializers and function members with inferred return types are conservatively
         * assumed not to be free of "this" references.
         */
        function isThisless(symbol) {
            if (symbol.declarations && symbol.declarations.length === 1) {
                var declaration = symbol.declarations[0];
                if (declaration) {
                    switch (declaration.kind) {
                        case 159 /* PropertyDeclaration */:
                        case 158 /* PropertySignature */:
                            return isThislessVariableLikeDeclaration(declaration);
                        case 161 /* MethodDeclaration */:
                        case 160 /* MethodSignature */:
                        case 162 /* Constructor */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                            return isThislessFunctionLikeDeclaration(declaration);
                    }
                }
            }
            return false;
        }
        // The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true,
        // we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation.
        function createInstantiatedSymbolTable(symbols, mapper, mappingThisOnly) {
            var result = ts.createSymbolTable();
            for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
                var symbol = symbols_2[_i];
                result.set(symbol.escapedName, mappingThisOnly && isThisless(symbol) ? symbol : instantiateSymbol(symbol, mapper));
            }
            return result;
        }
        function addInheritedMembers(symbols, baseSymbols) {
            for (var _i = 0, baseSymbols_1 = baseSymbols; _i < baseSymbols_1.length; _i++) {
                var s = baseSymbols_1[_i];
                if (!symbols.has(s.escapedName) && !isStaticPrivateIdentifierProperty(s)) {
                    symbols.set(s.escapedName, s);
                }
            }
        }
        function isStaticPrivateIdentifierProperty(s) {
            return !!s.valueDeclaration && ts.isPrivateIdentifierPropertyDeclaration(s.valueDeclaration) && ts.hasModifier(s.valueDeclaration, 32 /* Static */);
        }
        function resolveDeclaredMembers(type) {
            if (!type.declaredProperties) {
                var symbol = type.symbol;
                var members = getMembersOfSymbol(symbol);
                type.declaredProperties = getNamedMembers(members);
                // Start with signatures at empty array in case of recursive types
                type.declaredCallSignatures = ts.emptyArray;
                type.declaredConstructSignatures = ts.emptyArray;
                type.declaredCallSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */));
                type.declaredConstructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */));
                type.declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                type.declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
            }
            return type;
        }
        /**
         * Indicates whether a type can be used as a property name.
         */
        function isTypeUsableAsPropertyName(type) {
            return !!(type.flags & 8576 /* StringOrNumberLiteralOrUnique */);
        }
        /**
         * Indicates whether a declaration name is definitely late-bindable.
         * A declaration name is only late-bindable if:
         * - It is a `ComputedPropertyName`.
         * - Its expression is an `Identifier` or either a `PropertyAccessExpression` an
         * `ElementAccessExpression` consisting only of these same three types of nodes.
         * - The type of its expression is a string or numeric literal type, or is a `unique symbol` type.
         */
        function isLateBindableName(node) {
            if (!ts.isComputedPropertyName(node) && !ts.isElementAccessExpression(node)) {
                return false;
            }
            var expr = ts.isComputedPropertyName(node) ? node.expression : node.argumentExpression;
            return ts.isEntityNameExpression(expr)
                && isTypeUsableAsPropertyName(ts.isComputedPropertyName(node) ? checkComputedPropertyName(node) : checkExpressionCached(expr));
        }
        function isLateBoundName(name) {
            return name.charCodeAt(0) === 95 /* _ */ &&
                name.charCodeAt(1) === 95 /* _ */ &&
                name.charCodeAt(2) === 64 /* at */;
        }
        /**
         * Indicates whether a declaration has a late-bindable dynamic name.
         */
        function hasLateBindableName(node) {
            var name = ts.getNameOfDeclaration(node);
            return !!name && isLateBindableName(name);
        }
        /**
         * Indicates whether a declaration has a dynamic name that cannot be late-bound.
         */
        function hasNonBindableDynamicName(node) {
            return ts.hasDynamicName(node) && !hasLateBindableName(node);
        }
        /**
         * Indicates whether a declaration name is a dynamic name that cannot be late-bound.
         */
        function isNonBindableDynamicName(node) {
            return ts.isDynamicName(node) && !isLateBindableName(node);
        }
        /**
         * Gets the symbolic name for a member from its type.
         */
        function getPropertyNameFromType(type) {
            if (type.flags & 8192 /* UniqueESSymbol */) {
                return type.escapedName;
            }
            if (type.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */)) {
                return ts.escapeLeadingUnderscores("" + type.value);
            }
            return ts.Debug.fail();
        }
        /**
         * Adds a declaration to a late-bound dynamic member. This performs the same function for
         * late-bound members that `addDeclarationToSymbol` in binder.ts performs for early-bound
         * members.
         */
        function addDeclarationToLateBoundSymbol(symbol, member, symbolFlags) {
            ts.Debug.assert(!!(ts.getCheckFlags(symbol) & 4096 /* Late */), "Expected a late-bound symbol.");
            symbol.flags |= symbolFlags;
            getSymbolLinks(member.symbol).lateSymbol = symbol;
            if (!symbol.declarations) {
                symbol.declarations = [member];
            }
            else {
                symbol.declarations.push(member);
            }
            if (symbolFlags & 111551 /* Value */) {
                if (!symbol.valueDeclaration || symbol.valueDeclaration.kind !== member.kind) {
                    symbol.valueDeclaration = member;
                }
            }
        }
        /**
         * Performs late-binding of a dynamic member. This performs the same function for
         * late-bound members that `declareSymbol` in binder.ts performs for early-bound
         * members.
         *
         * If a symbol is a dynamic name from a computed property, we perform an additional "late"
         * binding phase to attempt to resolve the name for the symbol from the type of the computed
         * property's expression. If the type of the expression is a string-literal, numeric-literal,
         * or unique symbol type, we can use that type as the name of the symbol.
         *
         * For example, given:
         *
         *   const x = Symbol();
         *
         *   interface I {
         *     [x]: number;
         *   }
         *
         * The binder gives the property `[x]: number` a special symbol with the name "__computed".
         * In the late-binding phase we can type-check the expression `x` and see that it has a
         * unique symbol type which we can then use as the name of the member. This allows users
         * to define custom symbols that can be used in the members of an object type.
         *
         * @param parent The containing symbol for the member.
         * @param earlySymbols The early-bound symbols of the parent.
         * @param lateSymbols The late-bound symbols of the parent.
         * @param decl The member to bind.
         */
        function lateBindMember(parent, earlySymbols, lateSymbols, decl) {
            ts.Debug.assert(!!decl.symbol, "The member is expected to have a symbol.");
            var links = getNodeLinks(decl);
            if (!links.resolvedSymbol) {
                // In the event we attempt to resolve the late-bound name of this member recursively,
                // fall back to the early-bound name of this member.
                links.resolvedSymbol = decl.symbol;
                var declName = ts.isBinaryExpression(decl) ? decl.left : decl.name;
                var type = ts.isElementAccessExpression(declName) ? checkExpressionCached(declName.argumentExpression) : checkComputedPropertyName(declName);
                if (isTypeUsableAsPropertyName(type)) {
                    var memberName = getPropertyNameFromType(type);
                    var symbolFlags = decl.symbol.flags;
                    // Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations.
                    var lateSymbol = lateSymbols.get(memberName);
                    if (!lateSymbol)
                        lateSymbols.set(memberName, lateSymbol = createSymbol(0 /* None */, memberName, 4096 /* Late */));
                    // Report an error if a late-bound member has the same name as an early-bound member,
                    // or if we have another early-bound symbol declaration with the same name and
                    // conflicting flags.
                    var earlySymbol = earlySymbols && earlySymbols.get(memberName);
                    if (lateSymbol.flags & getExcludedSymbolFlags(symbolFlags) || earlySymbol) {
                        // If we have an existing early-bound member, combine its declarations so that we can
                        // report an error at each declaration.
                        var declarations = earlySymbol ? ts.concatenate(earlySymbol.declarations, lateSymbol.declarations) : lateSymbol.declarations;
                        var name_3 = !(type.flags & 8192 /* UniqueESSymbol */) && ts.unescapeLeadingUnderscores(memberName) || ts.declarationNameToString(declName);
                        ts.forEach(declarations, function (declaration) { return error(ts.getNameOfDeclaration(declaration) || declaration, ts.Diagnostics.Property_0_was_also_declared_here, name_3); });
                        error(declName || decl, ts.Diagnostics.Duplicate_property_0, name_3);
                        lateSymbol = createSymbol(0 /* None */, memberName, 4096 /* Late */);
                    }
                    lateSymbol.nameType = type;
                    addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags);
                    if (lateSymbol.parent) {
                        ts.Debug.assert(lateSymbol.parent === parent, "Existing symbol parent should match new one");
                    }
                    else {
                        lateSymbol.parent = parent;
                    }
                    return links.resolvedSymbol = lateSymbol;
                }
            }
            return links.resolvedSymbol;
        }
        function getResolvedMembersOrExportsOfSymbol(symbol, resolutionKind) {
            var links = getSymbolLinks(symbol);
            if (!links[resolutionKind]) {
                var isStatic = resolutionKind === "resolvedExports" /* resolvedExports */;
                var earlySymbols = !isStatic ? symbol.members :
                    symbol.flags & 1536 /* Module */ ? getExportsOfModuleWorker(symbol) :
                        symbol.exports;
                // In the event we recursively resolve the members/exports of the symbol, we
                // set the initial value of resolvedMembers/resolvedExports to the early-bound
                // members/exports of the symbol.
                links[resolutionKind] = earlySymbols || emptySymbols;
                // fill in any as-yet-unresolved late-bound members.
                var lateSymbols = ts.createSymbolTable();
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var members = ts.getMembersOfDeclaration(decl);
                    if (members) {
                        for (var _b = 0, members_5 = members; _b < members_5.length; _b++) {
                            var member = members_5[_b];
                            if (isStatic === ts.hasStaticModifier(member) && hasLateBindableName(member)) {
                                lateBindMember(symbol, earlySymbols, lateSymbols, member);
                            }
                        }
                    }
                }
                var assignments = symbol.assignmentDeclarationMembers;
                if (assignments) {
                    var decls = ts.arrayFrom(assignments.values());
                    for (var _c = 0, decls_1 = decls; _c < decls_1.length; _c++) {
                        var member = decls_1[_c];
                        var assignmentKind = ts.getAssignmentDeclarationKind(member);
                        var isInstanceMember = assignmentKind === 3 /* PrototypeProperty */
                            || assignmentKind === 4 /* ThisProperty */
                            || assignmentKind === 9 /* ObjectDefinePrototypeProperty */
                            || assignmentKind === 6 /* Prototype */; // A straight `Prototype` assignment probably can never have a computed name
                        if (isStatic === !isInstanceMember && hasLateBindableName(member)) {
                            lateBindMember(symbol, earlySymbols, lateSymbols, member);
                        }
                    }
                }
                links[resolutionKind] = combineSymbolTables(earlySymbols, lateSymbols) || emptySymbols;
            }
            return links[resolutionKind];
        }
        /**
         * Gets a SymbolTable containing both the early- and late-bound members of a symbol.
         *
         * For a description of late-binding, see `lateBindMember`.
         */
        function getMembersOfSymbol(symbol) {
            return symbol.flags & 6256 /* LateBindingContainer */
                ? getResolvedMembersOrExportsOfSymbol(symbol, "resolvedMembers" /* resolvedMembers */)
                : symbol.members || emptySymbols;
        }
        /**
         * If a symbol is the dynamic name of the member of an object type, get the late-bound
         * symbol of the member.
         *
         * For a description of late-binding, see `lateBindMember`.
         */
        function getLateBoundSymbol(symbol) {
            if (symbol.flags & 106500 /* ClassMember */ && symbol.escapedName === "__computed" /* Computed */) {
                var links = getSymbolLinks(symbol);
                if (!links.lateSymbol && ts.some(symbol.declarations, hasLateBindableName)) {
                    // force late binding of members/exports. This will set the late-bound symbol
                    var parent = getMergedSymbol(symbol.parent);
                    if (ts.some(symbol.declarations, ts.hasStaticModifier)) {
                        getExportsOfSymbol(parent);
                    }
                    else {
                        getMembersOfSymbol(parent);
                    }
                }
                return links.lateSymbol || (links.lateSymbol = symbol);
            }
            return symbol;
        }
        function getTypeWithThisArgument(type, thisArgument, needApparentType) {
            if (ts.getObjectFlags(type) & 4 /* Reference */) {
                var target = type.target;
                var typeArguments = getTypeArguments(type);
                if (ts.length(target.typeParameters) === ts.length(typeArguments)) {
                    var ref = createTypeReference(target, ts.concatenate(typeArguments, [thisArgument || target.thisType]));
                    return needApparentType ? getApparentType(ref) : ref;
                }
            }
            else if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, function (t) { return getTypeWithThisArgument(t, thisArgument, needApparentType); }));
            }
            return needApparentType ? getApparentType(type) : type;
        }
        function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) {
            var mapper;
            var members;
            var callSignatures;
            var constructSignatures;
            var stringIndexInfo;
            var numberIndexInfo;
            if (ts.rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) {
                members = source.symbol ? getMembersOfSymbol(source.symbol) : ts.createSymbolTable(source.declaredProperties);
                callSignatures = source.declaredCallSignatures;
                constructSignatures = source.declaredConstructSignatures;
                stringIndexInfo = source.declaredStringIndexInfo;
                numberIndexInfo = source.declaredNumberIndexInfo;
            }
            else {
                mapper = createTypeMapper(typeParameters, typeArguments);
                members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1);
                callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper);
                constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper);
                stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper);
                numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper);
            }
            var baseTypes = getBaseTypes(source);
            if (baseTypes.length) {
                if (source.symbol && members === getMembersOfSymbol(source.symbol)) {
                    members = ts.createSymbolTable(source.declaredProperties);
                }
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
                var thisArgument = ts.lastOrUndefined(typeArguments);
                for (var _i = 0, baseTypes_1 = baseTypes; _i < baseTypes_1.length; _i++) {
                    var baseType = baseTypes_1[_i];
                    var instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType;
                    addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType));
                    callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, 0 /* Call */));
                    constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, 1 /* Construct */));
                    if (!stringIndexInfo) {
                        stringIndexInfo = instantiatedBaseType === anyType ?
                            createIndexInfo(anyType, /*isReadonly*/ false) :
                            getIndexInfoOfType(instantiatedBaseType, 0 /* String */);
                    }
                    numberIndexInfo = numberIndexInfo || getIndexInfoOfType(instantiatedBaseType, 1 /* Number */);
                }
            }
            setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function resolveClassOrInterfaceMembers(type) {
            resolveObjectTypeMembers(type, resolveDeclaredMembers(type), ts.emptyArray, ts.emptyArray);
        }
        function resolveTypeReferenceMembers(type) {
            var source = resolveDeclaredMembers(type.target);
            var typeParameters = ts.concatenate(source.typeParameters, [source.thisType]);
            var typeArguments = getTypeArguments(type);
            var paddedTypeArguments = typeArguments.length === typeParameters.length ? typeArguments : ts.concatenate(typeArguments, [type]);
            resolveObjectTypeMembers(type, source, typeParameters, paddedTypeArguments);
        }
        function createSignature(declaration, typeParameters, thisParameter, parameters, resolvedReturnType, resolvedTypePredicate, minArgumentCount, flags) {
            var sig = new Signature(checker, flags);
            sig.declaration = declaration;
            sig.typeParameters = typeParameters;
            sig.parameters = parameters;
            sig.thisParameter = thisParameter;
            sig.resolvedReturnType = resolvedReturnType;
            sig.resolvedTypePredicate = resolvedTypePredicate;
            sig.minArgumentCount = minArgumentCount;
            sig.target = undefined;
            sig.mapper = undefined;
            sig.unionSignatures = undefined;
            return sig;
        }
        function cloneSignature(sig) {
            var result = createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & 3 /* PropagatingFlags */);
            result.target = sig.target;
            result.mapper = sig.mapper;
            result.unionSignatures = sig.unionSignatures;
            return result;
        }
        function createUnionSignature(signature, unionSignatures) {
            var result = cloneSignature(signature);
            result.unionSignatures = unionSignatures;
            result.target = undefined;
            result.mapper = undefined;
            return result;
        }
        function getOptionalCallSignature(signature, callChainFlags) {
            if ((signature.flags & 12 /* CallChainFlags */) === callChainFlags) {
                return signature;
            }
            if (!signature.optionalCallSignatureCache) {
                signature.optionalCallSignatureCache = {};
            }
            var key = callChainFlags === 4 /* IsInnerCallChain */ ? "inner" : "outer";
            return signature.optionalCallSignatureCache[key]
                || (signature.optionalCallSignatureCache[key] = createOptionalCallSignature(signature, callChainFlags));
        }
        function createOptionalCallSignature(signature, callChainFlags) {
            ts.Debug.assert(callChainFlags === 4 /* IsInnerCallChain */ || callChainFlags === 8 /* IsOuterCallChain */, "An optional call signature can either be for an inner call chain or an outer call chain, but not both.");
            var result = cloneSignature(signature);
            result.flags |= callChainFlags;
            return result;
        }
        function getExpandedParameters(sig) {
            if (signatureHasRestParameter(sig)) {
                var restIndex_1 = sig.parameters.length - 1;
                var restParameter = sig.parameters[restIndex_1];
                var restType = getTypeOfSymbol(restParameter);
                if (isTupleType(restType)) {
                    var elementTypes = getTypeArguments(restType);
                    var minLength_1 = restType.target.minLength;
                    var tupleRestIndex_1 = restType.target.hasRestElement ? elementTypes.length - 1 : -1;
                    var restParams = ts.map(elementTypes, function (t, i) {
                        var name = getParameterNameAtPosition(sig, restIndex_1 + i);
                        var checkFlags = i === tupleRestIndex_1 ? 32768 /* RestParameter */ :
                            i >= minLength_1 ? 16384 /* OptionalParameter */ : 0;
                        var symbol = createSymbol(1 /* FunctionScopedVariable */, name, checkFlags);
                        symbol.type = i === tupleRestIndex_1 ? createArrayType(t) : t;
                        return symbol;
                    });
                    return ts.concatenate(sig.parameters.slice(0, restIndex_1), restParams);
                }
            }
            return sig.parameters;
        }
        function getDefaultConstructSignatures(classType) {
            var baseConstructorType = getBaseConstructorTypeOfClass(classType);
            var baseSignatures = getSignaturesOfType(baseConstructorType, 1 /* Construct */);
            if (baseSignatures.length === 0) {
                return [createSignature(undefined, classType.localTypeParameters, undefined, ts.emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */)];
            }
            var baseTypeNode = getBaseTypeNodeOfClass(classType);
            var isJavaScript = ts.isInJSFile(baseTypeNode);
            var typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode);
            var typeArgCount = ts.length(typeArguments);
            var result = [];
            for (var _i = 0, baseSignatures_1 = baseSignatures; _i < baseSignatures_1.length; _i++) {
                var baseSig = baseSignatures_1[_i];
                var minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters);
                var typeParamCount = ts.length(baseSig.typeParameters);
                if (isJavaScript || typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) {
                    var sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig);
                    sig.typeParameters = classType.localTypeParameters;
                    sig.resolvedReturnType = classType;
                    result.push(sig);
                }
            }
            return result;
        }
        function findMatchingSignature(signatureList, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes) {
            for (var _i = 0, signatureList_1 = signatureList; _i < signatureList_1.length; _i++) {
                var s = signatureList_1[_i];
                if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, partialMatch ? compareTypesSubtypeOf : compareTypesIdentical)) {
                    return s;
                }
            }
        }
        function findMatchingSignatures(signatureLists, signature, listIndex) {
            if (signature.typeParameters) {
                // We require an exact match for generic signatures, so we only return signatures from the first
                // signature list and only if they have exact matches in the other signature lists.
                if (listIndex > 0) {
                    return undefined;
                }
                for (var i = 1; i < signatureLists.length; i++) {
                    if (!findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false)) {
                        return undefined;
                    }
                }
                return [signature];
            }
            var result;
            for (var i = 0; i < signatureLists.length; i++) {
                // Allow matching non-generic signatures to have excess parameters and different return types.
                // Prefer matching this types if possible.
                var match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true);
                if (!match) {
                    return undefined;
                }
                result = ts.appendIfUnique(result, match);
            }
            return result;
        }
        // The signatures of a union type are those signatures that are present in each of the constituent types.
        // Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional
        // parameters and may differ in return types. When signatures differ in return types, the resulting return
        // type is the union of the constituent return types.
        function getUnionSignatures(signatureLists) {
            var result;
            var indexWithLengthOverOne;
            for (var i = 0; i < signatureLists.length; i++) {
                if (signatureLists[i].length === 0)
                    return ts.emptyArray;
                if (signatureLists[i].length > 1) {
                    indexWithLengthOverOne = indexWithLengthOverOne === undefined ? i : -1; // -1 is a signal there are multiple overload sets
                }
                for (var _i = 0, _a = signatureLists[i]; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    // Only process signatures with parameter lists that aren't already in the result list
                    if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ true)) {
                        var unionSignatures = findMatchingSignatures(signatureLists, signature, i);
                        if (unionSignatures) {
                            var s = signature;
                            // Union the result types when more than one signature matches
                            if (unionSignatures.length > 1) {
                                var thisParameter = signature.thisParameter;
                                var firstThisParameterOfUnionSignatures = ts.forEach(unionSignatures, function (sig) { return sig.thisParameter; });
                                if (firstThisParameterOfUnionSignatures) {
                                    var thisType = getIntersectionType(ts.mapDefined(unionSignatures, function (sig) { return sig.thisParameter && getTypeOfSymbol(sig.thisParameter); }));
                                    thisParameter = createSymbolWithType(firstThisParameterOfUnionSignatures, thisType);
                                }
                                s = createUnionSignature(signature, unionSignatures);
                                s.thisParameter = thisParameter;
                            }
                            (result || (result = [])).push(s);
                        }
                    }
                }
            }
            if (!ts.length(result) && indexWithLengthOverOne !== -1) {
                // No sufficiently similar signature existed to subsume all the other signatures in the union - time to see if we can make a single
                // signature that handles all over them. We only do this when there are overloads in only one constituent.
                // (Overloads are conditional in nature and having overloads in multiple constituents would necessitate making a power set of
                // signatures from the type, whose ordering would be non-obvious)
                var masterList = signatureLists[indexWithLengthOverOne !== undefined ? indexWithLengthOverOne : 0];
                var results = masterList.slice();
                var _loop_9 = function (signatures) {
                    if (signatures !== masterList) {
                        var signature_1 = signatures[0];
                        ts.Debug.assert(!!signature_1, "getUnionSignatures bails early on empty signature lists and should not have empty lists on second pass");
                        results = signature_1.typeParameters && ts.some(results, function (s) { return !!s.typeParameters; }) ? undefined : ts.map(results, function (sig) { return combineSignaturesOfUnionMembers(sig, signature_1); });
                        if (!results) {
                            return "break";
                        }
                    }
                };
                for (var _b = 0, signatureLists_1 = signatureLists; _b < signatureLists_1.length; _b++) {
                    var signatures = signatureLists_1[_b];
                    var state_3 = _loop_9(signatures);
                    if (state_3 === "break")
                        break;
                }
                result = results;
            }
            return result || ts.emptyArray;
        }
        function combineUnionThisParam(left, right) {
            if (!left || !right) {
                return left || right;
            }
            // A signature `this` type might be a read or a write position... It's very possible that it should be invariant
            // and we should refuse to merge signatures if there are `this` types and they do not match. However, so as to be
            // permissive when calling, for now, we'll intersect the `this` types just like we do for param types in union signatures.
            var thisType = getIntersectionType([getTypeOfSymbol(left), getTypeOfSymbol(right)]);
            return createSymbolWithType(left, thisType);
        }
        function combineUnionParameters(left, right) {
            var leftCount = getParameterCount(left);
            var rightCount = getParameterCount(right);
            var longest = leftCount >= rightCount ? left : right;
            var shorter = longest === left ? right : left;
            var longestCount = longest === left ? leftCount : rightCount;
            var eitherHasEffectiveRest = (hasEffectiveRestParameter(left) || hasEffectiveRestParameter(right));
            var needsExtraRestElement = eitherHasEffectiveRest && !hasEffectiveRestParameter(longest);
            var params = new Array(longestCount + (needsExtraRestElement ? 1 : 0));
            for (var i = 0; i < longestCount; i++) {
                var longestParamType = tryGetTypeAtPosition(longest, i);
                var shorterParamType = tryGetTypeAtPosition(shorter, i) || unknownType;
                var unionParamType = getIntersectionType([longestParamType, shorterParamType]);
                var isRestParam = eitherHasEffectiveRest && !needsExtraRestElement && i === (longestCount - 1);
                var isOptional = i >= getMinArgumentCount(longest) && i >= getMinArgumentCount(shorter);
                var leftName = i >= leftCount ? undefined : getParameterNameAtPosition(left, i);
                var rightName = i >= rightCount ? undefined : getParameterNameAtPosition(right, i);
                var paramName = leftName === rightName ? leftName :
                    !leftName ? rightName :
                        !rightName ? leftName :
                            undefined;
                var paramSymbol = createSymbol(1 /* FunctionScopedVariable */ | (isOptional && !isRestParam ? 16777216 /* Optional */ : 0), paramName || "arg" + i);
                paramSymbol.type = isRestParam ? createArrayType(unionParamType) : unionParamType;
                params[i] = paramSymbol;
            }
            if (needsExtraRestElement) {
                var restParamSymbol = createSymbol(1 /* FunctionScopedVariable */, "args");
                restParamSymbol.type = createArrayType(getTypeAtPosition(shorter, longestCount));
                params[longestCount] = restParamSymbol;
            }
            return params;
        }
        function combineSignaturesOfUnionMembers(left, right) {
            var declaration = left.declaration;
            var params = combineUnionParameters(left, right);
            var thisParam = combineUnionThisParam(left.thisParameter, right.thisParameter);
            var minArgCount = Math.max(left.minArgumentCount, right.minArgumentCount);
            var result = createSignature(declaration, left.typeParameters || right.typeParameters, thisParam, params, 
            /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, minArgCount, (left.flags | right.flags) & 3 /* PropagatingFlags */);
            result.unionSignatures = ts.concatenate(left.unionSignatures || [left], [right]);
            return result;
        }
        function getUnionIndexInfo(types, kind) {
            var indexTypes = [];
            var isAnyReadonly = false;
            for (var _i = 0, types_3 = types; _i < types_3.length; _i++) {
                var type = types_3[_i];
                var indexInfo = getIndexInfoOfType(getApparentType(type), kind);
                if (!indexInfo) {
                    return undefined;
                }
                indexTypes.push(indexInfo.type);
                isAnyReadonly = isAnyReadonly || indexInfo.isReadonly;
            }
            return createIndexInfo(getUnionType(indexTypes, 2 /* Subtype */), isAnyReadonly);
        }
        function resolveUnionTypeMembers(type) {
            // The members and properties collections are empty for union types. To get all properties of a union
            // type use getPropertiesOfType (only the language service uses this).
            var callSignatures = getUnionSignatures(ts.map(type.types, function (t) { return t === globalFunctionType ? [unknownSignature] : getSignaturesOfType(t, 0 /* Call */); }));
            var constructSignatures = getUnionSignatures(ts.map(type.types, function (t) { return getSignaturesOfType(t, 1 /* Construct */); }));
            var stringIndexInfo = getUnionIndexInfo(type.types, 0 /* String */);
            var numberIndexInfo = getUnionIndexInfo(type.types, 1 /* Number */);
            setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
        }
        function intersectTypes(type1, type2) {
            return !type1 ? type2 : !type2 ? type1 : getIntersectionType([type1, type2]);
        }
        function intersectIndexInfos(info1, info2) {
            return !info1 ? info2 : !info2 ? info1 : createIndexInfo(getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly);
        }
        function unionSpreadIndexInfos(info1, info2) {
            return info1 && info2 && createIndexInfo(getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly);
        }
        function findMixins(types) {
            var constructorTypeCount = ts.countWhere(types, function (t) { return getSignaturesOfType(t, 1 /* Construct */).length > 0; });
            var mixinFlags = ts.map(types, isMixinConstructorType);
            if (constructorTypeCount > 0 && constructorTypeCount === ts.countWhere(mixinFlags, function (b) { return b; })) {
                var firstMixinIndex = mixinFlags.indexOf(/*searchElement*/ true);
                mixinFlags[firstMixinIndex] = false;
            }
            return mixinFlags;
        }
        function includeMixinType(type, types, mixinFlags, index) {
            var mixedTypes = [];
            for (var i = 0; i < types.length; i++) {
                if (i === index) {
                    mixedTypes.push(type);
                }
                else if (mixinFlags[i]) {
                    mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], 1 /* Construct */)[0]));
                }
            }
            return getIntersectionType(mixedTypes);
        }
        function resolveIntersectionTypeMembers(type) {
            // The members and properties collections are empty for intersection types. To get all properties of an
            // intersection type use getPropertiesOfType (only the language service uses this).
            var callSignatures;
            var constructSignatures;
            var stringIndexInfo;
            var numberIndexInfo;
            var types = type.types;
            var mixinFlags = findMixins(types);
            var mixinCount = ts.countWhere(mixinFlags, function (b) { return b; });
            var _loop_10 = function (i) {
                var t = type.types[i];
                // When an intersection type contains mixin constructor types, the construct signatures from
                // those types are discarded and their return types are mixed into the return types of all
                // other construct signatures in the intersection type. For example, the intersection type
                // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature
                // 'new(s: string) => A & B'.
                if (!mixinFlags[i]) {
                    var signatures = getSignaturesOfType(t, 1 /* Construct */);
                    if (signatures.length && mixinCount > 0) {
                        signatures = ts.map(signatures, function (s) {
                            var clone = cloneSignature(s);
                            clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, mixinFlags, i);
                            return clone;
                        });
                    }
                    constructSignatures = appendSignatures(constructSignatures, signatures);
                }
                callSignatures = appendSignatures(callSignatures, getSignaturesOfType(t, 0 /* Call */));
                stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, 0 /* String */));
                numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, 1 /* Number */));
            };
            for (var i = 0; i < types.length; i++) {
                _loop_10(i);
            }
            setStructuredTypeMembers(type, emptySymbols, callSignatures || ts.emptyArray, constructSignatures || ts.emptyArray, stringIndexInfo, numberIndexInfo);
        }
        function appendSignatures(signatures, newSignatures) {
            var _loop_11 = function (sig) {
                if (!signatures || ts.every(signatures, function (s) { return !compareSignaturesIdentical(s, sig, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, compareTypesIdentical); })) {
                    signatures = ts.append(signatures, sig);
                }
            };
            for (var _i = 0, newSignatures_1 = newSignatures; _i < newSignatures_1.length; _i++) {
                var sig = newSignatures_1[_i];
                _loop_11(sig);
            }
            return signatures;
        }
        /**
         * Converts an AnonymousType to a ResolvedType.
         */
        function resolveAnonymousTypeMembers(type) {
            var symbol = getMergedSymbol(type.symbol);
            if (type.target) {
                setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
                var members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false);
                var callSignatures = instantiateSignatures(getSignaturesOfType(type.target, 0 /* Call */), type.mapper);
                var constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, 1 /* Construct */), type.mapper);
                var stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 0 /* String */), type.mapper);
                var numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 1 /* Number */), type.mapper);
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else if (symbol.flags & 2048 /* TypeLiteral */) {
                setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
                var members = getMembersOfSymbol(symbol);
                var callSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */));
                var constructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */));
                var stringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */);
                var numberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */);
                setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo);
            }
            else {
                // Combinations of function, class, enum and module
                var members = emptySymbols;
                var stringIndexInfo = void 0;
                if (symbol.exports) {
                    members = getExportsOfSymbol(symbol);
                    if (symbol === globalThisSymbol) {
                        var varsOnly_1 = ts.createMap();
                        members.forEach(function (p) {
                            if (!(p.flags & 418 /* BlockScoped */)) {
                                varsOnly_1.set(p.escapedName, p);
                            }
                        });
                        members = varsOnly_1;
                    }
                }
                setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, undefined, undefined);
                if (symbol.flags & 32 /* Class */) {
                    var classType = getDeclaredTypeOfClassOrInterface(symbol);
                    var baseConstructorType = getBaseConstructorTypeOfClass(classType);
                    if (baseConstructorType.flags & (524288 /* Object */ | 2097152 /* Intersection */ | 8650752 /* TypeVariable */)) {
                        members = ts.createSymbolTable(getNamedMembers(members));
                        addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
                    }
                    else if (baseConstructorType === anyType) {
                        stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
                    }
                }
                var numberIndexInfo = symbol.flags & 384 /* Enum */ && (getDeclaredTypeOfSymbol(symbol).flags & 32 /* Enum */ ||
                    ts.some(type.properties, function (prop) { return !!(getTypeOfSymbol(prop).flags & 296 /* NumberLike */); })) ? enumNumberIndexInfo : undefined;
                setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
                // We resolve the members before computing the signatures because a signature may use
                // typeof with a qualified name expression that circularly references the type we are
                // in the process of resolving (see issue #6072). The temporarily empty signature list
                // will never be observed because a qualified name can't reference signatures.
                if (symbol.flags & (16 /* Function */ | 8192 /* Method */)) {
                    type.callSignatures = getSignaturesOfSymbol(symbol);
                }
                // And likewise for construct signatures for classes
                if (symbol.flags & 32 /* Class */) {
                    var classType_1 = getDeclaredTypeOfClassOrInterface(symbol);
                    var constructSignatures = symbol.members ? getSignaturesOfSymbol(symbol.members.get("__constructor" /* Constructor */)) : ts.emptyArray;
                    if (symbol.flags & 16 /* Function */) {
                        constructSignatures = ts.addRange(constructSignatures.slice(), ts.mapDefined(type.callSignatures, function (sig) { return isJSConstructor(sig.declaration) ?
                            createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType_1, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & 3 /* PropagatingFlags */) :
                            undefined; }));
                    }
                    if (!constructSignatures.length) {
                        constructSignatures = getDefaultConstructSignatures(classType_1);
                    }
                    type.constructSignatures = constructSignatures;
                }
            }
        }
        function resolveReverseMappedTypeMembers(type) {
            var indexInfo = getIndexInfoOfType(type.source, 0 /* String */);
            var modifiers = getMappedTypeModifiers(type.mappedType);
            var readonlyMask = modifiers & 1 /* IncludeReadonly */ ? false : true;
            var optionalMask = modifiers & 4 /* IncludeOptional */ ? 0 : 16777216 /* Optional */;
            var stringIndexInfo = indexInfo && createIndexInfo(inferReverseMappedType(indexInfo.type, type.mappedType, type.constraintType), readonlyMask && indexInfo.isReadonly);
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfType(type.source); _i < _a.length; _i++) {
                var prop = _a[_i];
                var checkFlags = 8192 /* ReverseMapped */ | (readonlyMask && isReadonlySymbol(prop) ? 8 /* Readonly */ : 0);
                var inferredProp = createSymbol(4 /* Property */ | prop.flags & optionalMask, prop.escapedName, checkFlags);
                inferredProp.declarations = prop.declarations;
                inferredProp.nameType = getSymbolLinks(prop).nameType;
                inferredProp.propertyType = getTypeOfSymbol(prop);
                inferredProp.mappedType = type.mappedType;
                inferredProp.constraintType = type.constraintType;
                members.set(prop.escapedName, inferredProp);
            }
            setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined);
        }
        // Return the lower bound of the key type in a mapped type. Intuitively, the lower
        // bound includes those keys that are known to always be present, for example because
        // because of constraints on type parameters (e.g. 'keyof T' for a constrained T).
        function getLowerBoundOfKeyType(type) {
            if (type.flags & (1 /* Any */ | 131068 /* Primitive */)) {
                return type;
            }
            if (type.flags & 4194304 /* Index */) {
                return getIndexType(getApparentType(type.type));
            }
            if (type.flags & 16777216 /* Conditional */) {
                if (type.root.isDistributive) {
                    var checkType = type.checkType;
                    var constraint = getLowerBoundOfKeyType(checkType);
                    if (constraint !== checkType) {
                        return getConditionalTypeInstantiation(type, prependTypeMapping(type.root.checkType, constraint, type.mapper));
                    }
                }
                return type;
            }
            if (type.flags & 1048576 /* Union */) {
                return getUnionType(ts.sameMap(type.types, getLowerBoundOfKeyType));
            }
            if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.sameMap(type.types, getLowerBoundOfKeyType));
            }
            return neverType;
        }
        /** Resolve the members of a mapped type { [P in K]: T } */
        function resolveMappedTypeMembers(type) {
            var members = ts.createSymbolTable();
            var stringIndexInfo;
            var numberIndexInfo;
            // Resolve upfront such that recursive references see an empty object type.
            setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
            // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type,
            // and T as the template type.
            var typeParameter = getTypeParameterFromMappedType(type);
            var constraintType = getConstraintTypeFromMappedType(type);
            var templateType = getTemplateTypeFromMappedType(type.target || type);
            var modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
            var templateModifiers = getMappedTypeModifiers(type);
            var include = keyofStringsOnly ? 128 /* StringLiteral */ : 8576 /* StringOrNumberLiteralOrUnique */;
            if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                // We have a { [P in keyof T]: X }
                for (var _i = 0, _a = getPropertiesOfType(modifiersType); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    addMemberForKeyType(getLiteralTypeFromProperty(prop, include));
                }
                if (modifiersType.flags & 1 /* Any */ || getIndexInfoOfType(modifiersType, 0 /* String */)) {
                    addMemberForKeyType(stringType);
                }
                if (!keyofStringsOnly && getIndexInfoOfType(modifiersType, 1 /* Number */)) {
                    addMemberForKeyType(numberType);
                }
            }
            else {
                forEachType(getLowerBoundOfKeyType(constraintType), addMemberForKeyType);
            }
            setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
            function addMemberForKeyType(t) {
                // Create a mapper from T to the current iteration type constituent. Then, if the
                // mapped type is itself an instantiated type, combine the iteration mapper with the
                // instantiation mapper.
                var templateMapper = appendTypeMapping(type.mapper, typeParameter, t);
                // If the current iteration type constituent is a string literal type, create a property.
                // Otherwise, for type string create a string index signature.
                if (isTypeUsableAsPropertyName(t)) {
                    var propName = getPropertyNameFromType(t);
                    var modifiersProp = getPropertyOfType(modifiersType, propName);
                    var isOptional = !!(templateModifiers & 4 /* IncludeOptional */ ||
                        !(templateModifiers & 8 /* ExcludeOptional */) && modifiersProp && modifiersProp.flags & 16777216 /* Optional */);
                    var isReadonly = !!(templateModifiers & 1 /* IncludeReadonly */ ||
                        !(templateModifiers & 2 /* ExcludeReadonly */) && modifiersProp && isReadonlySymbol(modifiersProp));
                    var stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & 16777216 /* Optional */;
                    var prop = createSymbol(4 /* Property */ | (isOptional ? 16777216 /* Optional */ : 0), propName, 262144 /* Mapped */ | (isReadonly ? 8 /* Readonly */ : 0) | (stripOptional ? 524288 /* StripOptional */ : 0));
                    prop.mappedType = type;
                    prop.mapper = templateMapper;
                    if (modifiersProp) {
                        prop.syntheticOrigin = modifiersProp;
                        prop.declarations = modifiersProp.declarations;
                    }
                    prop.nameType = t;
                    members.set(propName, prop);
                }
                else if (t.flags & (1 /* Any */ | 4 /* String */ | 8 /* Number */ | 32 /* Enum */)) {
                    var propType = instantiateType(templateType, templateMapper);
                    if (t.flags & (1 /* Any */ | 4 /* String */)) {
                        stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & 1 /* IncludeReadonly */));
                    }
                    else {
                        numberIndexInfo = createIndexInfo(numberIndexInfo ? getUnionType([numberIndexInfo.type, propType]) : propType, !!(templateModifiers & 1 /* IncludeReadonly */));
                    }
                }
            }
        }
        function getTypeOfMappedSymbol(symbol) {
            if (!symbol.type) {
                if (!pushTypeResolution(symbol, 0 /* Type */)) {
                    return errorType;
                }
                var templateType = getTemplateTypeFromMappedType(symbol.mappedType.target || symbol.mappedType);
                var propType = instantiateType(templateType, symbol.mapper);
                // When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the
                // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks
                // mode, if the underlying property is optional we remove 'undefined' from the type.
                var type = strictNullChecks && symbol.flags & 16777216 /* Optional */ && !maybeTypeOfKind(propType, 32768 /* Undefined */ | 16384 /* Void */) ? getOptionalType(propType) :
                    symbol.checkFlags & 524288 /* StripOptional */ ? getTypeWithFacts(propType, 524288 /* NEUndefined */) :
                        propType;
                if (!popTypeResolution()) {
                    error(currentNode, ts.Diagnostics.Type_of_property_0_circularly_references_itself_in_mapped_type_1, symbolToString(symbol), typeToString(symbol.mappedType));
                    type = errorType;
                }
                symbol.type = type;
                symbol.mapper = undefined;
            }
            return symbol.type;
        }
        function getTypeParameterFromMappedType(type) {
            return type.typeParameter ||
                (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter)));
        }
        function getConstraintTypeFromMappedType(type) {
            return type.constraintType ||
                (type.constraintType = getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)) || errorType);
        }
        function getTemplateTypeFromMappedType(type) {
            return type.templateType ||
                (type.templateType = type.declaration.type ?
                    instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!(getMappedTypeModifiers(type) & 4 /* IncludeOptional */)), type.mapper) :
                    errorType);
        }
        function getConstraintDeclarationForMappedType(type) {
            return ts.getEffectiveConstraintOfTypeParameter(type.declaration.typeParameter);
        }
        function isMappedTypeWithKeyofConstraintDeclaration(type) {
            var constraintDeclaration = getConstraintDeclarationForMappedType(type); // TODO: GH#18217
            return constraintDeclaration.kind === 184 /* TypeOperator */ &&
                constraintDeclaration.operator === 134 /* KeyOfKeyword */;
        }
        function getModifiersTypeFromMappedType(type) {
            if (!type.modifiersType) {
                if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
                    // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check
                    // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves
                    // 'keyof T' to a literal union type and we can't recover T from that type.
                    type.modifiersType = instantiateType(getTypeFromTypeNode(getConstraintDeclarationForMappedType(type).type), type.mapper);
                }
                else {
                    // Otherwise, get the declared constraint type, and if the constraint type is a type parameter,
                    // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T',
                    // the modifiers type is T. Otherwise, the modifiers type is unknown.
                    var declaredType = getTypeFromMappedTypeNode(type.declaration);
                    var constraint = getConstraintTypeFromMappedType(declaredType);
                    var extendedConstraint = constraint && constraint.flags & 262144 /* TypeParameter */ ? getConstraintOfTypeParameter(constraint) : constraint;
                    type.modifiersType = extendedConstraint && extendedConstraint.flags & 4194304 /* Index */ ? instantiateType(extendedConstraint.type, type.mapper) : unknownType;
                }
            }
            return type.modifiersType;
        }
        function getMappedTypeModifiers(type) {
            var declaration = type.declaration;
            return (declaration.readonlyToken ? declaration.readonlyToken.kind === 40 /* MinusToken */ ? 2 /* ExcludeReadonly */ : 1 /* IncludeReadonly */ : 0) |
                (declaration.questionToken ? declaration.questionToken.kind === 40 /* MinusToken */ ? 8 /* ExcludeOptional */ : 4 /* IncludeOptional */ : 0);
        }
        function getMappedTypeOptionality(type) {
            var modifiers = getMappedTypeModifiers(type);
            return modifiers & 8 /* ExcludeOptional */ ? -1 : modifiers & 4 /* IncludeOptional */ ? 1 : 0;
        }
        function getCombinedMappedTypeOptionality(type) {
            var optionality = getMappedTypeOptionality(type);
            var modifiersType = getModifiersTypeFromMappedType(type);
            return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(modifiersType) : 0);
        }
        function isPartialMappedType(type) {
            return !!(ts.getObjectFlags(type) & 32 /* Mapped */ && getMappedTypeModifiers(type) & 4 /* IncludeOptional */);
        }
        function isGenericMappedType(type) {
            return !!(ts.getObjectFlags(type) & 32 /* Mapped */) && isGenericIndexType(getConstraintTypeFromMappedType(type));
        }
        function resolveStructuredTypeMembers(type) {
            if (!type.members) {
                if (type.flags & 524288 /* Object */) {
                    if (type.objectFlags & 4 /* Reference */) {
                        resolveTypeReferenceMembers(type);
                    }
                    else if (type.objectFlags & 3 /* ClassOrInterface */) {
                        resolveClassOrInterfaceMembers(type);
                    }
                    else if (type.objectFlags & 2048 /* ReverseMapped */) {
                        resolveReverseMappedTypeMembers(type);
                    }
                    else if (type.objectFlags & 16 /* Anonymous */) {
                        resolveAnonymousTypeMembers(type);
                    }
                    else if (type.objectFlags & 32 /* Mapped */) {
                        resolveMappedTypeMembers(type);
                    }
                }
                else if (type.flags & 1048576 /* Union */) {
                    resolveUnionTypeMembers(type);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    resolveIntersectionTypeMembers(type);
                }
            }
            return type;
        }
        /** Return properties of an object type or an empty array for other types */
        function getPropertiesOfObjectType(type) {
            if (type.flags & 524288 /* Object */) {
                return resolveStructuredTypeMembers(type).properties;
            }
            return ts.emptyArray;
        }
        /** If the given type is an object type and that type has a property by the given name,
         * return the symbol for that property. Otherwise return undefined.
         */
        function getPropertyOfObjectType(type, name) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                var symbol = resolved.members.get(name);
                if (symbol && symbolIsValue(symbol)) {
                    return symbol;
                }
            }
        }
        function getPropertiesOfUnionOrIntersectionType(type) {
            if (!type.resolvedProperties) {
                var members = ts.createSymbolTable();
                for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                    var current = _a[_i];
                    for (var _b = 0, _c = getPropertiesOfType(current); _b < _c.length; _b++) {
                        var prop = _c[_b];
                        if (!members.has(prop.escapedName)) {
                            var combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.escapedName);
                            if (combinedProp) {
                                members.set(prop.escapedName, combinedProp);
                            }
                        }
                    }
                    // The properties of a union type are those that are present in all constituent types, so
                    // we only need to check the properties of the first type without index signature
                    if (type.flags & 1048576 /* Union */ && !getIndexInfoOfType(current, 0 /* String */) && !getIndexInfoOfType(current, 1 /* Number */)) {
                        break;
                    }
                }
                type.resolvedProperties = getNamedMembers(members);
            }
            return type.resolvedProperties;
        }
        function getPropertiesOfType(type) {
            type = getReducedApparentType(type);
            return type.flags & 3145728 /* UnionOrIntersection */ ?
                getPropertiesOfUnionOrIntersectionType(type) :
                getPropertiesOfObjectType(type);
        }
        function isTypeInvalidDueToUnionDiscriminant(contextualType, obj) {
            var list = obj.properties;
            return list.some(function (property) {
                var nameType = property.name && getLiteralTypeFromPropertyName(property.name);
                var name = nameType && isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined;
                var expected = name === undefined ? undefined : getTypeOfPropertyOfType(contextualType, name);
                return !!expected && isLiteralType(expected) && !isTypeAssignableTo(getTypeOfNode(property), expected);
            });
        }
        function getAllPossiblePropertiesOfTypes(types) {
            var unionType = getUnionType(types);
            if (!(unionType.flags & 1048576 /* Union */)) {
                return getAugmentedPropertiesOfType(unionType);
            }
            var props = ts.createSymbolTable();
            for (var _i = 0, types_4 = types; _i < types_4.length; _i++) {
                var memberType = types_4[_i];
                for (var _a = 0, _b = getAugmentedPropertiesOfType(memberType); _a < _b.length; _a++) {
                    var escapedName = _b[_a].escapedName;
                    if (!props.has(escapedName)) {
                        var prop = createUnionOrIntersectionProperty(unionType, escapedName);
                        // May be undefined if the property is private
                        if (prop)
                            props.set(escapedName, prop);
                    }
                }
            }
            return ts.arrayFrom(props.values());
        }
        function getConstraintOfType(type) {
            return type.flags & 262144 /* TypeParameter */ ? getConstraintOfTypeParameter(type) :
                type.flags & 8388608 /* IndexedAccess */ ? getConstraintOfIndexedAccess(type) :
                    type.flags & 16777216 /* Conditional */ ? getConstraintOfConditionalType(type) :
                        getBaseConstraintOfType(type);
        }
        function getConstraintOfTypeParameter(typeParameter) {
            return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
        }
        function getConstraintOfIndexedAccess(type) {
            return hasNonCircularBaseConstraint(type) ? getConstraintFromIndexedAccess(type) : undefined;
        }
        function getSimplifiedTypeOrConstraint(type) {
            var simplified = getSimplifiedType(type, /*writing*/ false);
            return simplified !== type ? simplified : getConstraintOfType(type);
        }
        function getConstraintFromIndexedAccess(type) {
            var indexConstraint = getSimplifiedTypeOrConstraint(type.indexType);
            if (indexConstraint && indexConstraint !== type.indexType) {
                var indexedAccess = getIndexedAccessTypeOrUndefined(type.objectType, indexConstraint);
                if (indexedAccess) {
                    return indexedAccess;
                }
            }
            var objectConstraint = getSimplifiedTypeOrConstraint(type.objectType);
            if (objectConstraint && objectConstraint !== type.objectType) {
                return getIndexedAccessTypeOrUndefined(objectConstraint, type.indexType);
            }
            return undefined;
        }
        function getDefaultConstraintOfConditionalType(type) {
            if (!type.resolvedDefaultConstraint) {
                // An `any` branch of a conditional type would normally be viral - specifically, without special handling here,
                // a conditional type with a single branch of type `any` would be assignable to anything, since it's constraint would simplify to
                // just `any`. This result is _usually_ unwanted - so instead here we elide an `any` branch from the constraint type,
                // in effect treating `any` like `never` rather than `unknown` in this location.
                var trueConstraint = getInferredTrueTypeFromConditionalType(type);
                var falseConstraint = getFalseTypeFromConditionalType(type);
                type.resolvedDefaultConstraint = isTypeAny(trueConstraint) ? falseConstraint : isTypeAny(falseConstraint) ? trueConstraint : getUnionType([trueConstraint, falseConstraint]);
            }
            return type.resolvedDefaultConstraint;
        }
        function getConstraintOfDistributiveConditionalType(type) {
            // Check if we have a conditional type of the form 'T extends U ? X : Y', where T is a constrained
            // type parameter. If so, create an instantiation of the conditional type where T is replaced
            // with its constraint. We do this because if the constraint is a union type it will be distributed
            // over the conditional type and possibly reduced. For example, 'T extends undefined ? never : T'
            // removes 'undefined' from T.
            // We skip returning a distributive constraint for a restrictive instantiation of a conditional type
            // as the constraint for all type params (check type included) have been replace with `unknown`, which
            // is going to produce even more false positive/negative results than the distribute constraint already does.
            // Please note: the distributive constraint is a kludge for emulating what a negated type could to do filter
            // a union - once negated types exist and are applied to the conditional false branch, this "constraint"
            // likely doesn't need to exist.
            if (type.root.isDistributive && type.restrictiveInstantiation !== type) {
                var simplified = getSimplifiedType(type.checkType, /*writing*/ false);
                var constraint = simplified === type.checkType ? getConstraintOfType(simplified) : simplified;
                if (constraint && constraint !== type.checkType) {
                    var instantiated = getConditionalTypeInstantiation(type, prependTypeMapping(type.root.checkType, constraint, type.mapper));
                    if (!(instantiated.flags & 131072 /* Never */)) {
                        return instantiated;
                    }
                }
            }
            return undefined;
        }
        function getConstraintFromConditionalType(type) {
            return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type);
        }
        function getConstraintOfConditionalType(type) {
            return hasNonCircularBaseConstraint(type) ? getConstraintFromConditionalType(type) : undefined;
        }
        function getEffectiveConstraintOfIntersection(types, targetIsUnion) {
            var constraints;
            var hasDisjointDomainType = false;
            for (var _i = 0, types_5 = types; _i < types_5.length; _i++) {
                var t = types_5[_i];
                if (t.flags & 63176704 /* Instantiable */) {
                    // We keep following constraints as long as we have an instantiable type that is known
                    // not to be circular or infinite (hence we stop on index access types).
                    var constraint = getConstraintOfType(t);
                    while (constraint && constraint.flags & (262144 /* TypeParameter */ | 4194304 /* Index */ | 16777216 /* Conditional */)) {
                        constraint = getConstraintOfType(constraint);
                    }
                    if (constraint) {
                        constraints = ts.append(constraints, constraint);
                        if (targetIsUnion) {
                            constraints = ts.append(constraints, t);
                        }
                    }
                }
                else if (t.flags & 67238908 /* DisjointDomains */) {
                    hasDisjointDomainType = true;
                }
            }
            // If the target is a union type or if we are intersecting with types belonging to one of the
            // disjoint domains, we may end up producing a constraint that hasn't been examined before.
            if (constraints && (targetIsUnion || hasDisjointDomainType)) {
                if (hasDisjointDomainType) {
                    // We add any types belong to one of the disjoint domains because they might cause the final
                    // intersection operation to reduce the union constraints.
                    for (var _a = 0, types_6 = types; _a < types_6.length; _a++) {
                        var t = types_6[_a];
                        if (t.flags & 67238908 /* DisjointDomains */) {
                            constraints = ts.append(constraints, t);
                        }
                    }
                }
                return getIntersectionType(constraints);
            }
            return undefined;
        }
        function getBaseConstraintOfType(type) {
            if (type.flags & (58982400 /* InstantiableNonPrimitive */ | 3145728 /* UnionOrIntersection */)) {
                var constraint = getResolvedBaseConstraint(type);
                return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
            }
            return type.flags & 4194304 /* Index */ ? keyofConstraintType : undefined;
        }
        /**
         * This is similar to `getBaseConstraintOfType` except it returns the input type if there's no base constraint, instead of `undefined`
         * It also doesn't map indexes to `string`, as where this is used this would be unneeded (and likely undesirable)
         */
        function getBaseConstraintOrType(type) {
            return getBaseConstraintOfType(type) || type;
        }
        function hasNonCircularBaseConstraint(type) {
            return getResolvedBaseConstraint(type) !== circularConstraintType;
        }
        /**
         * Return the resolved base constraint of a type variable. The noConstraintType singleton is returned if the
         * type variable has no constraint, and the circularConstraintType singleton is returned if the constraint
         * circularly references the type variable.
         */
        function getResolvedBaseConstraint(type) {
            var nonTerminating = false;
            return type.resolvedBaseConstraint ||
                (type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type));
            function getImmediateBaseConstraint(t) {
                if (!t.immediateBaseConstraint) {
                    if (!pushTypeResolution(t, 4 /* ImmediateBaseConstraint */)) {
                        return circularConstraintType;
                    }
                    if (constraintDepth >= 50) {
                        // We have reached 50 recursive invocations of getImmediateBaseConstraint and there is a
                        // very high likelihood we're dealing with an infinite generic type that perpetually generates
                        // new type identities as we descend into it. We stop the recursion here and mark this type
                        // and the outer types as having circular constraints.
                        error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
                        nonTerminating = true;
                        return t.immediateBaseConstraint = noConstraintType;
                    }
                    constraintDepth++;
                    var result = computeBaseConstraint(getSimplifiedType(t, /*writing*/ false));
                    constraintDepth--;
                    if (!popTypeResolution()) {
                        if (t.flags & 262144 /* TypeParameter */) {
                            var errorNode = getConstraintDeclaration(t);
                            if (errorNode) {
                                var diagnostic = error(errorNode, ts.Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(t));
                                if (currentNode && !ts.isNodeDescendantOf(errorNode, currentNode) && !ts.isNodeDescendantOf(currentNode, errorNode)) {
                                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(currentNode, ts.Diagnostics.Circularity_originates_in_type_at_this_location));
                                }
                            }
                        }
                        result = circularConstraintType;
                    }
                    if (nonTerminating) {
                        result = circularConstraintType;
                    }
                    t.immediateBaseConstraint = result || noConstraintType;
                }
                return t.immediateBaseConstraint;
            }
            function getBaseConstraint(t) {
                var c = getImmediateBaseConstraint(t);
                return c !== noConstraintType && c !== circularConstraintType ? c : undefined;
            }
            function computeBaseConstraint(t) {
                if (t.flags & 262144 /* TypeParameter */) {
                    var constraint = getConstraintFromTypeParameter(t);
                    return t.isThisType || !constraint ?
                        constraint :
                        getBaseConstraint(constraint);
                }
                if (t.flags & 3145728 /* UnionOrIntersection */) {
                    var types = t.types;
                    var baseTypes = [];
                    for (var _i = 0, types_7 = types; _i < types_7.length; _i++) {
                        var type_2 = types_7[_i];
                        var baseType = getBaseConstraint(type_2);
                        if (baseType) {
                            baseTypes.push(baseType);
                        }
                    }
                    return t.flags & 1048576 /* Union */ && baseTypes.length === types.length ? getUnionType(baseTypes) :
                        t.flags & 2097152 /* Intersection */ && baseTypes.length ? getIntersectionType(baseTypes) :
                            undefined;
                }
                if (t.flags & 4194304 /* Index */) {
                    return keyofConstraintType;
                }
                if (t.flags & 8388608 /* IndexedAccess */) {
                    var baseObjectType = getBaseConstraint(t.objectType);
                    var baseIndexType = getBaseConstraint(t.indexType);
                    var baseIndexedAccess = baseObjectType && baseIndexType && getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType);
                    return baseIndexedAccess && getBaseConstraint(baseIndexedAccess);
                }
                if (t.flags & 16777216 /* Conditional */) {
                    var constraint = getConstraintFromConditionalType(t);
                    constraintDepth++; // Penalize repeating conditional types (this captures the recursion within getConstraintFromConditionalType and carries it forward)
                    var result = constraint && getBaseConstraint(constraint);
                    constraintDepth--;
                    return result;
                }
                if (t.flags & 33554432 /* Substitution */) {
                    return getBaseConstraint(t.substitute);
                }
                return t;
            }
        }
        function getApparentTypeOfIntersectionType(type) {
            return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type, /*apparentType*/ true));
        }
        function getResolvedTypeParameterDefault(typeParameter) {
            if (!typeParameter.default) {
                if (typeParameter.target) {
                    var targetDefault = getResolvedTypeParameterDefault(typeParameter.target);
                    typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType;
                }
                else {
                    // To block recursion, set the initial value to the resolvingDefaultType.
                    typeParameter.default = resolvingDefaultType;
                    var defaultDeclaration = typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; });
                    var defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType;
                    if (typeParameter.default === resolvingDefaultType) {
                        // If we have not been called recursively, set the correct default type.
                        typeParameter.default = defaultType;
                    }
                }
            }
            else if (typeParameter.default === resolvingDefaultType) {
                // If we are called recursively for this type parameter, mark the default as circular.
                typeParameter.default = circularConstraintType;
            }
            return typeParameter.default;
        }
        /**
         * Gets the default type for a type parameter.
         *
         * If the type parameter is the result of an instantiation, this gets the instantiated
         * default type of its target. If the type parameter has no default type or the default is
         * circular, `undefined` is returned.
         */
        function getDefaultFromTypeParameter(typeParameter) {
            var defaultType = getResolvedTypeParameterDefault(typeParameter);
            return defaultType !== noConstraintType && defaultType !== circularConstraintType ? defaultType : undefined;
        }
        function hasNonCircularTypeParameterDefault(typeParameter) {
            return getResolvedTypeParameterDefault(typeParameter) !== circularConstraintType;
        }
        /**
         * Indicates whether the declaration of a typeParameter has a default type.
         */
        function hasTypeParameterDefault(typeParameter) {
            return !!(typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; }));
        }
        function getApparentTypeOfMappedType(type) {
            return type.resolvedApparentType || (type.resolvedApparentType = getResolvedApparentTypeOfMappedType(type));
        }
        function getResolvedApparentTypeOfMappedType(type) {
            var typeVariable = getHomomorphicTypeVariable(type);
            if (typeVariable) {
                var constraint = getConstraintOfTypeParameter(typeVariable);
                if (constraint && (isArrayType(constraint) || isTupleType(constraint))) {
                    return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
                }
            }
            return type;
        }
        /**
         * For a type parameter, return the base constraint of the type parameter. For the string, number,
         * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
         * type itself.
         */
        function getApparentType(type) {
            var t = type.flags & 63176704 /* Instantiable */ ? getBaseConstraintOfType(type) || unknownType : type;
            return ts.getObjectFlags(t) & 32 /* Mapped */ ? getApparentTypeOfMappedType(t) :
                t.flags & 2097152 /* Intersection */ ? getApparentTypeOfIntersectionType(t) :
                    t.flags & 132 /* StringLike */ ? globalStringType :
                        t.flags & 296 /* NumberLike */ ? globalNumberType :
                            t.flags & 2112 /* BigIntLike */ ? getGlobalBigIntType(/*reportErrors*/ languageVersion >= 7 /* ES2020 */) :
                                t.flags & 528 /* BooleanLike */ ? globalBooleanType :
                                    t.flags & 12288 /* ESSymbolLike */ ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= 2 /* ES2015 */) :
                                        t.flags & 67108864 /* NonPrimitive */ ? emptyObjectType :
                                            t.flags & 4194304 /* Index */ ? keyofConstraintType :
                                                t.flags & 2 /* Unknown */ && !strictNullChecks ? emptyObjectType :
                                                    t;
        }
        function getReducedApparentType(type) {
            // Since getApparentType may return a non-reduced union or intersection type, we need to perform
            // type reduction both before and after obtaining the apparent type. For example, given a type parameter
            // 'T extends A | B', the type 'T & X' becomes 'A & X | B & X' after obtaining the apparent type, and
            // that type may need futher reduction to remove empty intersections.
            return getReducedType(getApparentType(getReducedType(type)));
        }
        function createUnionOrIntersectionProperty(containingType, name) {
            var singleProp;
            var propSet;
            var indexTypes;
            var isUnion = containingType.flags & 1048576 /* Union */;
            // Flags we want to propagate to the result if they exist in all source symbols
            var optionalFlag = isUnion ? 0 /* None */ : 16777216 /* Optional */;
            var syntheticFlag = 4 /* SyntheticMethod */;
            var checkFlags = 0;
            for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) {
                var current = _a[_i];
                var type = getApparentType(current);
                if (!(type === errorType || type.flags & 131072 /* Never */)) {
                    var prop = getPropertyOfType(type, name);
                    var modifiers = prop ? ts.getDeclarationModifierFlagsFromSymbol(prop) : 0;
                    if (prop) {
                        if (isUnion) {
                            optionalFlag |= (prop.flags & 16777216 /* Optional */);
                        }
                        else {
                            optionalFlag &= prop.flags;
                        }
                        if (!singleProp) {
                            singleProp = prop;
                        }
                        else if (prop !== singleProp) {
                            if (!propSet) {
                                propSet = ts.createMap();
                                propSet.set("" + getSymbolId(singleProp), singleProp);
                            }
                            var id = "" + getSymbolId(prop);
                            if (!propSet.has(id)) {
                                propSet.set(id, prop);
                            }
                        }
                        checkFlags |= (isReadonlySymbol(prop) ? 8 /* Readonly */ : 0) |
                            (!(modifiers & 24 /* NonPublicAccessibilityModifier */) ? 256 /* ContainsPublic */ : 0) |
                            (modifiers & 16 /* Protected */ ? 512 /* ContainsProtected */ : 0) |
                            (modifiers & 8 /* Private */ ? 1024 /* ContainsPrivate */ : 0) |
                            (modifiers & 32 /* Static */ ? 2048 /* ContainsStatic */ : 0);
                        if (!isPrototypeProperty(prop)) {
                            syntheticFlag = 2 /* SyntheticProperty */;
                        }
                    }
                    else if (isUnion) {
                        var indexInfo = !isLateBoundName(name) && (isNumericLiteralName(name) && getIndexInfoOfType(type, 1 /* Number */) || getIndexInfoOfType(type, 0 /* String */));
                        if (indexInfo) {
                            checkFlags |= 32 /* WritePartial */ | (indexInfo.isReadonly ? 8 /* Readonly */ : 0);
                            indexTypes = ts.append(indexTypes, isTupleType(type) ? getRestTypeOfTupleType(type) || undefinedType : indexInfo.type);
                        }
                        else if (isObjectLiteralType(type)) {
                            checkFlags |= 32 /* WritePartial */;
                            indexTypes = ts.append(indexTypes, undefinedType);
                        }
                        else {
                            checkFlags |= 16 /* ReadPartial */;
                        }
                    }
                }
            }
            if (!singleProp || isUnion && (propSet || checkFlags & 48 /* Partial */) && checkFlags & (1024 /* ContainsPrivate */ | 512 /* ContainsProtected */)) {
                // No property was found, or, in a union, a property has a private or protected declaration in one
                // constituent, but is missing or has a different declaration in another constituent.
                return undefined;
            }
            if (!propSet && !(checkFlags & 16 /* ReadPartial */) && !indexTypes) {
                return singleProp;
            }
            var props = propSet ? ts.arrayFrom(propSet.values()) : [singleProp];
            var declarations;
            var firstType;
            var nameType;
            var propTypes = [];
            var firstValueDeclaration;
            var hasNonUniformValueDeclaration = false;
            for (var _b = 0, props_1 = props; _b < props_1.length; _b++) {
                var prop = props_1[_b];
                if (!firstValueDeclaration) {
                    firstValueDeclaration = prop.valueDeclaration;
                }
                else if (prop.valueDeclaration && prop.valueDeclaration !== firstValueDeclaration) {
                    hasNonUniformValueDeclaration = true;
                }
                declarations = ts.addRange(declarations, prop.declarations);
                var type = getTypeOfSymbol(prop);
                if (!firstType) {
                    firstType = type;
                    nameType = getSymbolLinks(prop).nameType;
                }
                else if (type !== firstType) {
                    checkFlags |= 64 /* HasNonUniformType */;
                }
                if (isLiteralType(type)) {
                    checkFlags |= 128 /* HasLiteralType */;
                }
                if (type.flags & 131072 /* Never */) {
                    checkFlags |= 131072 /* HasNeverType */;
                }
                propTypes.push(type);
            }
            ts.addRange(propTypes, indexTypes);
            var result = createSymbol(4 /* Property */ | optionalFlag, name, syntheticFlag | checkFlags);
            result.containingType = containingType;
            if (!hasNonUniformValueDeclaration && firstValueDeclaration) {
                result.valueDeclaration = firstValueDeclaration;
                // Inherit information about parent type.
                if (firstValueDeclaration.symbol.parent) {
                    result.parent = firstValueDeclaration.symbol.parent;
                }
            }
            result.declarations = declarations;
            result.nameType = nameType;
            if (propTypes.length > 2) {
                // When `propTypes` has the potential to explode in size when normalized, defer normalization until absolutely needed
                result.checkFlags |= 65536 /* DeferredType */;
                result.deferralParent = containingType;
                result.deferralConstituents = propTypes;
            }
            else {
                result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
            }
            return result;
        }
        // Return the symbol for a given property in a union or intersection type, or undefined if the property
        // does not exist in any constituent type. Note that the returned property may only be present in some
        // constituents, in which case the isPartial flag is set when the containing type is union type. We need
        // these partial properties when identifying discriminant properties, but otherwise they are filtered out
        // and do not appear to be present in the union type.
        function getUnionOrIntersectionProperty(type, name) {
            var properties = type.propertyCache || (type.propertyCache = ts.createSymbolTable());
            var property = properties.get(name);
            if (!property) {
                property = createUnionOrIntersectionProperty(type, name);
                if (property) {
                    properties.set(name, property);
                }
            }
            return property;
        }
        function getPropertyOfUnionOrIntersectionType(type, name) {
            var property = getUnionOrIntersectionProperty(type, name);
            // We need to filter out partial properties in union types
            return property && !(ts.getCheckFlags(property) & 16 /* ReadPartial */) ? property : undefined;
        }
        /**
         * Return the reduced form of the given type. For a union type, it is a union of the normalized constituent types.
         * For an intersection of types containing one or more mututally exclusive discriminant properties, it is 'never'.
         * For all other types, it is simply the type itself. Discriminant properties are considered mutually exclusive when
         * no constituent property has type 'never', but the intersection of the constituent property types is 'never'.
         */
        function getReducedType(type) {
            if (type.flags & 1048576 /* Union */ && type.objectFlags & 268435456 /* ContainsIntersections */) {
                return type.resolvedReducedType || (type.resolvedReducedType = getReducedUnionType(type));
            }
            else if (type.flags & 2097152 /* Intersection */) {
                if (!(type.objectFlags & 268435456 /* IsNeverIntersectionComputed */)) {
                    type.objectFlags |= 268435456 /* IsNeverIntersectionComputed */ |
                        (ts.some(getPropertiesOfUnionOrIntersectionType(type), isNeverReducedProperty) ? 536870912 /* IsNeverIntersection */ : 0);
                }
                return type.objectFlags & 536870912 /* IsNeverIntersection */ ? neverType : type;
            }
            return type;
        }
        function getReducedUnionType(unionType) {
            var reducedTypes = ts.sameMap(unionType.types, getReducedType);
            if (reducedTypes === unionType.types) {
                return unionType;
            }
            var reduced = getUnionType(reducedTypes);
            if (reduced.flags & 1048576 /* Union */) {
                reduced.resolvedReducedType = reduced;
            }
            return reduced;
        }
        function isNeverReducedProperty(prop) {
            return isDiscriminantWithNeverType(prop) || isConflictingPrivateProperty(prop);
        }
        function isDiscriminantWithNeverType(prop) {
            // Return true for a synthetic non-optional property with non-uniform types, where at least one is
            // a literal type and none is never, that reduces to never.
            return !(prop.flags & 16777216 /* Optional */) &&
                (ts.getCheckFlags(prop) & (192 /* Discriminant */ | 131072 /* HasNeverType */)) === 192 /* Discriminant */ &&
                !!(getTypeOfSymbol(prop).flags & 131072 /* Never */);
        }
        function isConflictingPrivateProperty(prop) {
            // Return true for a synthetic property with multiple declarations, at least one of which is private.
            return !prop.valueDeclaration && !!(ts.getCheckFlags(prop) & 1024 /* ContainsPrivate */);
        }
        function elaborateNeverIntersection(errorInfo, type) {
            if (ts.getObjectFlags(type) & 536870912 /* IsNeverIntersection */) {
                var neverProp = ts.find(getPropertiesOfUnionOrIntersectionType(type), isDiscriminantWithNeverType);
                if (neverProp) {
                    return ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_has_conflicting_types_in_some_constituents, typeToString(type, /*enclosingDeclaration*/ undefined, 536870912 /* NoTypeReduction */), symbolToString(neverProp));
                }
                var privateProp = ts.find(getPropertiesOfUnionOrIntersectionType(type), isConflictingPrivateProperty);
                if (privateProp) {
                    return ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.The_intersection_0_was_reduced_to_never_because_property_1_exists_in_multiple_constituents_and_is_private_in_some, typeToString(type, /*enclosingDeclaration*/ undefined, 536870912 /* NoTypeReduction */), symbolToString(privateProp));
                }
            }
            return errorInfo;
        }
        /**
         * Return the symbol for the property with the given name in the given type. Creates synthetic union properties when
         * necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from
         * Object and Function as appropriate.
         *
         * @param type a type to look up property from
         * @param name a name of property to look up in a given type
         */
        function getPropertyOfType(type, name) {
            type = getReducedApparentType(type);
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                var symbol = resolved.members.get(name);
                if (symbol && symbolIsValue(symbol)) {
                    return symbol;
                }
                var functionType = resolved === anyFunctionType ? globalFunctionType :
                    resolved.callSignatures.length ? globalCallableFunctionType :
                        resolved.constructSignatures.length ? globalNewableFunctionType :
                            undefined;
                if (functionType) {
                    var symbol_1 = getPropertyOfObjectType(functionType, name);
                    if (symbol_1) {
                        return symbol_1;
                    }
                }
                return getPropertyOfObjectType(globalObjectType, name);
            }
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                return getPropertyOfUnionOrIntersectionType(type, name);
            }
            return undefined;
        }
        function getSignaturesOfStructuredType(type, kind) {
            if (type.flags & 3670016 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* Call */ ? resolved.callSignatures : resolved.constructSignatures;
            }
            return ts.emptyArray;
        }
        /**
         * Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and
         * maps primitive types and type parameters are to their apparent types.
         */
        function getSignaturesOfType(type, kind) {
            return getSignaturesOfStructuredType(getReducedApparentType(type), kind);
        }
        function getIndexInfoOfStructuredType(type, kind) {
            if (type.flags & 3670016 /* StructuredType */) {
                var resolved = resolveStructuredTypeMembers(type);
                return kind === 0 /* String */ ? resolved.stringIndexInfo : resolved.numberIndexInfo;
            }
        }
        function getIndexTypeOfStructuredType(type, kind) {
            var info = getIndexInfoOfStructuredType(type, kind);
            return info && info.type;
        }
        // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and
        // maps primitive types and type parameters are to their apparent types.
        function getIndexInfoOfType(type, kind) {
            return getIndexInfoOfStructuredType(getReducedApparentType(type), kind);
        }
        // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and
        // maps primitive types and type parameters are to their apparent types.
        function getIndexTypeOfType(type, kind) {
            return getIndexTypeOfStructuredType(getReducedApparentType(type), kind);
        }
        function getImplicitIndexTypeOfType(type, kind) {
            if (isObjectTypeWithInferableIndex(type)) {
                var propTypes = [];
                for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
                        propTypes.push(getTypeOfSymbol(prop));
                    }
                }
                if (kind === 0 /* String */) {
                    ts.append(propTypes, getIndexTypeOfType(type, 1 /* Number */));
                }
                if (propTypes.length) {
                    return getUnionType(propTypes);
                }
            }
            return undefined;
        }
        // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual
        // type checking functions).
        function getTypeParametersFromDeclaration(declaration) {
            var result;
            for (var _i = 0, _a = ts.getEffectiveTypeParameterDeclarations(declaration); _i < _a.length; _i++) {
                var node = _a[_i];
                result = ts.appendIfUnique(result, getDeclaredTypeOfTypeParameter(node.symbol));
            }
            return result;
        }
        function symbolsToArray(symbols) {
            var result = [];
            symbols.forEach(function (symbol, id) {
                if (!isReservedMemberName(id)) {
                    result.push(symbol);
                }
            });
            return result;
        }
        function isJSDocOptionalParameter(node) {
            return ts.isInJSFile(node) && (
            // node.type should only be a JSDocOptionalType when node is a parameter of a JSDocFunctionType
            node.type && node.type.kind === 299 /* JSDocOptionalType */
                || ts.getJSDocParameterTags(node).some(function (_a) {
                    var isBracketed = _a.isBracketed, typeExpression = _a.typeExpression;
                    return isBracketed || !!typeExpression && typeExpression.type.kind === 299 /* JSDocOptionalType */;
                }));
        }
        function tryFindAmbientModule(moduleName, withAugmentations) {
            if (ts.isExternalModuleNameRelative(moduleName)) {
                return undefined;
            }
            var symbol = getSymbol(globals, '"' + moduleName + '"', 512 /* ValueModule */);
            // merged symbol is module declaration symbol combined with all augmentations
            return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol;
        }
        function isOptionalParameter(node) {
            if (ts.hasQuestionToken(node) || isOptionalJSDocParameterTag(node) || isJSDocOptionalParameter(node)) {
                return true;
            }
            if (node.initializer) {
                var signature = getSignatureFromDeclaration(node.parent);
                var parameterIndex = node.parent.parameters.indexOf(node);
                ts.Debug.assert(parameterIndex >= 0);
                return parameterIndex >= getMinArgumentCount(signature, /*strongArityForUntypedJS*/ true);
            }
            var iife = ts.getImmediatelyInvokedFunctionExpression(node.parent);
            if (iife) {
                return !node.type &&
                    !node.dotDotDotToken &&
                    node.parent.parameters.indexOf(node) >= iife.arguments.length;
            }
            return false;
        }
        function isOptionalJSDocParameterTag(node) {
            if (!ts.isJSDocParameterTag(node)) {
                return false;
            }
            var isBracketed = node.isBracketed, typeExpression = node.typeExpression;
            return isBracketed || !!typeExpression && typeExpression.type.kind === 299 /* JSDocOptionalType */;
        }
        function createTypePredicate(kind, parameterName, parameterIndex, type) {
            return { kind: kind, parameterName: parameterName, parameterIndex: parameterIndex, type: type };
        }
        /**
         * Gets the minimum number of type arguments needed to satisfy all non-optional type
         * parameters.
         */
        function getMinTypeArgumentCount(typeParameters) {
            var minTypeArgumentCount = 0;
            if (typeParameters) {
                for (var i = 0; i < typeParameters.length; i++) {
                    if (!hasTypeParameterDefault(typeParameters[i])) {
                        minTypeArgumentCount = i + 1;
                    }
                }
            }
            return minTypeArgumentCount;
        }
        function fillMissingTypeArguments(typeArguments, typeParameters, minTypeArgumentCount, isJavaScriptImplicitAny) {
            var numTypeParameters = ts.length(typeParameters);
            if (!numTypeParameters) {
                return [];
            }
            var numTypeArguments = ts.length(typeArguments);
            if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) {
                var result = typeArguments ? typeArguments.slice() : [];
                // Map invalid forward references in default types to the error type
                for (var i = numTypeArguments; i < numTypeParameters; i++) {
                    result[i] = errorType;
                }
                var baseDefaultType = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
                for (var i = numTypeArguments; i < numTypeParameters; i++) {
                    var defaultType = getDefaultFromTypeParameter(typeParameters[i]);
                    if (isJavaScriptImplicitAny && defaultType && (isTypeIdenticalTo(defaultType, unknownType) || isTypeIdenticalTo(defaultType, emptyObjectType))) {
                        defaultType = anyType;
                    }
                    result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters, result)) : baseDefaultType;
                }
                result.length = typeParameters.length;
                return result;
            }
            return typeArguments && typeArguments.slice();
        }
        function getSignatureFromDeclaration(declaration) {
            var links = getNodeLinks(declaration);
            if (!links.resolvedSignature) {
                var parameters = [];
                var flags = 0 /* None */;
                var minArgumentCount = 0;
                var thisParameter = void 0;
                var hasThisParameter = false;
                var iife = ts.getImmediatelyInvokedFunctionExpression(declaration);
                var isJSConstructSignature = ts.isJSDocConstructSignature(declaration);
                var isUntypedSignatureInJSFile = !iife &&
                    ts.isInJSFile(declaration) &&
                    ts.isValueSignatureDeclaration(declaration) &&
                    !ts.hasJSDocParameterTags(declaration) &&
                    !ts.getJSDocType(declaration);
                if (isUntypedSignatureInJSFile) {
                    flags |= 16 /* IsUntypedSignatureInJSFile */;
                }
                // If this is a JSDoc construct signature, then skip the first parameter in the
                // parameter list.  The first parameter represents the return type of the construct
                // signature.
                for (var i = isJSConstructSignature ? 1 : 0; i < declaration.parameters.length; i++) {
                    var param = declaration.parameters[i];
                    var paramSymbol = param.symbol;
                    var type = ts.isJSDocParameterTag(param) ? (param.typeExpression && param.typeExpression.type) : param.type;
                    // Include parameter symbol instead of property symbol in the signature
                    if (paramSymbol && !!(paramSymbol.flags & 4 /* Property */) && !ts.isBindingPattern(param.name)) {
                        var resolvedSymbol = resolveName(param, paramSymbol.escapedName, 111551 /* Value */, undefined, undefined, /*isUse*/ false);
                        paramSymbol = resolvedSymbol;
                    }
                    if (i === 0 && paramSymbol.escapedName === "this" /* This */) {
                        hasThisParameter = true;
                        thisParameter = param.symbol;
                    }
                    else {
                        parameters.push(paramSymbol);
                    }
                    if (type && type.kind === 187 /* LiteralType */) {
                        flags |= 2 /* HasLiteralTypes */;
                    }
                    // Record a new minimum argument count if this is not an optional parameter
                    var isOptionalParameter_1 = isOptionalJSDocParameterTag(param) ||
                        param.initializer || param.questionToken || param.dotDotDotToken ||
                        iife && parameters.length > iife.arguments.length && !type ||
                        isJSDocOptionalParameter(param);
                    if (!isOptionalParameter_1) {
                        minArgumentCount = parameters.length;
                    }
                }
                // If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation
                if ((declaration.kind === 163 /* GetAccessor */ || declaration.kind === 164 /* SetAccessor */) &&
                    !hasNonBindableDynamicName(declaration) &&
                    (!hasThisParameter || !thisParameter)) {
                    var otherKind = declaration.kind === 163 /* GetAccessor */ ? 164 /* SetAccessor */ : 163 /* GetAccessor */;
                    var other = ts.getDeclarationOfKind(getSymbolOfNode(declaration), otherKind);
                    if (other) {
                        thisParameter = getAnnotatedAccessorThisParameter(other);
                    }
                }
                var classType = declaration.kind === 162 /* Constructor */ ?
                    getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol))
                    : undefined;
                var typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration);
                if (ts.hasRestParameter(declaration) || ts.isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) {
                    flags |= 1 /* HasRestParameter */;
                }
                links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, 
                /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, minArgumentCount, flags);
            }
            return links.resolvedSignature;
        }
        /**
         * A JS function gets a synthetic rest parameter if it references `arguments` AND:
         * 1. It has no parameters but at least one `@param` with a type that starts with `...`
         * OR
         * 2. It has at least one parameter, and the last parameter has a matching `@param` with a type that starts with `...`
         */
        function maybeAddJsSyntheticRestParameter(declaration, parameters) {
            if (ts.isJSDocSignature(declaration) || !containsArgumentsReference(declaration)) {
                return false;
            }
            var lastParam = ts.lastOrUndefined(declaration.parameters);
            var lastParamTags = lastParam ? ts.getJSDocParameterTags(lastParam) : ts.getJSDocTags(declaration).filter(ts.isJSDocParameterTag);
            var lastParamVariadicType = ts.firstDefined(lastParamTags, function (p) {
                return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined;
            });
            var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args", 32768 /* RestParameter */);
            syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType;
            if (lastParamVariadicType) {
                // Replace the last parameter with a rest parameter.
                parameters.pop();
            }
            parameters.push(syntheticArgsSymbol);
            return true;
        }
        function getSignatureOfTypeTag(node) {
            // should be attached to a function declaration or expression
            if (!(ts.isInJSFile(node) && ts.isFunctionLikeDeclaration(node)))
                return undefined;
            var typeTag = ts.getJSDocTypeTag(node);
            var signature = typeTag && typeTag.typeExpression && getSingleCallSignature(getTypeFromTypeNode(typeTag.typeExpression));
            return signature && getErasedSignature(signature);
        }
        function getReturnTypeOfTypeTag(node) {
            var signature = getSignatureOfTypeTag(node);
            return signature && getReturnTypeOfSignature(signature);
        }
        function containsArgumentsReference(declaration) {
            var links = getNodeLinks(declaration);
            if (links.containsArgumentsReference === undefined) {
                if (links.flags & 8192 /* CaptureArguments */) {
                    links.containsArgumentsReference = true;
                }
                else {
                    links.containsArgumentsReference = traverse(declaration.body);
                }
            }
            return links.containsArgumentsReference;
            function traverse(node) {
                if (!node)
                    return false;
                switch (node.kind) {
                    case 75 /* Identifier */:
                        return node.escapedText === "arguments" && ts.isExpressionNode(node);
                    case 159 /* PropertyDeclaration */:
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        return node.name.kind === 154 /* ComputedPropertyName */
                            && traverse(node.name);
                    default:
                        return !ts.nodeStartsNewLexicalEnvironment(node) && !ts.isPartOfTypeNode(node) && !!ts.forEachChild(node, traverse);
                }
            }
        }
        function getSignaturesOfSymbol(symbol) {
            if (!symbol)
                return ts.emptyArray;
            var result = [];
            for (var i = 0; i < symbol.declarations.length; i++) {
                var decl = symbol.declarations[i];
                if (!ts.isFunctionLike(decl))
                    continue;
                // Don't include signature if node is the implementation of an overloaded function. A node is considered
                // an implementation node if it has a body and the previous node is of the same kind and immediately
                // precedes the implementation node (i.e. has the same parent and ends where the implementation starts).
                if (i > 0 && decl.body) {
                    var previous = symbol.declarations[i - 1];
                    if (decl.parent === previous.parent && decl.kind === previous.kind && decl.pos === previous.end) {
                        continue;
                    }
                }
                result.push(getSignatureFromDeclaration(decl));
            }
            return result;
        }
        function resolveExternalModuleTypeByLiteral(name) {
            var moduleSym = resolveExternalModuleName(name, name);
            if (moduleSym) {
                var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
                if (resolvedModuleSymbol) {
                    return getTypeOfSymbol(resolvedModuleSymbol);
                }
            }
            return anyType;
        }
        function getThisTypeOfSignature(signature) {
            if (signature.thisParameter) {
                return getTypeOfSymbol(signature.thisParameter);
            }
        }
        function getTypePredicateOfSignature(signature) {
            if (!signature.resolvedTypePredicate) {
                if (signature.target) {
                    var targetTypePredicate = getTypePredicateOfSignature(signature.target);
                    signature.resolvedTypePredicate = targetTypePredicate ? instantiateTypePredicate(targetTypePredicate, signature.mapper) : noTypePredicate;
                }
                else if (signature.unionSignatures) {
                    signature.resolvedTypePredicate = getUnionTypePredicate(signature.unionSignatures) || noTypePredicate;
                }
                else {
                    var type = signature.declaration && ts.getEffectiveReturnTypeNode(signature.declaration);
                    var jsdocPredicate = void 0;
                    if (!type && ts.isInJSFile(signature.declaration)) {
                        var jsdocSignature = getSignatureOfTypeTag(signature.declaration);
                        if (jsdocSignature && signature !== jsdocSignature) {
                            jsdocPredicate = getTypePredicateOfSignature(jsdocSignature);
                        }
                    }
                    signature.resolvedTypePredicate = type && ts.isTypePredicateNode(type) ?
                        createTypePredicateFromTypePredicateNode(type, signature) :
                        jsdocPredicate || noTypePredicate;
                }
                ts.Debug.assert(!!signature.resolvedTypePredicate);
            }
            return signature.resolvedTypePredicate === noTypePredicate ? undefined : signature.resolvedTypePredicate;
        }
        function createTypePredicateFromTypePredicateNode(node, signature) {
            var parameterName = node.parameterName;
            var type = node.type && getTypeFromTypeNode(node.type);
            return parameterName.kind === 183 /* ThisType */ ?
                createTypePredicate(node.assertsModifier ? 2 /* AssertsThis */ : 0 /* This */, /*parameterName*/ undefined, /*parameterIndex*/ undefined, type) :
                createTypePredicate(node.assertsModifier ? 3 /* AssertsIdentifier */ : 1 /* Identifier */, parameterName.escapedText, ts.findIndex(signature.parameters, function (p) { return p.escapedName === parameterName.escapedText; }), type);
        }
        function getReturnTypeOfSignature(signature) {
            if (!signature.resolvedReturnType) {
                if (!pushTypeResolution(signature, 3 /* ResolvedReturnType */)) {
                    return errorType;
                }
                var type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper) :
                    signature.unionSignatures ? getUnionType(ts.map(signature.unionSignatures, getReturnTypeOfSignature), 2 /* Subtype */) :
                        getReturnTypeFromAnnotation(signature.declaration) ||
                            (ts.nodeIsMissing(signature.declaration.body) ? anyType : getReturnTypeFromBody(signature.declaration));
                if (signature.flags & 4 /* IsInnerCallChain */) {
                    type = addOptionalTypeMarker(type);
                }
                else if (signature.flags & 8 /* IsOuterCallChain */) {
                    type = getOptionalType(type);
                }
                if (!popTypeResolution()) {
                    if (signature.declaration) {
                        var typeNode = ts.getEffectiveReturnTypeNode(signature.declaration);
                        if (typeNode) {
                            error(typeNode, ts.Diagnostics.Return_type_annotation_circularly_references_itself);
                        }
                        else if (noImplicitAny) {
                            var declaration = signature.declaration;
                            var name = ts.getNameOfDeclaration(declaration);
                            if (name) {
                                error(name, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, ts.declarationNameToString(name));
                            }
                            else {
                                error(declaration, ts.Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions);
                            }
                        }
                    }
                    type = anyType;
                }
                signature.resolvedReturnType = type;
            }
            return signature.resolvedReturnType;
        }
        function getReturnTypeFromAnnotation(declaration) {
            if (declaration.kind === 162 /* Constructor */) {
                return getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol));
            }
            if (ts.isJSDocConstructSignature(declaration)) {
                return getTypeFromTypeNode(declaration.parameters[0].type); // TODO: GH#18217
            }
            var typeNode = ts.getEffectiveReturnTypeNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
            if (declaration.kind === 163 /* GetAccessor */ && !hasNonBindableDynamicName(declaration)) {
                var jsDocType = ts.isInJSFile(declaration) && getTypeForDeclarationFromJSDocComment(declaration);
                if (jsDocType) {
                    return jsDocType;
                }
                var setter = ts.getDeclarationOfKind(getSymbolOfNode(declaration), 164 /* SetAccessor */);
                var setterType = getAnnotatedAccessorType(setter);
                if (setterType) {
                    return setterType;
                }
            }
            return getReturnTypeOfTypeTag(declaration);
        }
        function isResolvingReturnTypeOfSignature(signature) {
            return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0;
        }
        function getRestTypeOfSignature(signature) {
            return tryGetRestTypeOfSignature(signature) || anyType;
        }
        function tryGetRestTypeOfSignature(signature) {
            if (signatureHasRestParameter(signature)) {
                var sigRestType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                var restType = isTupleType(sigRestType) ? getRestTypeOfTupleType(sigRestType) : sigRestType;
                return restType && getIndexTypeOfType(restType, 1 /* Number */);
            }
            return undefined;
        }
        function getSignatureInstantiation(signature, typeArguments, isJavascript, inferredTypeParameters) {
            var instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript));
            if (inferredTypeParameters) {
                var returnSignature = getSingleCallOrConstructSignature(getReturnTypeOfSignature(instantiatedSignature));
                if (returnSignature) {
                    var newReturnSignature = cloneSignature(returnSignature);
                    newReturnSignature.typeParameters = inferredTypeParameters;
                    var newInstantiatedSignature = cloneSignature(instantiatedSignature);
                    newInstantiatedSignature.resolvedReturnType = getOrCreateTypeFromSignature(newReturnSignature);
                    return newInstantiatedSignature;
                }
            }
            return instantiatedSignature;
        }
        function getSignatureInstantiationWithoutFillingInTypeArguments(signature, typeArguments) {
            var instantiations = signature.instantiations || (signature.instantiations = ts.createMap());
            var id = getTypeListId(typeArguments);
            var instantiation = instantiations.get(id);
            if (!instantiation) {
                instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments));
            }
            return instantiation;
        }
        function createSignatureInstantiation(signature, typeArguments) {
            return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true);
        }
        function createSignatureTypeMapper(signature, typeArguments) {
            return createTypeMapper(signature.typeParameters, typeArguments);
        }
        function getErasedSignature(signature) {
            return signature.typeParameters ?
                signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) :
                signature;
        }
        function createErasedSignature(signature) {
            // Create an instantiation of the signature where all type arguments are the any type.
            return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true);
        }
        function getCanonicalSignature(signature) {
            return signature.typeParameters ?
                signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) :
                signature;
        }
        function createCanonicalSignature(signature) {
            // Create an instantiation of the signature where each unconstrained type parameter is replaced with
            // its original. When a generic class or interface is instantiated, each generic method in the class or
            // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios
            // where different generations of the same type parameter are in scope). This leads to a lot of new type
            // identities, and potentially a lot of work comparing those identities, so here we create an instantiation
            // that uses the original type identities for all unconstrained type parameters.
            return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; }), ts.isInJSFile(signature.declaration));
        }
        function getBaseSignature(signature) {
            var typeParameters = signature.typeParameters;
            if (typeParameters) {
                var typeEraser_1 = createTypeEraser(typeParameters);
                var baseConstraints = ts.map(typeParameters, function (tp) { return instantiateType(getBaseConstraintOfType(tp), typeEraser_1) || unknownType; });
                return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true);
            }
            return signature;
        }
        function getOrCreateTypeFromSignature(signature) {
            // There are two ways to declare a construct signature, one is by declaring a class constructor
            // using the constructor keyword, and the other is declaring a bare construct signature in an
            // object type literal or interface (using the new keyword). Each way of declaring a constructor
            // will result in a different declaration kind.
            if (!signature.isolatedSignatureType) {
                var kind = signature.declaration ? signature.declaration.kind : 0 /* Unknown */;
                var isConstructor = kind === 162 /* Constructor */ || kind === 166 /* ConstructSignature */ || kind === 171 /* ConstructorType */;
                var type = createObjectType(16 /* Anonymous */);
                type.members = emptySymbols;
                type.properties = ts.emptyArray;
                type.callSignatures = !isConstructor ? [signature] : ts.emptyArray;
                type.constructSignatures = isConstructor ? [signature] : ts.emptyArray;
                signature.isolatedSignatureType = type;
            }
            return signature.isolatedSignatureType;
        }
        function getIndexSymbol(symbol) {
            return symbol.members.get("__index" /* Index */);
        }
        function getIndexDeclarationOfSymbol(symbol, kind) {
            var syntaxKind = kind === 1 /* Number */ ? 140 /* NumberKeyword */ : 143 /* StringKeyword */;
            var indexSymbol = getIndexSymbol(symbol);
            if (indexSymbol) {
                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var node = ts.cast(decl, ts.isIndexSignatureDeclaration);
                    if (node.parameters.length === 1) {
                        var parameter = node.parameters[0];
                        if (parameter.type && parameter.type.kind === syntaxKind) {
                            return node;
                        }
                    }
                }
            }
            return undefined;
        }
        function createIndexInfo(type, isReadonly, declaration) {
            return { type: type, isReadonly: isReadonly, declaration: declaration };
        }
        function getIndexInfoOfSymbol(symbol, kind) {
            var declaration = getIndexDeclarationOfSymbol(symbol, kind);
            if (declaration) {
                return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64 /* Readonly */), declaration);
            }
            return undefined;
        }
        function getConstraintDeclaration(type) {
            return ts.mapDefined(ts.filter(type.symbol && type.symbol.declarations, ts.isTypeParameterDeclaration), ts.getEffectiveConstraintOfTypeParameter)[0];
        }
        function getInferredTypeParameterConstraint(typeParameter) {
            var inferences;
            if (typeParameter.symbol) {
                for (var _i = 0, _a = typeParameter.symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (declaration.parent.kind === 181 /* InferType */) {
                        // When an 'infer T' declaration is immediately contained in a type reference node
                        // (such as 'Foo<infer T>'), T's constraint is inferred from the constraint of the
                        // corresponding type parameter in 'Foo'. When multiple 'infer T' declarations are
                        // present, we form an intersection of the inferred constraint types.
                        var grandParent = declaration.parent.parent;
                        if (grandParent.kind === 169 /* TypeReference */) {
                            var typeReference = grandParent;
                            var typeParameters = getTypeParametersForTypeReference(typeReference);
                            if (typeParameters) {
                                var index = typeReference.typeArguments.indexOf(declaration.parent);
                                if (index < typeParameters.length) {
                                    var declaredConstraint = getConstraintOfTypeParameter(typeParameters[index]);
                                    if (declaredConstraint) {
                                        // Type parameter constraints can reference other type parameters so
                                        // constraints need to be instantiated. If instantiation produces the
                                        // type parameter itself, we discard that inference. For example, in
                                        //   type Foo<T extends string, U extends T> = [T, U];
                                        //   type Bar<T> = T extends Foo<infer X, infer X> ? Foo<X, X> : T;
                                        // the instantiated constraint for U is X, so we discard that inference.
                                        var mapper = createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReference, typeParameters));
                                        var constraint = instantiateType(declaredConstraint, mapper);
                                        if (constraint !== typeParameter) {
                                            inferences = ts.append(inferences, constraint);
                                        }
                                    }
                                }
                            }
                        }
                        // When an 'infer T' declaration is immediately contained in a rest parameter
                        // declaration, we infer an 'unknown[]' constraint.
                        else if (grandParent.kind === 156 /* Parameter */ && grandParent.dotDotDotToken) {
                            inferences = ts.append(inferences, createArrayType(unknownType));
                        }
                    }
                }
            }
            return inferences && getIntersectionType(inferences);
        }
        /** This is a worker function. Use getConstraintOfTypeParameter which guards against circular constraints. */
        function getConstraintFromTypeParameter(typeParameter) {
            if (!typeParameter.constraint) {
                if (typeParameter.target) {
                    var targetConstraint = getConstraintOfTypeParameter(typeParameter.target);
                    typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper) : noConstraintType;
                }
                else {
                    var constraintDeclaration = getConstraintDeclaration(typeParameter);
                    if (!constraintDeclaration) {
                        typeParameter.constraint = getInferredTypeParameterConstraint(typeParameter) || noConstraintType;
                    }
                    else {
                        var type = getTypeFromTypeNode(constraintDeclaration);
                        if (type.flags & 1 /* Any */ && type !== errorType) { // Allow errorType to propegate to keep downstream errors suppressed
                            // use keyofConstraintType as the base constraint for mapped type key constraints (unknown isn;t assignable to that, but `any` was),
                            // use unknown otherwise
                            type = constraintDeclaration.parent.parent.kind === 186 /* MappedType */ ? keyofConstraintType : unknownType;
                        }
                        typeParameter.constraint = type;
                    }
                }
            }
            return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint;
        }
        function getParentSymbolOfTypeParameter(typeParameter) {
            var tp = ts.getDeclarationOfKind(typeParameter.symbol, 155 /* TypeParameter */);
            var host = ts.isJSDocTemplateTag(tp.parent) ? ts.getHostSignatureFromJSDoc(tp.parent) : tp.parent;
            return host && getSymbolOfNode(host);
        }
        function getTypeListId(types) {
            var result = "";
            if (types) {
                var length_4 = types.length;
                var i = 0;
                while (i < length_4) {
                    var startId = types[i].id;
                    var count = 1;
                    while (i + count < length_4 && types[i + count].id === startId + count) {
                        count++;
                    }
                    if (result.length) {
                        result += ",";
                    }
                    result += startId;
                    if (count > 1) {
                        result += ":" + count;
                    }
                    i += count;
                }
            }
            return result;
        }
        // This function is used to propagate certain flags when creating new object type references and union types.
        // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type
        // of an object literal or the anyFunctionType. This is because there are operations in the type checker
        // that care about the presence of such types at arbitrary depth in a containing type.
        function getPropagatingFlagsOfTypes(types, excludeKinds) {
            var result = 0;
            for (var _i = 0, types_8 = types; _i < types_8.length; _i++) {
                var type = types_8[_i];
                if (!(type.flags & excludeKinds)) {
                    result |= ts.getObjectFlags(type);
                }
            }
            return result & 3670016 /* PropagatingFlags */;
        }
        function createTypeReference(target, typeArguments) {
            var id = getTypeListId(typeArguments);
            var type = target.instantiations.get(id);
            if (!type) {
                type = createObjectType(4 /* Reference */, target.symbol);
                target.instantiations.set(id, type);
                type.objectFlags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
                type.target = target;
                type.resolvedTypeArguments = typeArguments;
            }
            return type;
        }
        function cloneTypeReference(source) {
            var type = createType(source.flags);
            type.symbol = source.symbol;
            type.objectFlags = source.objectFlags;
            type.target = source.target;
            type.resolvedTypeArguments = source.resolvedTypeArguments;
            return type;
        }
        function createDeferredTypeReference(target, node, mapper) {
            var aliasSymbol = getAliasSymbolForTypeNode(node);
            var aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
            var type = createObjectType(4 /* Reference */, target.symbol);
            type.target = target;
            type.node = node;
            type.mapper = mapper;
            type.aliasSymbol = aliasSymbol;
            type.aliasTypeArguments = mapper ? instantiateTypes(aliasTypeArguments, mapper) : aliasTypeArguments;
            return type;
        }
        function getTypeArguments(type) {
            var _a, _b;
            if (!type.resolvedTypeArguments) {
                if (!pushTypeResolution(type, 6 /* ResolvedTypeArguments */)) {
                    return ((_a = type.target.localTypeParameters) === null || _a === void 0 ? void 0 : _a.map(function () { return errorType; })) || ts.emptyArray;
                }
                var node = type.node;
                var typeArguments = !node ? ts.emptyArray :
                    node.kind === 169 /* TypeReference */ ? ts.concatenate(type.target.outerTypeParameters, getEffectiveTypeArguments(node, type.target.localTypeParameters)) :
                        node.kind === 174 /* ArrayType */ ? [getTypeFromTypeNode(node.elementType)] :
                            ts.map(node.elementTypes, getTypeFromTypeNode);
                if (popTypeResolution()) {
                    type.resolvedTypeArguments = type.mapper ? instantiateTypes(typeArguments, type.mapper) : typeArguments;
                }
                else {
                    type.resolvedTypeArguments = ((_b = type.target.localTypeParameters) === null || _b === void 0 ? void 0 : _b.map(function () { return errorType; })) || ts.emptyArray;
                    error(type.node || currentNode, type.target.symbol
                        ? ts.Diagnostics.Type_arguments_for_0_circularly_reference_themselves
                        : ts.Diagnostics.Tuple_type_arguments_circularly_reference_themselves, type.target.symbol && symbolToString(type.target.symbol));
                }
            }
            return type.resolvedTypeArguments;
        }
        function getTypeReferenceArity(type) {
            return ts.length(type.target.typeParameters);
        }
        /**
         * Get type from type-reference that reference to class or interface
         */
        function getTypeFromClassOrInterfaceReference(node, symbol) {
            var type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol));
            var typeParameters = type.localTypeParameters;
            if (typeParameters) {
                var numTypeArguments = ts.length(node.typeArguments);
                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                var isJs = ts.isInJSFile(node);
                var isJsImplicitAny = !noImplicitAny && isJs;
                if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) {
                    var missingAugmentsTag = isJs && ts.isExpressionWithTypeArguments(node) && !ts.isJSDocAugmentsTag(node.parent);
                    var diag = minTypeArgumentCount === typeParameters.length ?
                        missingAugmentsTag ?
                            ts.Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag :
                            ts.Diagnostics.Generic_type_0_requires_1_type_argument_s :
                        missingAugmentsTag ?
                            ts.Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag :
                            ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments;
                    var typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, 2 /* WriteArrayAsGenericType */);
                    error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length);
                    if (!isJs) {
                        // TODO: Adopt same permissive behavior in TS as in JS to reduce follow-on editing experience failures (requires editing fillMissingTypeArguments)
                        return errorType;
                    }
                }
                if (node.kind === 169 /* TypeReference */ && isDeferredTypeReferenceNode(node, ts.length(node.typeArguments) !== typeParameters.length)) {
                    return createDeferredTypeReference(type, node, /*mapper*/ undefined);
                }
                // In a type reference, the outer type parameters of the referenced class or interface are automatically
                // supplied as type arguments and the type reference only specifies arguments for the local type parameters
                // of the class or interface.
                var typeArguments = ts.concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgumentsFromTypeReferenceNode(node), typeParameters, minTypeArgumentCount, isJs));
                return createTypeReference(type, typeArguments);
            }
            return checkNoTypeArguments(node, symbol) ? type : errorType;
        }
        function getTypeAliasInstantiation(symbol, typeArguments) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var links = getSymbolLinks(symbol);
            var typeParameters = links.typeParameters;
            var id = getTypeListId(typeArguments);
            var instantiation = links.instantiations.get(id);
            if (!instantiation) {
                links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJSFile(symbol.valueDeclaration)))));
            }
            return instantiation;
        }
        /**
         * Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include
         * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the
         * declared type. Instantiations are cached using the type identities of the type arguments as the key.
         */
        function getTypeFromTypeAliasReference(node, symbol) {
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeParameters = getSymbolLinks(symbol).typeParameters;
            if (typeParameters) {
                var numTypeArguments = ts.length(node.typeArguments);
                var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) {
                    error(node, minTypeArgumentCount === typeParameters.length ?
                        ts.Diagnostics.Generic_type_0_requires_1_type_argument_s :
                        ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, symbolToString(symbol), minTypeArgumentCount, typeParameters.length);
                    return errorType;
                }
                return getTypeAliasInstantiation(symbol, typeArgumentsFromTypeReferenceNode(node));
            }
            return checkNoTypeArguments(node, symbol) ? type : errorType;
        }
        function getTypeReferenceName(node) {
            switch (node.kind) {
                case 169 /* TypeReference */:
                    return node.typeName;
                case 216 /* ExpressionWithTypeArguments */:
                    // We only support expressions that are simple qualified names. For other
                    // expressions this produces undefined.
                    var expr = node.expression;
                    if (ts.isEntityNameExpression(expr)) {
                        return expr;
                    }
                // fall through;
            }
            return undefined;
        }
        function resolveTypeReferenceName(typeReferenceName, meaning, ignoreErrors) {
            if (!typeReferenceName) {
                return unknownSymbol;
            }
            return resolveEntityName(typeReferenceName, meaning, ignoreErrors) || unknownSymbol;
        }
        function getTypeReferenceType(node, symbol) {
            if (symbol === unknownSymbol) {
                return errorType;
            }
            symbol = getExpandoSymbol(symbol) || symbol;
            if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) {
                return getTypeFromClassOrInterfaceReference(node, symbol);
            }
            if (symbol.flags & 524288 /* TypeAlias */) {
                return getTypeFromTypeAliasReference(node, symbol);
            }
            // Get type from reference to named type that cannot be generic (enum or type parameter)
            var res = tryGetDeclaredTypeOfSymbol(symbol);
            if (res) {
                return checkNoTypeArguments(node, symbol) ? getRegularTypeOfLiteralType(res) : errorType;
            }
            if (symbol.flags & 111551 /* Value */ && isJSDocTypeReference(node)) {
                var jsdocType = getTypeFromJSDocValueReference(node, symbol);
                if (jsdocType) {
                    return jsdocType;
                }
                else {
                    // Resolve the type reference as a Type for the purpose of reporting errors.
                    resolveTypeReferenceName(getTypeReferenceName(node), 788968 /* Type */);
                    return getTypeOfSymbol(symbol);
                }
            }
            return errorType;
        }
        /**
         * A JSdoc TypeReference may be to a value, but resolve it as a type anyway.
         * Note: If the value is imported from commonjs, it should really be an alias,
         * but this function's special-case code fakes alias resolution as well.
         */
        function getTypeFromJSDocValueReference(node, symbol) {
            var links = getNodeLinks(node);
            if (!links.resolvedJSDocType) {
                var valueType = getTypeOfSymbol(symbol);
                var typeType = valueType;
                if (symbol.valueDeclaration) {
                    var decl = ts.getRootDeclaration(symbol.valueDeclaration);
                    var isRequireAlias = false;
                    if (ts.isVariableDeclaration(decl) && decl.initializer) {
                        var expr = decl.initializer;
                        // skip past entity names, eg `require("x").a.b.c`
                        while (ts.isPropertyAccessExpression(expr)) {
                            expr = expr.expression;
                        }
                        isRequireAlias = ts.isCallExpression(expr) && ts.isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !!valueType.symbol;
                    }
                    var isImportTypeWithQualifier = node.kind === 188 /* ImportType */ && node.qualifier;
                    // valueType might not have a symbol, eg, {import('./b').STRING_LITERAL}
                    if (valueType.symbol && (isRequireAlias || isImportTypeWithQualifier)) {
                        typeType = getTypeReferenceType(node, valueType.symbol);
                    }
                }
                links.resolvedJSDocType = typeType;
            }
            return links.resolvedJSDocType;
        }
        function getSubstitutionType(baseType, substitute) {
            if (substitute.flags & 3 /* AnyOrUnknown */ || substitute === baseType) {
                return baseType;
            }
            var id = getTypeId(baseType) + ">" + getTypeId(substitute);
            var cached = substitutionTypes.get(id);
            if (cached) {
                return cached;
            }
            var result = createType(33554432 /* Substitution */);
            result.baseType = baseType;
            result.substitute = substitute;
            substitutionTypes.set(id, result);
            return result;
        }
        function isUnaryTupleTypeNode(node) {
            return node.kind === 175 /* TupleType */ && node.elementTypes.length === 1;
        }
        function getImpliedConstraint(type, checkNode, extendsNode) {
            return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(type, checkNode.elementTypes[0], extendsNode.elementTypes[0]) :
                getActualTypeVariable(getTypeFromTypeNode(checkNode)) === type ? getTypeFromTypeNode(extendsNode) :
                    undefined;
        }
        function getConditionalFlowTypeOfType(type, node) {
            var constraints;
            while (node && !ts.isStatement(node) && node.kind !== 303 /* JSDocComment */) {
                var parent = node.parent;
                if (parent.kind === 180 /* ConditionalType */ && node === parent.trueType) {
                    var constraint = getImpliedConstraint(type, parent.checkType, parent.extendsType);
                    if (constraint) {
                        constraints = ts.append(constraints, constraint);
                    }
                }
                node = parent;
            }
            return constraints ? getSubstitutionType(type, getIntersectionType(ts.append(constraints, type))) : type;
        }
        function isJSDocTypeReference(node) {
            return !!(node.flags & 4194304 /* JSDoc */) && (node.kind === 169 /* TypeReference */ || node.kind === 188 /* ImportType */);
        }
        function checkNoTypeArguments(node, symbol) {
            if (node.typeArguments) {
                error(node, ts.Diagnostics.Type_0_is_not_generic, symbol ? symbolToString(symbol) : node.typeName ? ts.declarationNameToString(node.typeName) : anon);
                return false;
            }
            return true;
        }
        function getIntendedTypeFromJSDocTypeReference(node) {
            if (ts.isIdentifier(node.typeName)) {
                var typeArgs = node.typeArguments;
                switch (node.typeName.escapedText) {
                    case "String":
                        checkNoTypeArguments(node);
                        return stringType;
                    case "Number":
                        checkNoTypeArguments(node);
                        return numberType;
                    case "Boolean":
                        checkNoTypeArguments(node);
                        return booleanType;
                    case "Void":
                        checkNoTypeArguments(node);
                        return voidType;
                    case "Undefined":
                        checkNoTypeArguments(node);
                        return undefinedType;
                    case "Null":
                        checkNoTypeArguments(node);
                        return nullType;
                    case "Function":
                    case "function":
                        checkNoTypeArguments(node);
                        return globalFunctionType;
                    case "array":
                        return (!typeArgs || !typeArgs.length) && !noImplicitAny ? anyArrayType : undefined;
                    case "promise":
                        return (!typeArgs || !typeArgs.length) && !noImplicitAny ? createPromiseType(anyType) : undefined;
                    case "Object":
                        if (typeArgs && typeArgs.length === 2) {
                            if (ts.isJSDocIndexSignature(node)) {
                                var indexed = getTypeFromTypeNode(typeArgs[0]);
                                var target = getTypeFromTypeNode(typeArgs[1]);
                                var index = createIndexInfo(target, /*isReadonly*/ false);
                                return createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, indexed === stringType ? index : undefined, indexed === numberType ? index : undefined);
                            }
                            return anyType;
                        }
                        checkNoTypeArguments(node);
                        return !noImplicitAny ? anyType : undefined;
                }
            }
        }
        function getTypeFromJSDocNullableTypeNode(node) {
            var type = getTypeFromTypeNode(node.type);
            return strictNullChecks ? getNullableType(type, 65536 /* Null */) : type;
        }
        function getTypeFromTypeReference(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // handle LS queries on the `const` in `x as const` by resolving to the type of `x`
                if (ts.isConstTypeReference(node) && ts.isAssertionExpression(node.parent)) {
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = checkExpressionCached(node.parent.expression);
                }
                var symbol = void 0;
                var type = void 0;
                var meaning = 788968 /* Type */;
                if (isJSDocTypeReference(node)) {
                    type = getIntendedTypeFromJSDocTypeReference(node);
                    if (!type) {
                        symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning, /*ignoreErrors*/ true);
                        if (symbol === unknownSymbol) {
                            symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning | 111551 /* Value */);
                        }
                        else {
                            resolveTypeReferenceName(getTypeReferenceName(node), meaning); // Resolve again to mark errors, if any
                        }
                        type = getTypeReferenceType(node, symbol);
                    }
                }
                if (!type) {
                    symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning);
                    type = getTypeReferenceType(node, symbol);
                }
                // Cache both the resolved symbol and the resolved type. The resolved symbol is needed when we check the
                // type reference in checkTypeReferenceNode.
                links.resolvedSymbol = symbol;
                links.resolvedType = type;
            }
            return links.resolvedType;
        }
        function typeArgumentsFromTypeReferenceNode(node) {
            return ts.map(node.typeArguments, getTypeFromTypeNode);
        }
        function getTypeFromTypeQueryNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // TypeScript 1.0 spec (April 2014): 3.6.3
                // The expression is processed as an identifier expression (section 4.3)
                // or property access expression(section 4.10),
                // the widened type(section 3.9) of which becomes the result.
                links.resolvedType = getRegularTypeOfLiteralType(getWidenedType(checkExpression(node.exprName)));
            }
            return links.resolvedType;
        }
        function getTypeOfGlobalSymbol(symbol, arity) {
            function getTypeDeclaration(symbol) {
                var declarations = symbol.declarations;
                for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) {
                    var declaration = declarations_3[_i];
                    switch (declaration.kind) {
                        case 245 /* ClassDeclaration */:
                        case 246 /* InterfaceDeclaration */:
                        case 248 /* EnumDeclaration */:
                            return declaration;
                    }
                }
            }
            if (!symbol) {
                return arity ? emptyGenericType : emptyObjectType;
            }
            var type = getDeclaredTypeOfSymbol(symbol);
            if (!(type.flags & 524288 /* Object */)) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, ts.symbolName(symbol));
                return arity ? emptyGenericType : emptyObjectType;
            }
            if (ts.length(type.typeParameters) !== arity) {
                error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, ts.symbolName(symbol), arity);
                return arity ? emptyGenericType : emptyObjectType;
            }
            return type;
        }
        function getGlobalValueSymbol(name, reportErrors) {
            return getGlobalSymbol(name, 111551 /* Value */, reportErrors ? ts.Diagnostics.Cannot_find_global_value_0 : undefined);
        }
        function getGlobalTypeSymbol(name, reportErrors) {
            return getGlobalSymbol(name, 788968 /* Type */, reportErrors ? ts.Diagnostics.Cannot_find_global_type_0 : undefined);
        }
        function getGlobalSymbol(name, meaning, diagnostic) {
            // Don't track references for global symbols anyway, so value if `isReference` is arbitrary
            return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false);
        }
        function getGlobalType(name, arity, reportErrors) {
            var symbol = getGlobalTypeSymbol(name, reportErrors);
            return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined;
        }
        function getGlobalTypedPropertyDescriptorType() {
            return deferredGlobalTypedPropertyDescriptorType || (deferredGlobalTypedPropertyDescriptorType = getGlobalType("TypedPropertyDescriptor", /*arity*/ 1, /*reportErrors*/ true)) || emptyGenericType;
        }
        function getGlobalTemplateStringsArrayType() {
            return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
        }
        function getGlobalImportMetaType() {
            return deferredGlobalImportMetaType || (deferredGlobalImportMetaType = getGlobalType("ImportMeta", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
        }
        function getGlobalESSymbolConstructorSymbol(reportErrors) {
            return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol", reportErrors));
        }
        function getGlobalESSymbolType(reportErrors) {
            return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        function getGlobalPromiseType(reportErrors) {
            return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalPromiseLikeType(reportErrors) {
            return deferredGlobalPromiseLikeType || (deferredGlobalPromiseLikeType = getGlobalType("PromiseLike", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalPromiseConstructorSymbol(reportErrors) {
            return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise", reportErrors));
        }
        function getGlobalPromiseConstructorLikeType(reportErrors) {
            return deferredGlobalPromiseConstructorLikeType || (deferredGlobalPromiseConstructorLikeType = getGlobalType("PromiseConstructorLike", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        function getGlobalAsyncIterableType(reportErrors) {
            return deferredGlobalAsyncIterableType || (deferredGlobalAsyncIterableType = getGlobalType("AsyncIterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncIteratorType(reportErrors) {
            return deferredGlobalAsyncIteratorType || (deferredGlobalAsyncIteratorType = getGlobalType("AsyncIterator", /*arity*/ 3, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncIterableIteratorType(reportErrors) {
            return deferredGlobalAsyncIterableIteratorType || (deferredGlobalAsyncIterableIteratorType = getGlobalType("AsyncIterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalAsyncGeneratorType(reportErrors) {
            return deferredGlobalAsyncGeneratorType || (deferredGlobalAsyncGeneratorType = getGlobalType("AsyncGenerator", /*arity*/ 3, reportErrors)) || emptyGenericType;
        }
        function getGlobalIterableType(reportErrors) {
            return deferredGlobalIterableType || (deferredGlobalIterableType = getGlobalType("Iterable", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIteratorType(reportErrors) {
            return deferredGlobalIteratorType || (deferredGlobalIteratorType = getGlobalType("Iterator", /*arity*/ 3, reportErrors)) || emptyGenericType;
        }
        function getGlobalIterableIteratorType(reportErrors) {
            return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalGeneratorType(reportErrors) {
            return deferredGlobalGeneratorType || (deferredGlobalGeneratorType = getGlobalType("Generator", /*arity*/ 3, reportErrors)) || emptyGenericType;
        }
        function getGlobalIteratorYieldResultType(reportErrors) {
            return deferredGlobalIteratorYieldResultType || (deferredGlobalIteratorYieldResultType = getGlobalType("IteratorYieldResult", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalIteratorReturnResultType(reportErrors) {
            return deferredGlobalIteratorReturnResultType || (deferredGlobalIteratorReturnResultType = getGlobalType("IteratorReturnResult", /*arity*/ 1, reportErrors)) || emptyGenericType;
        }
        function getGlobalTypeOrUndefined(name, arity) {
            if (arity === void 0) { arity = 0; }
            var symbol = getGlobalSymbol(name, 788968 /* Type */, /*diagnostic*/ undefined);
            return symbol && getTypeOfGlobalSymbol(symbol, arity);
        }
        function getGlobalExtractSymbol() {
            return deferredGlobalExtractSymbol || (deferredGlobalExtractSymbol = getGlobalSymbol("Extract", 524288 /* TypeAlias */, ts.Diagnostics.Cannot_find_global_type_0)); // TODO: GH#18217
        }
        function getGlobalOmitSymbol() {
            return deferredGlobalOmitSymbol || (deferredGlobalOmitSymbol = getGlobalSymbol("Omit", 524288 /* TypeAlias */, ts.Diagnostics.Cannot_find_global_type_0)); // TODO: GH#18217
        }
        function getGlobalBigIntType(reportErrors) {
            return deferredGlobalBigIntType || (deferredGlobalBigIntType = getGlobalType("BigInt", /*arity*/ 0, reportErrors)) || emptyObjectType;
        }
        /**
         * Instantiates a global type that is generic with some element type, and returns that instantiation.
         */
        function createTypeFromGenericGlobalType(genericGlobalType, typeArguments) {
            return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, typeArguments) : emptyObjectType;
        }
        function createTypedPropertyDescriptorType(propertyType) {
            return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]);
        }
        function createIterableType(iteratedType) {
            return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]);
        }
        function createArrayType(elementType, readonly) {
            return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]);
        }
        function getArrayOrTupleTargetType(node) {
            var readonly = isReadonlyTypeOperator(node.parent);
            if (node.kind === 174 /* ArrayType */ || node.elementTypes.length === 1 && node.elementTypes[0].kind === 177 /* RestType */) {
                return readonly ? globalReadonlyArrayType : globalArrayType;
            }
            var lastElement = ts.lastOrUndefined(node.elementTypes);
            var restElement = lastElement && lastElement.kind === 177 /* RestType */ ? lastElement : undefined;
            var minLength = ts.findLastIndex(node.elementTypes, function (n) { return n.kind !== 176 /* OptionalType */ && n !== restElement; }) + 1;
            return getTupleTypeOfArity(node.elementTypes.length, minLength, !!restElement, readonly, /*associatedNames*/ undefined);
        }
        // Return true if the given type reference node is directly aliased or if it needs to be deferred
        // because it is possibly contained in a circular chain of eagerly resolved types.
        function isDeferredTypeReferenceNode(node, hasDefaultTypeArguments) {
            return !!getAliasSymbolForTypeNode(node) || isResolvedByTypeAlias(node) && (node.kind === 174 /* ArrayType */ ? mayResolveTypeAlias(node.elementType) :
                node.kind === 175 /* TupleType */ ? ts.some(node.elementTypes, mayResolveTypeAlias) :
                    hasDefaultTypeArguments || ts.some(node.typeArguments, mayResolveTypeAlias));
        }
        // Return true when the given node is transitively contained in type constructs that eagerly
        // resolve their constituent types. We include SyntaxKind.TypeReference because type arguments
        // of type aliases are eagerly resolved.
        function isResolvedByTypeAlias(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 182 /* ParenthesizedType */:
                case 169 /* TypeReference */:
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                case 185 /* IndexedAccessType */:
                case 180 /* ConditionalType */:
                case 184 /* TypeOperator */:
                case 174 /* ArrayType */:
                case 175 /* TupleType */:
                    return isResolvedByTypeAlias(parent);
                case 247 /* TypeAliasDeclaration */:
                    return true;
            }
            return false;
        }
        // Return true if resolving the given node (i.e. getTypeFromTypeNode) possibly causes resolution
        // of a type alias.
        function mayResolveTypeAlias(node) {
            switch (node.kind) {
                case 169 /* TypeReference */:
                    return isJSDocTypeReference(node) || !!(resolveTypeReferenceName(node.typeName, 788968 /* Type */).flags & 524288 /* TypeAlias */);
                case 172 /* TypeQuery */:
                    return true;
                case 184 /* TypeOperator */:
                    return node.operator !== 147 /* UniqueKeyword */ && mayResolveTypeAlias(node.type);
                case 182 /* ParenthesizedType */:
                case 176 /* OptionalType */:
                case 299 /* JSDocOptionalType */:
                case 297 /* JSDocNullableType */:
                case 298 /* JSDocNonNullableType */:
                case 294 /* JSDocTypeExpression */:
                    return mayResolveTypeAlias(node.type);
                case 177 /* RestType */:
                    return node.type.kind !== 174 /* ArrayType */ || mayResolveTypeAlias(node.type.elementType);
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                    return ts.some(node.types, mayResolveTypeAlias);
                case 185 /* IndexedAccessType */:
                    return mayResolveTypeAlias(node.objectType) || mayResolveTypeAlias(node.indexType);
                case 180 /* ConditionalType */:
                    return mayResolveTypeAlias(node.checkType) || mayResolveTypeAlias(node.extendsType) ||
                        mayResolveTypeAlias(node.trueType) || mayResolveTypeAlias(node.falseType);
            }
            return false;
        }
        function getTypeFromArrayOrTupleTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var target = getArrayOrTupleTargetType(node);
                if (target === emptyGenericType) {
                    links.resolvedType = emptyObjectType;
                }
                else if (isDeferredTypeReferenceNode(node)) {
                    links.resolvedType = node.kind === 175 /* TupleType */ && node.elementTypes.length === 0 ? target :
                        createDeferredTypeReference(target, node, /*mapper*/ undefined);
                }
                else {
                    var elementTypes = node.kind === 174 /* ArrayType */ ? [getTypeFromTypeNode(node.elementType)] : ts.map(node.elementTypes, getTypeFromTypeNode);
                    links.resolvedType = createTypeReference(target, elementTypes);
                }
            }
            return links.resolvedType;
        }
        function isReadonlyTypeOperator(node) {
            return ts.isTypeOperatorNode(node) && node.operator === 138 /* ReadonlyKeyword */;
        }
        // We represent tuple types as type references to synthesized generic interface types created by
        // this function. The types are of the form:
        //
        //   interface Tuple<T0, T1, T2, ...> extends Array<T0 | T1 | T2 | ...> { 0: T0, 1: T1, 2: T2, ... }
        //
        // Note that the generic type created by this function has no symbol associated with it. The same
        // is true for each of the synthesized type parameters.
        function createTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames) {
            var typeParameters;
            var properties = [];
            var maxLength = hasRestElement ? arity - 1 : arity;
            if (arity) {
                typeParameters = new Array(arity);
                for (var i = 0; i < arity; i++) {
                    var typeParameter = typeParameters[i] = createTypeParameter();
                    if (i < maxLength) {
                        var property = createSymbol(4 /* Property */ | (i >= minLength ? 16777216 /* Optional */ : 0), "" + i, readonly ? 8 /* Readonly */ : 0);
                        property.type = typeParameter;
                        properties.push(property);
                    }
                }
            }
            var literalTypes = [];
            for (var i = minLength; i <= maxLength; i++)
                literalTypes.push(getLiteralType(i));
            var lengthSymbol = createSymbol(4 /* Property */, "length");
            lengthSymbol.type = hasRestElement ? numberType : getUnionType(literalTypes);
            properties.push(lengthSymbol);
            var type = createObjectType(8 /* Tuple */ | 4 /* Reference */);
            type.typeParameters = typeParameters;
            type.outerTypeParameters = undefined;
            type.localTypeParameters = typeParameters;
            type.instantiations = ts.createMap();
            type.instantiations.set(getTypeListId(type.typeParameters), type);
            type.target = type;
            type.resolvedTypeArguments = type.typeParameters;
            type.thisType = createTypeParameter();
            type.thisType.isThisType = true;
            type.thisType.constraint = type;
            type.declaredProperties = properties;
            type.declaredCallSignatures = ts.emptyArray;
            type.declaredConstructSignatures = ts.emptyArray;
            type.declaredStringIndexInfo = undefined;
            type.declaredNumberIndexInfo = undefined;
            type.minLength = minLength;
            type.hasRestElement = hasRestElement;
            type.readonly = readonly;
            type.associatedNames = associatedNames;
            return type;
        }
        function getTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames) {
            var key = arity + (hasRestElement ? "+" : ",") + minLength + (readonly ? "R" : "") + (associatedNames && associatedNames.length ? "," + associatedNames.join(",") : "");
            var type = tupleTypes.get(key);
            if (!type) {
                tupleTypes.set(key, type = createTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames));
            }
            return type;
        }
        function createTupleType(elementTypes, minLength, hasRestElement, readonly, associatedNames) {
            if (minLength === void 0) { minLength = elementTypes.length; }
            if (hasRestElement === void 0) { hasRestElement = false; }
            if (readonly === void 0) { readonly = false; }
            var arity = elementTypes.length;
            if (arity === 1 && hasRestElement) {
                return createArrayType(elementTypes[0], readonly);
            }
            var tupleType = getTupleTypeOfArity(arity, minLength, arity > 0 && hasRestElement, readonly, associatedNames);
            return elementTypes.length ? createTypeReference(tupleType, elementTypes) : tupleType;
        }
        function sliceTupleType(type, index) {
            var tuple = type.target;
            if (tuple.hasRestElement) {
                // don't slice off rest element
                index = Math.min(index, getTypeReferenceArity(type) - 1);
            }
            return createTupleType(getTypeArguments(type).slice(index), Math.max(0, tuple.minLength - index), tuple.hasRestElement, tuple.readonly, tuple.associatedNames && tuple.associatedNames.slice(index));
        }
        function getTypeFromOptionalTypeNode(node) {
            var type = getTypeFromTypeNode(node.type);
            return strictNullChecks ? getOptionalType(type) : type;
        }
        function getTypeId(type) {
            return type.id;
        }
        function containsType(types, type) {
            return ts.binarySearch(types, type, getTypeId, ts.compareValues) >= 0;
        }
        function insertType(types, type) {
            var index = ts.binarySearch(types, type, getTypeId, ts.compareValues);
            if (index < 0) {
                types.splice(~index, 0, type);
                return true;
            }
            return false;
        }
        function addTypeToUnion(typeSet, includes, type) {
            var flags = type.flags;
            if (flags & 1048576 /* Union */) {
                return addTypesToUnion(typeSet, includes, type.types);
            }
            // We ignore 'never' types in unions
            if (!(flags & 131072 /* Never */)) {
                includes |= flags & 71041023 /* IncludesMask */;
                if (flags & 66846720 /* StructuredOrInstantiable */)
                    includes |= 262144 /* IncludesStructuredOrInstantiable */;
                if (type === wildcardType)
                    includes |= 8388608 /* IncludesWildcard */;
                if (!strictNullChecks && flags & 98304 /* Nullable */) {
                    if (!(ts.getObjectFlags(type) & 524288 /* ContainsWideningType */))
                        includes |= 4194304 /* IncludesNonWideningType */;
                }
                else {
                    var len = typeSet.length;
                    var index = len && type.id > typeSet[len - 1].id ? ~len : ts.binarySearch(typeSet, type, getTypeId, ts.compareValues);
                    if (index < 0) {
                        typeSet.splice(~index, 0, type);
                    }
                }
            }
            return includes;
        }
        // Add the given types to the given type set. Order is preserved, duplicates are removed,
        // and nested types of the given kind are flattened into the set.
        function addTypesToUnion(typeSet, includes, types) {
            for (var _i = 0, types_9 = types; _i < types_9.length; _i++) {
                var type = types_9[_i];
                includes = addTypeToUnion(typeSet, includes, type);
            }
            return includes;
        }
        function isSetOfLiteralsFromSameEnum(types) {
            var first = types[0];
            if (first.flags & 1024 /* EnumLiteral */) {
                var firstEnum = getParentOfSymbol(first.symbol);
                for (var i = 1; i < types.length; i++) {
                    var other = types[i];
                    if (!(other.flags & 1024 /* EnumLiteral */) || (firstEnum !== getParentOfSymbol(other.symbol))) {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }
        function removeSubtypes(types, primitivesOnly) {
            var len = types.length;
            if (len === 0 || isSetOfLiteralsFromSameEnum(types)) {
                return true;
            }
            var i = len;
            var count = 0;
            while (i > 0) {
                i--;
                var source = types[i];
                for (var _i = 0, types_10 = types; _i < types_10.length; _i++) {
                    var target = types_10[_i];
                    if (source !== target) {
                        if (count === 100000) {
                            // After 100000 subtype checks we estimate the remaining amount of work by assuming the
                            // same ratio of checks per element. If the estimated number of remaining type checks is
                            // greater than an upper limit we deem the union type too complex to represent. The
                            // upper limit is 25M for unions of primitives only, and 1M otherwise. This for example
                            // caps union types at 5000 unique literal types and 1000 unique object types.
                            var estimatedCount = (count / (len - i)) * len;
                            if (estimatedCount > (primitivesOnly ? 25000000 : 1000000)) {
                                error(currentNode, ts.Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
                                return false;
                            }
                        }
                        count++;
                        if (isTypeRelatedTo(source, target, strictSubtypeRelation) && (!(ts.getObjectFlags(getTargetType(source)) & 1 /* Class */) ||
                            !(ts.getObjectFlags(getTargetType(target)) & 1 /* Class */) ||
                            isTypeDerivedFrom(source, target))) {
                            ts.orderedRemoveItemAt(types, i);
                            break;
                        }
                    }
                }
            }
            return true;
        }
        function removeRedundantLiteralTypes(types, includes) {
            var i = types.length;
            while (i > 0) {
                i--;
                var t = types[i];
                var remove = t.flags & 128 /* StringLiteral */ && includes & 4 /* String */ ||
                    t.flags & 256 /* NumberLiteral */ && includes & 8 /* Number */ ||
                    t.flags & 2048 /* BigIntLiteral */ && includes & 64 /* BigInt */ ||
                    t.flags & 8192 /* UniqueESSymbol */ && includes & 4096 /* ESSymbol */ ||
                    isFreshLiteralType(t) && containsType(types, t.regularType);
                if (remove) {
                    ts.orderedRemoveItemAt(types, i);
                }
            }
        }
        // We sort and deduplicate the constituent types based on object identity. If the subtypeReduction
        // flag is specified we also reduce the constituent type set to only include types that aren't subtypes
        // of other types. Subtype reduction is expensive for large union types and is possible only when union
        // types are known not to circularly reference themselves (as is the case with union types created by
        // expression constructs such as array literals and the || and ?: operators). Named types can
        // circularly reference themselves and therefore cannot be subtype reduced during their declaration.
        // For example, "type Item = string | (() => Item" is a named type that circularly references itself.
        function getUnionType(types, unionReduction, aliasSymbol, aliasTypeArguments) {
            if (unionReduction === void 0) { unionReduction = 1 /* Literal */; }
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var typeSet = [];
            var includes = addTypesToUnion(typeSet, 0, types);
            if (unionReduction !== 0 /* None */) {
                if (includes & 3 /* AnyOrUnknown */) {
                    return includes & 1 /* Any */ ? includes & 8388608 /* IncludesWildcard */ ? wildcardType : anyType : unknownType;
                }
                switch (unionReduction) {
                    case 1 /* Literal */:
                        if (includes & (2944 /* Literal */ | 8192 /* UniqueESSymbol */)) {
                            removeRedundantLiteralTypes(typeSet, includes);
                        }
                        break;
                    case 2 /* Subtype */:
                        if (!removeSubtypes(typeSet, !(includes & 262144 /* IncludesStructuredOrInstantiable */))) {
                            return errorType;
                        }
                        break;
                }
                if (typeSet.length === 0) {
                    return includes & 65536 /* Null */ ? includes & 4194304 /* IncludesNonWideningType */ ? nullType : nullWideningType :
                        includes & 32768 /* Undefined */ ? includes & 4194304 /* IncludesNonWideningType */ ? undefinedType : undefinedWideningType :
                            neverType;
                }
            }
            var objectFlags = (includes & 66994211 /* NotPrimitiveUnion */ ? 0 : 262144 /* PrimitiveUnion */) |
                (includes & 2097152 /* Intersection */ ? 268435456 /* ContainsIntersections */ : 0);
            return getUnionTypeFromSortedList(typeSet, objectFlags, aliasSymbol, aliasTypeArguments);
        }
        function getUnionTypePredicate(signatures) {
            var first;
            var types = [];
            for (var _i = 0, signatures_6 = signatures; _i < signatures_6.length; _i++) {
                var sig = signatures_6[_i];
                var pred = getTypePredicateOfSignature(sig);
                if (!pred || pred.kind === 2 /* AssertsThis */ || pred.kind === 3 /* AssertsIdentifier */) {
                    continue;
                }
                if (first) {
                    if (!typePredicateKindsMatch(first, pred)) {
                        // No common type predicate.
                        return undefined;
                    }
                }
                else {
                    first = pred;
                }
                types.push(pred.type);
            }
            if (!first) {
                // No union signatures had a type predicate.
                return undefined;
            }
            var unionType = getUnionType(types);
            return createTypePredicate(first.kind, first.parameterName, first.parameterIndex, unionType);
        }
        function typePredicateKindsMatch(a, b) {
            return a.kind === b.kind && a.parameterIndex === b.parameterIndex;
        }
        // This function assumes the constituent type list is sorted and deduplicated.
        function getUnionTypeFromSortedList(types, objectFlags, aliasSymbol, aliasTypeArguments) {
            if (types.length === 0) {
                return neverType;
            }
            if (types.length === 1) {
                return types[0];
            }
            var id = getTypeListId(types);
            var type = unionTypes.get(id);
            if (!type) {
                type = createType(1048576 /* Union */);
                unionTypes.set(id, type);
                type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 98304 /* Nullable */);
                type.types = types;
                /*
                Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type.
                For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol.
                (In the language service, the order may depend on the order in which a user takes actions, such as hovering over symbols.)
                It's important that we create equivalent union types only once, so that's an unfortunate side effect.
                */
                type.aliasSymbol = aliasSymbol;
                type.aliasTypeArguments = aliasTypeArguments;
            }
            return type;
        }
        function getTypeFromUnionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), 1 /* Literal */, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
            }
            return links.resolvedType;
        }
        function addTypeToIntersection(typeSet, includes, type) {
            var flags = type.flags;
            if (flags & 2097152 /* Intersection */) {
                return addTypesToIntersection(typeSet, includes, type.types);
            }
            if (isEmptyAnonymousObjectType(type)) {
                if (!(includes & 16777216 /* IncludesEmptyObject */)) {
                    includes |= 16777216 /* IncludesEmptyObject */;
                    typeSet.set(type.id.toString(), type);
                }
            }
            else {
                if (flags & 3 /* AnyOrUnknown */) {
                    if (type === wildcardType)
                        includes |= 8388608 /* IncludesWildcard */;
                }
                else if ((strictNullChecks || !(flags & 98304 /* Nullable */)) && !typeSet.has(type.id.toString())) {
                    if (type.flags & 109440 /* Unit */ && includes & 109440 /* Unit */) {
                        // We have seen two distinct unit types which means we should reduce to an
                        // empty intersection. Adding TypeFlags.NonPrimitive causes that to happen.
                        includes |= 67108864 /* NonPrimitive */;
                    }
                    typeSet.set(type.id.toString(), type);
                }
                includes |= flags & 71041023 /* IncludesMask */;
            }
            return includes;
        }
        // Add the given types to the given type set. Order is preserved, freshness is removed from literal
        // types, duplicates are removed, and nested types of the given kind are flattened into the set.
        function addTypesToIntersection(typeSet, includes, types) {
            for (var _i = 0, types_11 = types; _i < types_11.length; _i++) {
                var type = types_11[_i];
                includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type));
            }
            return includes;
        }
        function removeRedundantPrimitiveTypes(types, includes) {
            var i = types.length;
            while (i > 0) {
                i--;
                var t = types[i];
                var remove = t.flags & 4 /* String */ && includes & 128 /* StringLiteral */ ||
                    t.flags & 8 /* Number */ && includes & 256 /* NumberLiteral */ ||
                    t.flags & 64 /* BigInt */ && includes & 2048 /* BigIntLiteral */ ||
                    t.flags & 4096 /* ESSymbol */ && includes & 8192 /* UniqueESSymbol */;
                if (remove) {
                    ts.orderedRemoveItemAt(types, i);
                }
            }
        }
        // Check that the given type has a match in every union. A given type is matched by
        // an identical type, and a literal type is additionally matched by its corresponding
        // primitive type.
        function eachUnionContains(unionTypes, type) {
            for (var _i = 0, unionTypes_1 = unionTypes; _i < unionTypes_1.length; _i++) {
                var u = unionTypes_1[_i];
                if (!containsType(u.types, type)) {
                    var primitive = type.flags & 128 /* StringLiteral */ ? stringType :
                        type.flags & 256 /* NumberLiteral */ ? numberType :
                            type.flags & 2048 /* BigIntLiteral */ ? bigintType :
                                type.flags & 8192 /* UniqueESSymbol */ ? esSymbolType :
                                    undefined;
                    if (!primitive || !containsType(u.types, primitive)) {
                        return false;
                    }
                }
            }
            return true;
        }
        function extractIrreducible(types, flag) {
            if (ts.every(types, function (t) { return !!(t.flags & 1048576 /* Union */) && ts.some(t.types, function (tt) { return !!(tt.flags & flag); }); })) {
                for (var i = 0; i < types.length; i++) {
                    types[i] = filterType(types[i], function (t) { return !(t.flags & flag); });
                }
                return true;
            }
            return false;
        }
        // If the given list of types contains more than one union of primitive types, replace the
        // first with a union containing an intersection of those primitive types, then remove the
        // other unions and return true. Otherwise, do nothing and return false.
        function intersectUnionsOfPrimitiveTypes(types) {
            var unionTypes;
            var index = ts.findIndex(types, function (t) { return !!(ts.getObjectFlags(t) & 262144 /* PrimitiveUnion */); });
            if (index < 0) {
                return false;
            }
            var i = index + 1;
            // Remove all but the first union of primitive types and collect them in
            // the unionTypes array.
            while (i < types.length) {
                var t = types[i];
                if (ts.getObjectFlags(t) & 262144 /* PrimitiveUnion */) {
                    (unionTypes || (unionTypes = [types[index]])).push(t);
                    ts.orderedRemoveItemAt(types, i);
                }
                else {
                    i++;
                }
            }
            // Return false if there was only one union of primitive types
            if (!unionTypes) {
                return false;
            }
            // We have more than one union of primitive types, now intersect them. For each
            // type in each union we check if the type is matched in every union and if so
            // we include it in the result.
            var checked = [];
            var result = [];
            for (var _i = 0, unionTypes_2 = unionTypes; _i < unionTypes_2.length; _i++) {
                var u = unionTypes_2[_i];
                for (var _a = 0, _b = u.types; _a < _b.length; _a++) {
                    var t = _b[_a];
                    if (insertType(checked, t)) {
                        if (eachUnionContains(unionTypes, t)) {
                            insertType(result, t);
                        }
                    }
                }
            }
            // Finally replace the first union with the result
            types[index] = getUnionTypeFromSortedList(result, 262144 /* PrimitiveUnion */);
            return true;
        }
        function createIntersectionType(types, aliasSymbol, aliasTypeArguments) {
            var result = createType(2097152 /* Intersection */);
            result.objectFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 98304 /* Nullable */);
            result.types = types;
            result.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
            result.aliasTypeArguments = aliasTypeArguments;
            return result;
        }
        // We normalize combinations of intersection and union types based on the distributive property of the '&'
        // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
        // types with union type constituents into equivalent union types with intersection type constituents and
        // effectively ensure that union types are always at the top level in type representations.
        //
        // We do not perform structural deduplication on intersection types. Intersection types are created only by the &
        // type operator and we can't reduce those because we want to support recursive intersection types. For example,
        // a type alias of the form "type List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
        // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
        // for intersections of types with signatures can be deterministic.
        function getIntersectionType(types, aliasSymbol, aliasTypeArguments) {
            var typeMembershipMap = ts.createMap();
            var includes = addTypesToIntersection(typeMembershipMap, 0, types);
            var typeSet = ts.arrayFrom(typeMembershipMap.values());
            // An intersection type is considered empty if it contains
            // the type never, or
            // more than one unit type or,
            // an object type and a nullable type (null or undefined), or
            // a string-like type and a type known to be non-string-like, or
            // a number-like type and a type known to be non-number-like, or
            // a symbol-like type and a type known to be non-symbol-like, or
            // a void-like type and a type known to be non-void-like, or
            // a non-primitive type and a type known to be primitive.
            if (includes & 131072 /* Never */ ||
                strictNullChecks && includes & 98304 /* Nullable */ && includes & (524288 /* Object */ | 67108864 /* NonPrimitive */ | 16777216 /* IncludesEmptyObject */) ||
                includes & 67108864 /* NonPrimitive */ && includes & (67238908 /* DisjointDomains */ & ~67108864 /* NonPrimitive */) ||
                includes & 132 /* StringLike */ && includes & (67238908 /* DisjointDomains */ & ~132 /* StringLike */) ||
                includes & 296 /* NumberLike */ && includes & (67238908 /* DisjointDomains */ & ~296 /* NumberLike */) ||
                includes & 2112 /* BigIntLike */ && includes & (67238908 /* DisjointDomains */ & ~2112 /* BigIntLike */) ||
                includes & 12288 /* ESSymbolLike */ && includes & (67238908 /* DisjointDomains */ & ~12288 /* ESSymbolLike */) ||
                includes & 49152 /* VoidLike */ && includes & (67238908 /* DisjointDomains */ & ~49152 /* VoidLike */)) {
                return neverType;
            }
            if (includes & 1 /* Any */) {
                return includes & 8388608 /* IncludesWildcard */ ? wildcardType : anyType;
            }
            if (!strictNullChecks && includes & 98304 /* Nullable */) {
                return includes & 32768 /* Undefined */ ? undefinedType : nullType;
            }
            if (includes & 4 /* String */ && includes & 128 /* StringLiteral */ ||
                includes & 8 /* Number */ && includes & 256 /* NumberLiteral */ ||
                includes & 64 /* BigInt */ && includes & 2048 /* BigIntLiteral */ ||
                includes & 4096 /* ESSymbol */ && includes & 8192 /* UniqueESSymbol */) {
                removeRedundantPrimitiveTypes(typeSet, includes);
            }
            if (includes & 16777216 /* IncludesEmptyObject */ && includes & 524288 /* Object */) {
                ts.orderedRemoveItemAt(typeSet, ts.findIndex(typeSet, isEmptyAnonymousObjectType));
            }
            if (typeSet.length === 0) {
                return unknownType;
            }
            if (typeSet.length === 1) {
                return typeSet[0];
            }
            var id = getTypeListId(typeSet);
            var result = intersectionTypes.get(id);
            if (!result) {
                if (includes & 1048576 /* Union */) {
                    if (intersectUnionsOfPrimitiveTypes(typeSet)) {
                        // When the intersection creates a reduced set (which might mean that *all* union types have
                        // disappeared), we restart the operation to get a new set of combined flags. Once we have
                        // reduced we'll never reduce again, so this occurs at most once.
                        result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
                    }
                    else if (extractIrreducible(typeSet, 32768 /* Undefined */)) {
                        result = getUnionType([getIntersectionType(typeSet), undefinedType], 1 /* Literal */, aliasSymbol, aliasTypeArguments);
                    }
                    else if (extractIrreducible(typeSet, 65536 /* Null */)) {
                        result = getUnionType([getIntersectionType(typeSet), nullType], 1 /* Literal */, aliasSymbol, aliasTypeArguments);
                    }
                    else {
                        // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of
                        // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain.
                        // If the estimated size of the resulting union type exceeds 100000 constituents, report an error.
                        var size = ts.reduceLeft(typeSet, function (n, t) { return n * (t.flags & 1048576 /* Union */ ? t.types.length : 1); }, 1);
                        if (size >= 100000) {
                            error(currentNode, ts.Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
                            return errorType;
                        }
                        var unionIndex_1 = ts.findIndex(typeSet, function (t) { return (t.flags & 1048576 /* Union */) !== 0; });
                        var unionType = typeSet[unionIndex_1];
                        result = getUnionType(ts.map(unionType.types, function (t) { return getIntersectionType(ts.replaceElement(typeSet, unionIndex_1, t)); }), 1 /* Literal */, aliasSymbol, aliasTypeArguments);
                    }
                }
                else {
                    result = createIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
                }
                intersectionTypes.set(id, result);
            }
            return result;
        }
        function getTypeFromIntersectionTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                links.resolvedType = getIntersectionType(ts.map(node.types, getTypeFromTypeNode), aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
            }
            return links.resolvedType;
        }
        function createIndexType(type, stringsOnly) {
            var result = createType(4194304 /* Index */);
            result.type = type;
            result.stringsOnly = stringsOnly;
            return result;
        }
        function getIndexTypeForGenericType(type, stringsOnly) {
            return stringsOnly ?
                type.resolvedStringIndexType || (type.resolvedStringIndexType = createIndexType(type, /*stringsOnly*/ true)) :
                type.resolvedIndexType || (type.resolvedIndexType = createIndexType(type, /*stringsOnly*/ false));
        }
        function getLiteralTypeFromPropertyName(name) {
            if (ts.isPrivateIdentifier(name)) {
                return neverType;
            }
            return ts.isIdentifier(name) ? getLiteralType(ts.unescapeLeadingUnderscores(name.escapedText)) :
                getRegularTypeOfLiteralType(ts.isComputedPropertyName(name) ? checkComputedPropertyName(name) : checkExpression(name));
        }
        function getBigIntLiteralType(node) {
            return getLiteralType({
                negative: false,
                base10Value: ts.parsePseudoBigInt(node.text)
            });
        }
        function getLiteralTypeFromProperty(prop, include) {
            if (!(ts.getDeclarationModifierFlagsFromSymbol(prop) & 24 /* NonPublicAccessibilityModifier */)) {
                var type = getSymbolLinks(getLateBoundSymbol(prop)).nameType;
                if (!type && !ts.isKnownSymbol(prop)) {
                    if (prop.escapedName === "default" /* Default */) {
                        type = getLiteralType("default");
                    }
                    else {
                        var name = prop.valueDeclaration && ts.getNameOfDeclaration(prop.valueDeclaration);
                        type = name && getLiteralTypeFromPropertyName(name) || getLiteralType(ts.symbolName(prop));
                    }
                }
                if (type && type.flags & include) {
                    return type;
                }
            }
            return neverType;
        }
        function getLiteralTypeFromProperties(type, include) {
            return getUnionType(ts.map(getPropertiesOfType(type), function (p) { return getLiteralTypeFromProperty(p, include); }));
        }
        function getNonEnumNumberIndexInfo(type) {
            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
            return numberIndexInfo !== enumNumberIndexInfo ? numberIndexInfo : undefined;
        }
        function getIndexType(type, stringsOnly, noIndexSignatures) {
            if (stringsOnly === void 0) { stringsOnly = keyofStringsOnly; }
            type = getReducedType(type);
            return type.flags & 1048576 /* Union */ ? getIntersectionType(ts.map(type.types, function (t) { return getIndexType(t, stringsOnly, noIndexSignatures); })) :
                type.flags & 2097152 /* Intersection */ ? getUnionType(ts.map(type.types, function (t) { return getIndexType(t, stringsOnly, noIndexSignatures); })) :
                    maybeTypeOfKind(type, 58982400 /* InstantiableNonPrimitive */) ? getIndexTypeForGenericType(type, stringsOnly) :
                        ts.getObjectFlags(type) & 32 /* Mapped */ ? filterType(getConstraintTypeFromMappedType(type), function (t) { return !(noIndexSignatures && t.flags & (1 /* Any */ | 4 /* String */)); }) :
                            type === wildcardType ? wildcardType :
                                type.flags & 2 /* Unknown */ ? neverType :
                                    type.flags & (1 /* Any */ | 131072 /* Never */) ? keyofConstraintType :
                                        stringsOnly ? !noIndexSignatures && getIndexInfoOfType(type, 0 /* String */) ? stringType : getLiteralTypeFromProperties(type, 128 /* StringLiteral */) :
                                            !noIndexSignatures && getIndexInfoOfType(type, 0 /* String */) ? getUnionType([stringType, numberType, getLiteralTypeFromProperties(type, 8192 /* UniqueESSymbol */)]) :
                                                getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromProperties(type, 128 /* StringLiteral */ | 8192 /* UniqueESSymbol */)]) :
                                                    getLiteralTypeFromProperties(type, 8576 /* StringOrNumberLiteralOrUnique */);
        }
        function getExtractStringType(type) {
            if (keyofStringsOnly) {
                return type;
            }
            var extractTypeAlias = getGlobalExtractSymbol();
            return extractTypeAlias ? getTypeAliasInstantiation(extractTypeAlias, [type, stringType]) : stringType;
        }
        function getIndexTypeOrString(type) {
            var indexType = getExtractStringType(getIndexType(type));
            return indexType.flags & 131072 /* Never */ ? stringType : indexType;
        }
        function getTypeFromTypeOperatorNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                switch (node.operator) {
                    case 134 /* KeyOfKeyword */:
                        links.resolvedType = getIndexType(getTypeFromTypeNode(node.type));
                        break;
                    case 147 /* UniqueKeyword */:
                        links.resolvedType = node.type.kind === 144 /* SymbolKeyword */
                            ? getESSymbolLikeTypeForNode(ts.walkUpParenthesizedTypes(node.parent))
                            : errorType;
                        break;
                    case 138 /* ReadonlyKeyword */:
                        links.resolvedType = getTypeFromTypeNode(node.type);
                        break;
                    default:
                        throw ts.Debug.assertNever(node.operator);
                }
            }
            return links.resolvedType;
        }
        function createIndexedAccessType(objectType, indexType, aliasSymbol, aliasTypeArguments) {
            var type = createType(8388608 /* IndexedAccess */);
            type.objectType = objectType;
            type.indexType = indexType;
            type.aliasSymbol = aliasSymbol;
            type.aliasTypeArguments = aliasTypeArguments;
            return type;
        }
        /**
         * Returns if a type is or consists of a JSLiteral object type
         * In addition to objects which are directly literals,
         * * unions where every element is a jsliteral
         * * intersections where at least one element is a jsliteral
         * * and instantiable types constrained to a jsliteral
         * Should all count as literals and not print errors on access or assignment of possibly existing properties.
         * This mirrors the behavior of the index signature propagation, to which this behaves similarly (but doesn't affect assignability or inference).
         */
        function isJSLiteralType(type) {
            if (noImplicitAny) {
                return false; // Flag is meaningless under `noImplicitAny` mode
            }
            if (ts.getObjectFlags(type) & 16384 /* JSLiteral */) {
                return true;
            }
            if (type.flags & 1048576 /* Union */) {
                return ts.every(type.types, isJSLiteralType);
            }
            if (type.flags & 2097152 /* Intersection */) {
                return ts.some(type.types, isJSLiteralType);
            }
            if (type.flags & 63176704 /* Instantiable */) {
                return isJSLiteralType(getResolvedBaseConstraint(type));
            }
            return false;
        }
        function getPropertyNameFromIndex(indexType, accessNode) {
            var accessExpression = accessNode && accessNode.kind === 195 /* ElementAccessExpression */ ? accessNode : undefined;
            return isTypeUsableAsPropertyName(indexType) ?
                getPropertyNameFromType(indexType) :
                accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ?
                    ts.getPropertyNameForKnownSymbolName(ts.idText(accessExpression.argumentExpression.name)) :
                    accessNode && ts.isPropertyName(accessNode) ?
                        // late bound names are handled in the first branch, so here we only need to handle normal names
                        ts.getPropertyNameForPropertyNameNode(accessNode) :
                        undefined;
        }
        function getPropertyTypeForIndexType(originalObjectType, objectType, indexType, fullIndexType, suppressNoImplicitAnyError, accessNode, accessFlags) {
            var accessExpression = accessNode && accessNode.kind === 195 /* ElementAccessExpression */ ? accessNode : undefined;
            var propName = accessNode && ts.isPrivateIdentifier(accessNode) ? undefined : getPropertyNameFromIndex(indexType, accessNode);
            if (propName !== undefined) {
                var prop = getPropertyOfType(objectType, propName);
                if (prop) {
                    if (accessExpression) {
                        markPropertyAsReferenced(prop, accessExpression, /*isThisAccess*/ accessExpression.expression.kind === 104 /* ThisKeyword */);
                        if (isAssignmentToReadonlyEntity(accessExpression, prop, ts.getAssignmentTargetKind(accessExpression))) {
                            error(accessExpression.argumentExpression, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(prop));
                            return undefined;
                        }
                        if (accessFlags & 4 /* CacheSymbol */) {
                            getNodeLinks(accessNode).resolvedSymbol = prop;
                        }
                    }
                    var propType = getTypeOfSymbol(prop);
                    return accessExpression && ts.getAssignmentTargetKind(accessExpression) !== 1 /* Definite */ ?
                        getFlowTypeOfReference(accessExpression, propType) :
                        propType;
                }
                if (everyType(objectType, isTupleType) && isNumericLiteralName(propName) && +propName >= 0) {
                    if (accessNode && everyType(objectType, function (t) { return !t.target.hasRestElement; }) && !(accessFlags & 8 /* NoTupleBoundsCheck */)) {
                        var indexNode = getIndexNodeForAccessExpression(accessNode);
                        if (isTupleType(objectType)) {
                            error(indexNode, ts.Diagnostics.Tuple_type_0_of_length_1_has_no_element_at_index_2, typeToString(objectType), getTypeReferenceArity(objectType), ts.unescapeLeadingUnderscores(propName));
                        }
                        else {
                            error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(propName), typeToString(objectType));
                        }
                    }
                    errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, 1 /* Number */));
                    return mapType(objectType, function (t) { return getRestTypeOfTupleType(t) || undefinedType; });
                }
            }
            if (!(indexType.flags & 98304 /* Nullable */) && isTypeAssignableToKind(indexType, 132 /* StringLike */ | 296 /* NumberLike */ | 12288 /* ESSymbolLike */)) {
                if (objectType.flags & (1 /* Any */ | 131072 /* Never */)) {
                    return objectType;
                }
                var stringIndexInfo = getIndexInfoOfType(objectType, 0 /* String */);
                var indexInfo = isTypeAssignableToKind(indexType, 296 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) || stringIndexInfo;
                if (indexInfo) {
                    if (accessFlags & 1 /* NoIndexSignatures */ && indexInfo === stringIndexInfo) {
                        if (accessExpression) {
                            error(accessExpression, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(originalObjectType));
                        }
                        return undefined;
                    }
                    if (accessNode && !isTypeAssignableToKind(indexType, 4 /* String */ | 8 /* Number */)) {
                        var indexNode = getIndexNodeForAccessExpression(accessNode);
                        error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
                        return indexInfo.type;
                    }
                    errorIfWritingToReadonlyIndex(indexInfo);
                    return indexInfo.type;
                }
                if (indexType.flags & 131072 /* Never */) {
                    return neverType;
                }
                if (isJSLiteralType(objectType)) {
                    return anyType;
                }
                if (accessExpression && !isConstEnumObjectType(objectType)) {
                    if (objectType.symbol === globalThisSymbol && propName !== undefined && globalThisSymbol.exports.has(propName) && (globalThisSymbol.exports.get(propName).flags & 418 /* BlockScoped */)) {
                        error(accessExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(propName), typeToString(objectType));
                    }
                    else if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors && !suppressNoImplicitAnyError) {
                        if (propName !== undefined && typeHasStaticProperty(propName, objectType)) {
                            error(accessExpression, ts.Diagnostics.Property_0_is_a_static_member_of_type_1, propName, typeToString(objectType));
                        }
                        else if (getIndexTypeOfType(objectType, 1 /* Number */)) {
                            error(accessExpression.argumentExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number);
                        }
                        else {
                            var suggestion = void 0;
                            if (propName !== undefined && (suggestion = getSuggestionForNonexistentProperty(propName, objectType))) {
                                if (suggestion !== undefined) {
                                    error(accessExpression.argumentExpression, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, propName, typeToString(objectType), suggestion);
                                }
                            }
                            else {
                                var suggestion_1 = getSuggestionForNonexistentIndexSignature(objectType, accessExpression, indexType);
                                if (suggestion_1 !== undefined) {
                                    error(accessExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_Did_you_mean_to_call_1, typeToString(objectType), suggestion_1);
                                }
                                else {
                                    var errorInfo = void 0;
                                    if (indexType.flags & 1024 /* EnumLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "[" + typeToString(indexType) + "]", typeToString(objectType));
                                    }
                                    else if (indexType.flags & 8192 /* UniqueESSymbol */) {
                                        var symbolName_2 = getFullyQualifiedName(indexType.symbol, accessExpression);
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "[" + symbolName_2 + "]", typeToString(objectType));
                                    }
                                    else if (indexType.flags & 128 /* StringLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, indexType.value, typeToString(objectType));
                                    }
                                    else if (indexType.flags & 256 /* NumberLiteral */) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.Property_0_does_not_exist_on_type_1, indexType.value, typeToString(objectType));
                                    }
                                    else if (indexType.flags & (8 /* Number */ | 4 /* String */)) {
                                        errorInfo = ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics.No_index_signature_with_a_parameter_of_type_0_was_found_on_type_1, typeToString(indexType), typeToString(objectType));
                                    }
                                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Element_implicitly_has_an_any_type_because_expression_of_type_0_can_t_be_used_to_index_type_1, typeToString(fullIndexType), typeToString(objectType));
                                    diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(accessExpression, errorInfo));
                                }
                            }
                        }
                    }
                    return undefined;
                }
            }
            if (isJSLiteralType(objectType)) {
                return anyType;
            }
            if (accessNode) {
                var indexNode = getIndexNodeForAccessExpression(accessNode);
                if (indexType.flags & (128 /* StringLiteral */ | 256 /* NumberLiteral */)) {
                    error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "" + indexType.value, typeToString(objectType));
                }
                else if (indexType.flags & (4 /* String */ | 8 /* Number */)) {
                    error(indexNode, ts.Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType));
                }
                else {
                    error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
                }
            }
            if (isTypeAny(indexType)) {
                return indexType;
            }
            return undefined;
            function errorIfWritingToReadonlyIndex(indexInfo) {
                if (indexInfo && indexInfo.isReadonly && accessExpression && (ts.isAssignmentTarget(accessExpression) || ts.isDeleteTarget(accessExpression))) {
                    error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
                }
            }
        }
        function getIndexNodeForAccessExpression(accessNode) {
            return accessNode.kind === 195 /* ElementAccessExpression */ ? accessNode.argumentExpression :
                accessNode.kind === 185 /* IndexedAccessType */ ? accessNode.indexType :
                    accessNode.kind === 154 /* ComputedPropertyName */ ? accessNode.expression :
                        accessNode;
        }
        function isGenericObjectType(type) {
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                if (!(type.objectFlags & 4194304 /* IsGenericObjectTypeComputed */)) {
                    type.objectFlags |= 4194304 /* IsGenericObjectTypeComputed */ |
                        (ts.some(type.types, isGenericObjectType) ? 8388608 /* IsGenericObjectType */ : 0);
                }
                return !!(type.objectFlags & 8388608 /* IsGenericObjectType */);
            }
            return !!(type.flags & 58982400 /* InstantiableNonPrimitive */) || isGenericMappedType(type);
        }
        function isGenericIndexType(type) {
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                if (!(type.objectFlags & 16777216 /* IsGenericIndexTypeComputed */)) {
                    type.objectFlags |= 16777216 /* IsGenericIndexTypeComputed */ |
                        (ts.some(type.types, isGenericIndexType) ? 33554432 /* IsGenericIndexType */ : 0);
                }
                return !!(type.objectFlags & 33554432 /* IsGenericIndexType */);
            }
            return !!(type.flags & (58982400 /* InstantiableNonPrimitive */ | 4194304 /* Index */));
        }
        function isThisTypeParameter(type) {
            return !!(type.flags & 262144 /* TypeParameter */ && type.isThisType);
        }
        function getSimplifiedType(type, writing) {
            return type.flags & 8388608 /* IndexedAccess */ ? getSimplifiedIndexedAccessType(type, writing) :
                type.flags & 16777216 /* Conditional */ ? getSimplifiedConditionalType(type, writing) :
                    type;
        }
        function distributeIndexOverObjectType(objectType, indexType, writing) {
            // (T | U)[K] -> T[K] | U[K] (reading)
            // (T | U)[K] -> T[K] & U[K] (writing)
            // (T & U)[K] -> T[K] & U[K]
            if (objectType.flags & 3145728 /* UnionOrIntersection */) {
                var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); });
                return objectType.flags & 2097152 /* Intersection */ || writing ? getIntersectionType(types) : getUnionType(types);
            }
        }
        function distributeObjectOverIndexType(objectType, indexType, writing) {
            // T[A | B] -> T[A] | T[B] (reading)
            // T[A | B] -> T[A] & T[B] (writing)
            if (indexType.flags & 1048576 /* Union */) {
                var types = ts.map(indexType.types, function (t) { return getSimplifiedType(getIndexedAccessType(objectType, t), writing); });
                return writing ? getIntersectionType(types) : getUnionType(types);
            }
        }
        function unwrapSubstitution(type) {
            if (type.flags & 33554432 /* Substitution */) {
                return type.substitute;
            }
            return type;
        }
        // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return
        // the type itself if no transformation is possible. The writing flag indicates that the type is
        // the target of an assignment.
        function getSimplifiedIndexedAccessType(type, writing) {
            var cache = writing ? "simplifiedForWriting" : "simplifiedForReading";
            if (type[cache]) {
                return type[cache] === circularConstraintType ? type : type[cache];
            }
            type[cache] = circularConstraintType;
            // We recursively simplify the object type as it may in turn be an indexed access type. For example, with
            // '{ [P in T]: { [Q in U]: number } }[T][U]' we want to first simplify the inner indexed access type.
            var objectType = unwrapSubstitution(getSimplifiedType(type.objectType, writing));
            var indexType = getSimplifiedType(type.indexType, writing);
            // T[A | B] -> T[A] | T[B] (reading)
            // T[A | B] -> T[A] & T[B] (writing)
            var distributedOverIndex = distributeObjectOverIndexType(objectType, indexType, writing);
            if (distributedOverIndex) {
                return type[cache] = distributedOverIndex;
            }
            // Only do the inner distributions if the index can no longer be instantiated to cause index distribution again
            if (!(indexType.flags & 63176704 /* Instantiable */)) {
                // (T | U)[K] -> T[K] | U[K] (reading)
                // (T | U)[K] -> T[K] & U[K] (writing)
                // (T & U)[K] -> T[K] & U[K]
                var distributedOverObject = distributeIndexOverObjectType(objectType, indexType, writing);
                if (distributedOverObject) {
                    return type[cache] = distributedOverObject;
                }
            }
            // So ultimately (reading):
            // ((A & B) | C)[K1 | K2] -> ((A & B) | C)[K1] | ((A & B) | C)[K2] -> (A & B)[K1] | C[K1] | (A & B)[K2] | C[K2] -> (A[K1] & B[K1]) | C[K1] | (A[K2] & B[K2]) | C[K2]
            // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper
            // that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
            // construct the type Box<T[X]>.
            if (isGenericMappedType(objectType)) {
                return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), function (t) { return getSimplifiedType(t, writing); });
            }
            return type[cache] = type;
        }
        function getSimplifiedConditionalType(type, writing) {
            var checkType = type.checkType;
            var extendsType = type.extendsType;
            var trueType = getTrueTypeFromConditionalType(type);
            var falseType = getFalseTypeFromConditionalType(type);
            // Simplifications for types of the form `T extends U ? T : never` and `T extends U ? never : T`.
            if (falseType.flags & 131072 /* Never */ && getActualTypeVariable(trueType) === getActualTypeVariable(checkType)) {
                if (checkType.flags & 1 /* Any */ || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
                    return getSimplifiedType(trueType, writing);
                }
                else if (isIntersectionEmpty(checkType, extendsType)) { // Always false
                    return neverType;
                }
            }
            else if (trueType.flags & 131072 /* Never */ && getActualTypeVariable(falseType) === getActualTypeVariable(checkType)) {
                if (!(checkType.flags & 1 /* Any */) && isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
                    return neverType;
                }
                else if (checkType.flags & 1 /* Any */ || isIntersectionEmpty(checkType, extendsType)) { // Always false
                    return getSimplifiedType(falseType, writing);
                }
            }
            return type;
        }
        /**
         * Invokes union simplification logic to determine if an intersection is considered empty as a union constituent
         */
        function isIntersectionEmpty(type1, type2) {
            return !!(getUnionType([intersectTypes(type1, type2), neverType]).flags & 131072 /* Never */);
        }
        function substituteIndexedMappedType(objectType, index) {
            var mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [index]);
            var templateMapper = combineTypeMappers(objectType.mapper, mapper);
            return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
        }
        function getIndexedAccessType(objectType, indexType, accessNode, aliasSymbol, aliasTypeArguments) {
            return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, 0 /* None */, aliasSymbol, aliasTypeArguments) || (accessNode ? errorType : unknownType);
        }
        function getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, accessFlags, aliasSymbol, aliasTypeArguments) {
            if (accessFlags === void 0) { accessFlags = 0 /* None */; }
            if (objectType === wildcardType || indexType === wildcardType) {
                return wildcardType;
            }
            // If the object type has a string index signature and no other members we know that the result will
            // always be the type of that index signature and we can simplify accordingly.
            if (isStringIndexSignatureOnlyType(objectType) && !(indexType.flags & 98304 /* Nullable */) && isTypeAssignableToKind(indexType, 4 /* String */ | 8 /* Number */)) {
                indexType = stringType;
            }
            // If the index type is generic, or if the object type is generic and doesn't originate in an expression,
            // we are performing a higher-order index access where we cannot meaningfully access the properties of the
            // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in
            // an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]'
            // has always been resolved eagerly using the constraint type of 'this' at the given location.
            if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind !== 185 /* IndexedAccessType */) && isGenericObjectType(objectType)) {
                if (objectType.flags & 3 /* AnyOrUnknown */) {
                    return objectType;
                }
                // Defer the operation by creating an indexed access type.
                var id = objectType.id + "," + indexType.id;
                var type = indexedAccessTypes.get(id);
                if (!type) {
                    indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType, aliasSymbol, aliasTypeArguments));
                }
                return type;
            }
            // In the following we resolve T[K] to the type of the property in T selected by K.
            // We treat boolean as different from other unions to improve errors;
            // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'.
            var apparentObjectType = getReducedApparentType(objectType);
            if (indexType.flags & 1048576 /* Union */ && !(indexType.flags & 16 /* Boolean */)) {
                var propTypes = [];
                var wasMissingProp = false;
                for (var _i = 0, _a = indexType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    var propType = getPropertyTypeForIndexType(objectType, apparentObjectType, t, indexType, wasMissingProp, accessNode, accessFlags);
                    if (propType) {
                        propTypes.push(propType);
                    }
                    else if (!accessNode) {
                        // If there's no error node, we can immeditely stop, since error reporting is off
                        return undefined;
                    }
                    else {
                        // Otherwise we set a flag and return at the end of the loop so we still mark all errors
                        wasMissingProp = true;
                    }
                }
                if (wasMissingProp) {
                    return undefined;
                }
                return accessFlags & 2 /* Writing */ ? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments) : getUnionType(propTypes, 1 /* Literal */, aliasSymbol, aliasTypeArguments);
            }
            return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | 4 /* CacheSymbol */);
        }
        function getTypeFromIndexedAccessTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var objectType = getTypeFromTypeNode(node.objectType);
                var indexType = getTypeFromTypeNode(node.indexType);
                var potentialAlias = getAliasSymbolForTypeNode(node);
                var resolved = getIndexedAccessType(objectType, indexType, node, potentialAlias, getTypeArgumentsForAliasSymbol(potentialAlias));
                links.resolvedType = resolved.flags & 8388608 /* IndexedAccess */ &&
                    resolved.objectType === objectType &&
                    resolved.indexType === indexType ?
                    getConditionalFlowTypeOfType(resolved, node) : resolved;
            }
            return links.resolvedType;
        }
        function getTypeFromMappedTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var type = createObjectType(32 /* Mapped */, node.symbol);
                type.declaration = node;
                type.aliasSymbol = getAliasSymbolForTypeNode(node);
                type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(type.aliasSymbol);
                links.resolvedType = type;
                // Eagerly resolve the constraint type which forces an error if the constraint type circularly
                // references itself through one or more type aliases.
                getConstraintTypeFromMappedType(type);
            }
            return links.resolvedType;
        }
        function getActualTypeVariable(type) {
            if (type.flags & 33554432 /* Substitution */) {
                return type.baseType;
            }
            if (type.flags & 8388608 /* IndexedAccess */ && (type.objectType.flags & 33554432 /* Substitution */ ||
                type.indexType.flags & 33554432 /* Substitution */)) {
                return getIndexedAccessType(getActualTypeVariable(type.objectType), getActualTypeVariable(type.indexType));
            }
            return type;
        }
        function getConditionalType(root, mapper) {
            var result;
            var extraTypes;
            var _loop_12 = function () {
                var checkType = instantiateType(root.checkType, mapper);
                var checkTypeInstantiable = isGenericObjectType(checkType) || isGenericIndexType(checkType);
                var extendsType = instantiateType(root.extendsType, mapper);
                if (checkType === wildcardType || extendsType === wildcardType) {
                    return { value: wildcardType };
                }
                var combinedMapper = void 0;
                if (root.inferTypeParameters) {
                    var context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, 0 /* None */);
                    // We skip inference of the possible `infer` types unles the `extendsType` _is_ an infer type
                    // if it was, it's trivial to say that extendsType = checkType, however such a pattern is used to
                    // "reset" the type being build up during constraint calculation and avoid making an apparently "infinite" constraint
                    // so in those cases we refain from performing inference and retain the uninfered type parameter
                    if (!checkTypeInstantiable || !ts.some(root.inferTypeParameters, function (t) { return t === extendsType; })) {
                        // We don't want inferences from constraints as they may cause us to eagerly resolve the
                        // conditional type instead of deferring resolution. Also, we always want strict function
                        // types rules (i.e. proper contravariance) for inferences.
                        inferTypes(context.inferences, checkType, extendsType, 128 /* NoConstraints */ | 256 /* AlwaysStrict */);
                    }
                    combinedMapper = mergeTypeMappers(mapper, context.mapper);
                }
                // Instantiate the extends type including inferences for 'infer T' type parameters
                var inferredExtendsType = combinedMapper ? instantiateType(root.extendsType, combinedMapper) : extendsType;
                // We attempt to resolve the conditional type only when the check and extends types are non-generic
                if (!checkTypeInstantiable && !isGenericObjectType(inferredExtendsType) && !isGenericIndexType(inferredExtendsType)) {
                    // Return falseType for a definitely false extends check. We check an instantiations of the two
                    // types with type parameters mapped to the wildcard type, the most permissive instantiations
                    // possible (the wildcard type is assignable to and from all types). If those are not related,
                    // then no instantiations will be and we can just return the false branch type.
                    if (!(inferredExtendsType.flags & 3 /* AnyOrUnknown */) && (checkType.flags & 1 /* Any */ || !isTypeAssignableTo(getPermissiveInstantiation(checkType), getPermissiveInstantiation(inferredExtendsType)))) {
                        // Return union of trueType and falseType for 'any' since it matches anything
                        if (checkType.flags & 1 /* Any */) {
                            (extraTypes || (extraTypes = [])).push(instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper));
                        }
                        // If falseType is an immediately nested conditional type that isn't distributive or has an
                        // identical checkType, switch to that type and loop.
                        var falseType_1 = root.falseType;
                        if (falseType_1.flags & 16777216 /* Conditional */) {
                            var newRoot = falseType_1.root;
                            if (newRoot.node.parent === root.node && (!newRoot.isDistributive || newRoot.checkType === root.checkType)) {
                                root = newRoot;
                                return "continue";
                            }
                        }
                        result = instantiateTypeWithoutDepthIncrease(falseType_1, mapper);
                        return "break";
                    }
                    // Return trueType for a definitely true extends check. We check instantiations of the two
                    // types with type parameters mapped to their restrictive form, i.e. a form of the type parameter
                    // that has no constraint. This ensures that, for example, the type
                    //   type Foo<T extends { x: any }> = T extends { x: string } ? string : number
                    // doesn't immediately resolve to 'string' instead of being deferred.
                    if (inferredExtendsType.flags & 3 /* AnyOrUnknown */ || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(inferredExtendsType))) {
                        result = instantiateTypeWithoutDepthIncrease(root.trueType, combinedMapper || mapper);
                        return "break";
                    }
                }
                // Return a deferred type for a check that is neither definitely true nor definitely false
                var erasedCheckType = getActualTypeVariable(checkType);
                result = createType(16777216 /* Conditional */);
                result.root = root;
                result.checkType = erasedCheckType;
                result.extendsType = extendsType;
                result.mapper = mapper;
                result.combinedMapper = combinedMapper;
                result.aliasSymbol = root.aliasSymbol;
                result.aliasTypeArguments = instantiateTypes(root.aliasTypeArguments, mapper); // TODO: GH#18217
                return "break";
            };
            // We loop here for an immediately nested conditional type in the false position, effectively treating
            // types of the form 'A extends B ? X : C extends D ? Y : E extends F ? Z : ...' as a single construct for
            // purposes of resolution. This means such types aren't subject to the instatiation depth limiter.
            while (true) {
                var state_4 = _loop_12();
                if (typeof state_4 === "object")
                    return state_4.value;
                if (state_4 === "break")
                    break;
            }
            return extraTypes ? getUnionType(ts.append(extraTypes, result)) : result;
        }
        function getTrueTypeFromConditionalType(type) {
            return type.resolvedTrueType || (type.resolvedTrueType = instantiateType(type.root.trueType, type.mapper));
        }
        function getFalseTypeFromConditionalType(type) {
            return type.resolvedFalseType || (type.resolvedFalseType = instantiateType(type.root.falseType, type.mapper));
        }
        function getInferredTrueTypeFromConditionalType(type) {
            return type.resolvedInferredTrueType || (type.resolvedInferredTrueType = type.combinedMapper ? instantiateType(type.root.trueType, type.combinedMapper) : getTrueTypeFromConditionalType(type));
        }
        function getInferTypeParameters(node) {
            var result;
            if (node.locals) {
                node.locals.forEach(function (symbol) {
                    if (symbol.flags & 262144 /* TypeParameter */) {
                        result = ts.append(result, getDeclaredTypeOfSymbol(symbol));
                    }
                });
            }
            return result;
        }
        function getTypeFromConditionalTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                var checkType = getTypeFromTypeNode(node.checkType);
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                var aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
                var allOuterTypeParameters = getOuterTypeParameters(node, /*includeThisTypes*/ true);
                var outerTypeParameters = aliasTypeArguments ? allOuterTypeParameters : ts.filter(allOuterTypeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, node); });
                var root = {
                    node: node,
                    checkType: checkType,
                    extendsType: getTypeFromTypeNode(node.extendsType),
                    trueType: getTypeFromTypeNode(node.trueType),
                    falseType: getTypeFromTypeNode(node.falseType),
                    isDistributive: !!(checkType.flags & 262144 /* TypeParameter */),
                    inferTypeParameters: getInferTypeParameters(node),
                    outerTypeParameters: outerTypeParameters,
                    instantiations: undefined,
                    aliasSymbol: aliasSymbol,
                    aliasTypeArguments: aliasTypeArguments
                };
                links.resolvedType = getConditionalType(root, /*mapper*/ undefined);
                if (outerTypeParameters) {
                    root.instantiations = ts.createMap();
                    root.instantiations.set(getTypeListId(outerTypeParameters), links.resolvedType);
                }
            }
            return links.resolvedType;
        }
        function getTypeFromInferTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter));
            }
            return links.resolvedType;
        }
        function getIdentifierChain(node) {
            if (ts.isIdentifier(node)) {
                return [node];
            }
            else {
                return ts.append(getIdentifierChain(node.left), node.right);
            }
        }
        function getTypeFromImportTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                if (node.isTypeOf && node.typeArguments) { // Only the non-typeof form can make use of type arguments
                    error(node, ts.Diagnostics.Type_arguments_cannot_be_used_here);
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                if (!ts.isLiteralImportTypeNode(node)) {
                    error(node.argument, ts.Diagnostics.String_literal_expected);
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                var targetMeaning = node.isTypeOf ? 111551 /* Value */ : node.flags & 4194304 /* JSDoc */ ? 111551 /* Value */ | 788968 /* Type */ : 788968 /* Type */;
                // TODO: Future work: support unions/generics/whatever via a deferred import-type
                var innerModuleSymbol = resolveExternalModuleName(node, node.argument.literal);
                if (!innerModuleSymbol) {
                    links.resolvedSymbol = unknownSymbol;
                    return links.resolvedType = errorType;
                }
                var moduleSymbol = resolveExternalModuleSymbol(innerModuleSymbol, /*dontResolveAlias*/ false);
                if (!ts.nodeIsMissing(node.qualifier)) {
                    var nameStack = getIdentifierChain(node.qualifier);
                    var currentNamespace = moduleSymbol;
                    var current = void 0;
                    while (current = nameStack.shift()) {
                        var meaning = nameStack.length ? 1920 /* Namespace */ : targetMeaning;
                        var next = getSymbol(getExportsOfSymbol(getMergedSymbol(resolveSymbol(currentNamespace))), current.escapedText, meaning);
                        if (!next) {
                            error(current, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(currentNamespace), ts.declarationNameToString(current));
                            return links.resolvedType = errorType;
                        }
                        getNodeLinks(current).resolvedSymbol = next;
                        getNodeLinks(current.parent).resolvedSymbol = next;
                        currentNamespace = next;
                    }
                    links.resolvedType = resolveImportSymbolType(node, links, currentNamespace, targetMeaning);
                }
                else {
                    if (moduleSymbol.flags & targetMeaning) {
                        links.resolvedType = resolveImportSymbolType(node, links, moduleSymbol, targetMeaning);
                    }
                    else {
                        var errorMessage = targetMeaning === 111551 /* Value */
                            ? ts.Diagnostics.Module_0_does_not_refer_to_a_value_but_is_used_as_a_value_here
                            : ts.Diagnostics.Module_0_does_not_refer_to_a_type_but_is_used_as_a_type_here_Did_you_mean_typeof_import_0;
                        error(node, errorMessage, node.argument.literal.text);
                        links.resolvedSymbol = unknownSymbol;
                        links.resolvedType = errorType;
                    }
                }
            }
            return links.resolvedType;
        }
        function resolveImportSymbolType(node, links, symbol, meaning) {
            var resolvedSymbol = resolveSymbol(symbol);
            links.resolvedSymbol = resolvedSymbol;
            if (meaning === 111551 /* Value */) {
                return getTypeOfSymbol(symbol); // intentionally doesn't use resolved symbol so type is cached as expected on the alias
            }
            else {
                return getTypeReferenceType(node, resolvedSymbol); // getTypeReferenceType doesn't handle aliases - it must get the resolved symbol
            }
        }
        function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                // Deferred resolution of members is handled by resolveObjectTypeMembers
                var aliasSymbol = getAliasSymbolForTypeNode(node);
                if (getMembersOfSymbol(node.symbol).size === 0 && !aliasSymbol) {
                    links.resolvedType = emptyTypeLiteralType;
                }
                else {
                    var type = createObjectType(16 /* Anonymous */, node.symbol);
                    type.aliasSymbol = aliasSymbol;
                    type.aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
                    if (ts.isJSDocTypeLiteral(node) && node.isArrayType) {
                        type = createArrayType(type);
                    }
                    links.resolvedType = type;
                }
            }
            return links.resolvedType;
        }
        function getAliasSymbolForTypeNode(node) {
            var host = node.parent;
            while (ts.isParenthesizedTypeNode(host) || ts.isTypeOperatorNode(host) && host.operator === 138 /* ReadonlyKeyword */) {
                host = host.parent;
            }
            return ts.isTypeAlias(host) ? getSymbolOfNode(host) : undefined;
        }
        function getTypeArgumentsForAliasSymbol(symbol) {
            return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined;
        }
        function isNonGenericObjectType(type) {
            return !!(type.flags & 524288 /* Object */) && !isGenericMappedType(type);
        }
        function isEmptyObjectTypeOrSpreadsIntoEmptyObject(type) {
            return isEmptyObjectType(type) || !!(type.flags & (65536 /* Null */ | 32768 /* Undefined */ | 528 /* BooleanLike */ | 296 /* NumberLike */ | 2112 /* BigIntLike */ | 132 /* StringLike */ | 1056 /* EnumLike */ | 67108864 /* NonPrimitive */ | 4194304 /* Index */));
        }
        function isSinglePropertyAnonymousObjectType(type) {
            return !!(type.flags & 524288 /* Object */) &&
                !!(ts.getObjectFlags(type) & 16 /* Anonymous */) &&
                (ts.length(getPropertiesOfType(type)) === 1 || ts.every(getPropertiesOfType(type), function (p) { return !!(p.flags & 16777216 /* Optional */); }));
        }
        function tryMergeUnionOfObjectTypeAndEmptyObject(type, readonly) {
            if (type.types.length === 2) {
                var firstType = type.types[0];
                var secondType = type.types[1];
                if (ts.every(type.types, isEmptyObjectTypeOrSpreadsIntoEmptyObject)) {
                    return isEmptyObjectType(firstType) ? firstType : isEmptyObjectType(secondType) ? secondType : emptyObjectType;
                }
                if (isEmptyObjectTypeOrSpreadsIntoEmptyObject(firstType) && isSinglePropertyAnonymousObjectType(secondType)) {
                    return getAnonymousPartialType(secondType);
                }
                if (isEmptyObjectTypeOrSpreadsIntoEmptyObject(secondType) && isSinglePropertyAnonymousObjectType(firstType)) {
                    return getAnonymousPartialType(firstType);
                }
            }
            function getAnonymousPartialType(type) {
                // gets the type as if it had been spread, but where everything in the spread is made optional
                var members = ts.createSymbolTable();
                for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    if (ts.getDeclarationModifierFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */)) {
                        // do nothing, skip privates
                    }
                    else if (isSpreadableProperty(prop)) {
                        var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */);
                        var flags = 4 /* Property */ | 16777216 /* Optional */;
                        var result = createSymbol(flags, prop.escapedName, readonly ? 8 /* Readonly */ : 0);
                        result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
                        result.declarations = prop.declarations;
                        result.nameType = getSymbolLinks(prop).nameType;
                        result.syntheticOrigin = prop;
                        members.set(prop.escapedName, result);
                    }
                }
                var spread = createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, getIndexInfoOfType(type, 0 /* String */), getIndexInfoOfType(type, 1 /* Number */));
                spread.objectFlags |= 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
                return spread;
            }
        }
        /**
         * Since the source of spread types are object literals, which are not binary,
         * this function should be called in a left folding style, with left = previous result of getSpreadType
         * and right = the new element to be spread.
         */
        function getSpreadType(left, right, symbol, objectFlags, readonly) {
            if (left.flags & 1 /* Any */ || right.flags & 1 /* Any */) {
                return anyType;
            }
            if (left.flags & 2 /* Unknown */ || right.flags & 2 /* Unknown */) {
                return unknownType;
            }
            if (left.flags & 131072 /* Never */) {
                return right;
            }
            if (right.flags & 131072 /* Never */) {
                return left;
            }
            if (left.flags & 1048576 /* Union */) {
                var merged = tryMergeUnionOfObjectTypeAndEmptyObject(left, readonly);
                if (merged) {
                    return getSpreadType(merged, right, symbol, objectFlags, readonly);
                }
                return mapType(left, function (t) { return getSpreadType(t, right, symbol, objectFlags, readonly); });
            }
            if (right.flags & 1048576 /* Union */) {
                var merged = tryMergeUnionOfObjectTypeAndEmptyObject(right, readonly);
                if (merged) {
                    return getSpreadType(left, merged, symbol, objectFlags, readonly);
                }
                return mapType(right, function (t) { return getSpreadType(left, t, symbol, objectFlags, readonly); });
            }
            if (right.flags & (528 /* BooleanLike */ | 296 /* NumberLike */ | 2112 /* BigIntLike */ | 132 /* StringLike */ | 1056 /* EnumLike */ | 67108864 /* NonPrimitive */ | 4194304 /* Index */)) {
                return left;
            }
            if (isGenericObjectType(left) || isGenericObjectType(right)) {
                if (isEmptyObjectType(left)) {
                    return right;
                }
                // When the left type is an intersection, we may need to merge the last constituent of the
                // intersection with the right type. For example when the left type is 'T & { a: string }'
                // and the right type is '{ b: string }' we produce 'T & { a: string, b: string }'.
                if (left.flags & 2097152 /* Intersection */) {
                    var types = left.types;
                    var lastLeft = types[types.length - 1];
                    if (isNonGenericObjectType(lastLeft) && isNonGenericObjectType(right)) {
                        return getIntersectionType(ts.concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, objectFlags, readonly)]));
                    }
                }
                return getIntersectionType([left, right]);
            }
            var members = ts.createSymbolTable();
            var skippedPrivateMembers = ts.createUnderscoreEscapedMap();
            var stringIndexInfo;
            var numberIndexInfo;
            if (left === emptyObjectType) {
                // for the first spread element, left === emptyObjectType, so take the right's string indexer
                stringIndexInfo = getIndexInfoOfType(right, 0 /* String */);
                numberIndexInfo = getIndexInfoOfType(right, 1 /* Number */);
            }
            else {
                stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 0 /* String */), getIndexInfoOfType(right, 0 /* String */));
                numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 1 /* Number */), getIndexInfoOfType(right, 1 /* Number */));
            }
            for (var _i = 0, _a = getPropertiesOfType(right); _i < _a.length; _i++) {
                var rightProp = _a[_i];
                if (ts.getDeclarationModifierFlagsFromSymbol(rightProp) & (8 /* Private */ | 16 /* Protected */)) {
                    skippedPrivateMembers.set(rightProp.escapedName, true);
                }
                else if (isSpreadableProperty(rightProp)) {
                    members.set(rightProp.escapedName, getSpreadSymbol(rightProp, readonly));
                }
            }
            for (var _b = 0, _c = getPropertiesOfType(left); _b < _c.length; _b++) {
                var leftProp = _c[_b];
                if (skippedPrivateMembers.has(leftProp.escapedName) || !isSpreadableProperty(leftProp)) {
                    continue;
                }
                if (members.has(leftProp.escapedName)) {
                    var rightProp = members.get(leftProp.escapedName);
                    var rightType = getTypeOfSymbol(rightProp);
                    if (rightProp.flags & 16777216 /* Optional */) {
                        var declarations = ts.concatenate(leftProp.declarations, rightProp.declarations);
                        var flags = 4 /* Property */ | (leftProp.flags & 16777216 /* Optional */);
                        var result = createSymbol(flags, leftProp.escapedName);
                        result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, 524288 /* NEUndefined */)]);
                        result.leftSpread = leftProp;
                        result.rightSpread = rightProp;
                        result.declarations = declarations;
                        result.nameType = getSymbolLinks(leftProp).nameType;
                        members.set(leftProp.escapedName, result);
                    }
                }
                else {
                    members.set(leftProp.escapedName, getSpreadSymbol(leftProp, readonly));
                }
            }
            var spread = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, getIndexInfoWithReadonly(stringIndexInfo, readonly), getIndexInfoWithReadonly(numberIndexInfo, readonly));
            spread.objectFlags |= 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */ | 1024 /* ContainsSpread */ | objectFlags;
            return spread;
        }
        /** We approximate own properties as non-methods plus methods that are inside the object literal */
        function isSpreadableProperty(prop) {
            return !ts.some(prop.declarations, ts.isPrivateIdentifierPropertyDeclaration) &&
                (!(prop.flags & (8192 /* Method */ | 32768 /* GetAccessor */ | 65536 /* SetAccessor */)) ||
                    !prop.declarations.some(function (decl) { return ts.isClassLike(decl.parent); }));
        }
        function getSpreadSymbol(prop, readonly) {
            var isSetonlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */);
            if (!isSetonlyAccessor && readonly === isReadonlySymbol(prop)) {
                return prop;
            }
            var flags = 4 /* Property */ | (prop.flags & 16777216 /* Optional */);
            var result = createSymbol(flags, prop.escapedName, readonly ? 8 /* Readonly */ : 0);
            result.type = isSetonlyAccessor ? undefinedType : getTypeOfSymbol(prop);
            result.declarations = prop.declarations;
            result.nameType = getSymbolLinks(prop).nameType;
            result.syntheticOrigin = prop;
            return result;
        }
        function getIndexInfoWithReadonly(info, readonly) {
            return info && info.isReadonly !== readonly ? createIndexInfo(info.type, readonly, info.declaration) : info;
        }
        function createLiteralType(flags, value, symbol) {
            var type = createType(flags);
            type.symbol = symbol;
            type.value = value;
            return type;
        }
        function getFreshTypeOfLiteralType(type) {
            if (type.flags & 2944 /* Literal */) {
                if (!type.freshType) {
                    var freshType = createLiteralType(type.flags, type.value, type.symbol);
                    freshType.regularType = type;
                    freshType.freshType = freshType;
                    type.freshType = freshType;
                }
                return type.freshType;
            }
            return type;
        }
        function getRegularTypeOfLiteralType(type) {
            return type.flags & 2944 /* Literal */ ? type.regularType :
                type.flags & 1048576 /* Union */ ? (type.regularType || (type.regularType = getUnionType(ts.sameMap(type.types, getRegularTypeOfLiteralType)))) :
                    type;
        }
        function isFreshLiteralType(type) {
            return !!(type.flags & 2944 /* Literal */) && type.freshType === type;
        }
        function getLiteralType(value, enumId, symbol) {
            // We store all literal types in a single map with keys of the form '#NNN' and '@SSS',
            // where NNN is the text representation of a numeric literal and SSS are the characters
            // of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where
            // EEE is a unique id for the containing enum type.
            var qualifier = typeof value === "number" ? "#" : typeof value === "string" ? "@" : "n";
            var key = (enumId ? enumId : "") + qualifier + (typeof value === "object" ? ts.pseudoBigIntToString(value) : value);
            var type = literalTypes.get(key);
            if (!type) {
                var flags = (typeof value === "number" ? 256 /* NumberLiteral */ :
                    typeof value === "string" ? 128 /* StringLiteral */ : 2048 /* BigIntLiteral */) |
                    (enumId ? 1024 /* EnumLiteral */ : 0);
                literalTypes.set(key, type = createLiteralType(flags, value, symbol));
                type.regularType = type;
            }
            return type;
        }
        function getTypeFromLiteralTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal));
            }
            return links.resolvedType;
        }
        function createUniqueESSymbolType(symbol) {
            var type = createType(8192 /* UniqueESSymbol */);
            type.symbol = symbol;
            type.escapedName = "__@" + type.symbol.escapedName + "@" + getSymbolId(type.symbol);
            return type;
        }
        function getESSymbolLikeTypeForNode(node) {
            if (ts.isValidESSymbolDeclaration(node)) {
                var symbol = getSymbolOfNode(node);
                var links = getSymbolLinks(symbol);
                return links.uniqueESSymbolType || (links.uniqueESSymbolType = createUniqueESSymbolType(symbol));
            }
            return esSymbolType;
        }
        function getThisType(node) {
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            var parent = container && container.parent;
            if (parent && (ts.isClassLike(parent) || parent.kind === 246 /* InterfaceDeclaration */)) {
                if (!ts.hasModifier(container, 32 /* Static */) &&
                    (!ts.isConstructorDeclaration(container) || ts.isNodeDescendantOf(node, container.body))) {
                    return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType;
                }
            }
            // inside x.prototype = { ... }
            if (parent && ts.isObjectLiteralExpression(parent) && ts.isBinaryExpression(parent.parent) && ts.getAssignmentDeclarationKind(parent.parent) === 6 /* Prototype */) {
                return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent.parent.left).parent).thisType;
            }
            // /** @return {this} */
            // x.prototype.m = function() { ... }
            var host = node.flags & 4194304 /* JSDoc */ ? ts.getHostSignatureFromJSDoc(node) : undefined;
            if (host && ts.isFunctionExpression(host) && ts.isBinaryExpression(host.parent) && ts.getAssignmentDeclarationKind(host.parent) === 3 /* PrototypeProperty */) {
                return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(host.parent.left).parent).thisType;
            }
            // inside constructor function C() { ... }
            if (isJSConstructor(container) && ts.isNodeDescendantOf(node, container.body)) {
                return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(container)).thisType;
            }
            error(node, ts.Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface);
            return errorType;
        }
        function getTypeFromThisTypeNode(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                links.resolvedType = getThisType(node);
            }
            return links.resolvedType;
        }
        function getTypeFromTypeNode(node) {
            return getConditionalFlowTypeOfType(getTypeFromTypeNodeWorker(node), node);
        }
        function getTypeFromTypeNodeWorker(node) {
            switch (node.kind) {
                case 125 /* AnyKeyword */:
                case 295 /* JSDocAllType */:
                case 296 /* JSDocUnknownType */:
                    return anyType;
                case 148 /* UnknownKeyword */:
                    return unknownType;
                case 143 /* StringKeyword */:
                    return stringType;
                case 140 /* NumberKeyword */:
                    return numberType;
                case 151 /* BigIntKeyword */:
                    return bigintType;
                case 128 /* BooleanKeyword */:
                    return booleanType;
                case 144 /* SymbolKeyword */:
                    return esSymbolType;
                case 110 /* VoidKeyword */:
                    return voidType;
                case 146 /* UndefinedKeyword */:
                    return undefinedType;
                case 100 /* NullKeyword */:
                    return nullType;
                case 137 /* NeverKeyword */:
                    return neverType;
                case 141 /* ObjectKeyword */:
                    return node.flags & 131072 /* JavaScriptFile */ && !noImplicitAny ? anyType : nonPrimitiveType;
                case 183 /* ThisType */:
                case 104 /* ThisKeyword */:
                    return getTypeFromThisTypeNode(node);
                case 187 /* LiteralType */:
                    return getTypeFromLiteralTypeNode(node);
                case 169 /* TypeReference */:
                    return getTypeFromTypeReference(node);
                case 168 /* TypePredicate */:
                    return node.assertsModifier ? voidType : booleanType;
                case 216 /* ExpressionWithTypeArguments */:
                    return getTypeFromTypeReference(node);
                case 172 /* TypeQuery */:
                    return getTypeFromTypeQueryNode(node);
                case 174 /* ArrayType */:
                case 175 /* TupleType */:
                    return getTypeFromArrayOrTupleTypeNode(node);
                case 176 /* OptionalType */:
                    return getTypeFromOptionalTypeNode(node);
                case 178 /* UnionType */:
                    return getTypeFromUnionTypeNode(node);
                case 179 /* IntersectionType */:
                    return getTypeFromIntersectionTypeNode(node);
                case 297 /* JSDocNullableType */:
                    return getTypeFromJSDocNullableTypeNode(node);
                case 299 /* JSDocOptionalType */:
                    return addOptionality(getTypeFromTypeNode(node.type));
                case 182 /* ParenthesizedType */:
                case 298 /* JSDocNonNullableType */:
                case 294 /* JSDocTypeExpression */:
                    return getTypeFromTypeNode(node.type);
                case 177 /* RestType */:
                    return getElementTypeOfArrayType(getTypeFromTypeNode(node.type)) || errorType;
                case 301 /* JSDocVariadicType */:
                    return getTypeFromJSDocVariadicType(node);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */:
                case 173 /* TypeLiteral */:
                case 304 /* JSDocTypeLiteral */:
                case 300 /* JSDocFunctionType */:
                case 305 /* JSDocSignature */:
                    return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                case 184 /* TypeOperator */:
                    return getTypeFromTypeOperatorNode(node);
                case 185 /* IndexedAccessType */:
                    return getTypeFromIndexedAccessTypeNode(node);
                case 186 /* MappedType */:
                    return getTypeFromMappedTypeNode(node);
                case 180 /* ConditionalType */:
                    return getTypeFromConditionalTypeNode(node);
                case 181 /* InferType */:
                    return getTypeFromInferTypeNode(node);
                case 188 /* ImportType */:
                    return getTypeFromImportTypeNode(node);
                // This function assumes that an identifier or qualified name is a type expression
                // Callers should first ensure this by calling isTypeNode
                case 75 /* Identifier */:
                case 153 /* QualifiedName */:
                    var symbol = getSymbolAtLocation(node);
                    return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
                default:
                    return errorType;
            }
        }
        function instantiateList(items, mapper, instantiator) {
            if (items && items.length) {
                for (var i = 0; i < items.length; i++) {
                    var item = items[i];
                    var mapped = instantiator(item, mapper);
                    if (item !== mapped) {
                        var result = i === 0 ? [] : items.slice(0, i);
                        result.push(mapped);
                        for (i++; i < items.length; i++) {
                            result.push(instantiator(items[i], mapper));
                        }
                        return result;
                    }
                }
            }
            return items;
        }
        function instantiateTypes(types, mapper) {
            return instantiateList(types, mapper, instantiateType);
        }
        function instantiateSignatures(signatures, mapper) {
            return instantiateList(signatures, mapper, instantiateSignature);
        }
        function createTypeMapper(sources, targets) {
            return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : makeArrayTypeMapper(sources, targets);
        }
        function getMappedType(type, mapper) {
            switch (mapper.kind) {
                case 0 /* Simple */:
                    return type === mapper.source ? mapper.target : type;
                case 1 /* Array */:
                    var sources = mapper.sources;
                    var targets = mapper.targets;
                    for (var i = 0; i < sources.length; i++) {
                        if (type === sources[i]) {
                            return targets ? targets[i] : anyType;
                        }
                    }
                    return type;
                case 2 /* Function */:
                    return mapper.func(type);
                case 3 /* Composite */:
                case 4 /* Merged */:
                    var t1 = getMappedType(type, mapper.mapper1);
                    return t1 !== type && mapper.kind === 3 /* Composite */ ? instantiateType(t1, mapper.mapper2) : getMappedType(t1, mapper.mapper2);
            }
        }
        function makeUnaryTypeMapper(source, target) {
            return { kind: 0 /* Simple */, source: source, target: target };
        }
        function makeArrayTypeMapper(sources, targets) {
            return { kind: 1 /* Array */, sources: sources, targets: targets };
        }
        function makeFunctionTypeMapper(func) {
            return { kind: 2 /* Function */, func: func };
        }
        function makeCompositeTypeMapper(kind, mapper1, mapper2) {
            return { kind: kind, mapper1: mapper1, mapper2: mapper2 };
        }
        function createTypeEraser(sources) {
            return createTypeMapper(sources, /*targets*/ undefined);
        }
        /**
         * Maps forward-references to later types parameters to the empty object type.
         * This is used during inference when instantiating type parameter defaults.
         */
        function createBackreferenceMapper(context, index) {
            return makeFunctionTypeMapper(function (t) { return ts.findIndex(context.inferences, function (info) { return info.typeParameter === t; }) >= index ? unknownType : t; });
        }
        function combineTypeMappers(mapper1, mapper2) {
            return mapper1 ? makeCompositeTypeMapper(3 /* Composite */, mapper1, mapper2) : mapper2;
        }
        function mergeTypeMappers(mapper1, mapper2) {
            return mapper1 ? makeCompositeTypeMapper(4 /* Merged */, mapper1, mapper2) : mapper2;
        }
        function prependTypeMapping(source, target, mapper) {
            return !mapper ? makeUnaryTypeMapper(source, target) : makeCompositeTypeMapper(4 /* Merged */, makeUnaryTypeMapper(source, target), mapper);
        }
        function appendTypeMapping(mapper, source, target) {
            return !mapper ? makeUnaryTypeMapper(source, target) : makeCompositeTypeMapper(4 /* Merged */, mapper, makeUnaryTypeMapper(source, target));
        }
        function getRestrictiveTypeParameter(tp) {
            return tp.constraint === unknownType ? tp : tp.restrictiveInstantiation || (tp.restrictiveInstantiation = createTypeParameter(tp.symbol),
                tp.restrictiveInstantiation.constraint = unknownType,
                tp.restrictiveInstantiation);
        }
        function cloneTypeParameter(typeParameter) {
            var result = createTypeParameter(typeParameter.symbol);
            result.target = typeParameter;
            return result;
        }
        function instantiateTypePredicate(predicate, mapper) {
            return createTypePredicate(predicate.kind, predicate.parameterName, predicate.parameterIndex, instantiateType(predicate.type, mapper));
        }
        function instantiateSignature(signature, mapper, eraseTypeParameters) {
            var freshTypeParameters;
            if (signature.typeParameters && !eraseTypeParameters) {
                // First create a fresh set of type parameters, then include a mapping from the old to the
                // new type parameters in the mapper function. Finally store this mapper in the new type
                // parameters such that we can use it when instantiating constraints.
                freshTypeParameters = ts.map(signature.typeParameters, cloneTypeParameter);
                mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper);
                for (var _i = 0, freshTypeParameters_1 = freshTypeParameters; _i < freshTypeParameters_1.length; _i++) {
                    var tp = freshTypeParameters_1[_i];
                    tp.mapper = mapper;
                }
            }
            // Don't compute resolvedReturnType and resolvedTypePredicate now,
            // because using `mapper` now could trigger inferences to become fixed. (See `createInferenceContext`.)
            // See GH#17600.
            var result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), 
            /*resolvedReturnType*/ undefined, 
            /*resolvedTypePredicate*/ undefined, signature.minArgumentCount, signature.flags & 3 /* PropagatingFlags */);
            result.target = signature;
            result.mapper = mapper;
            return result;
        }
        function instantiateSymbol(symbol, mapper) {
            var links = getSymbolLinks(symbol);
            if (links.type && !couldContainTypeVariables(links.type)) {
                // If the type of the symbol is already resolved, and if that type could not possibly
                // be affected by instantiation, simply return the symbol itself.
                return symbol;
            }
            if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) {
                // If symbol being instantiated is itself a instantiation, fetch the original target and combine the
                // type mappers. This ensures that original type identities are properly preserved and that aliases
                // always reference a non-aliases.
                symbol = links.target;
                mapper = combineTypeMappers(links.mapper, mapper);
            }
            // Keep the flags from the symbol we're instantiating.  Mark that is instantiated, and
            // also transient so that we can just store data on it directly.
            var result = createSymbol(symbol.flags, symbol.escapedName, 1 /* Instantiated */ | ts.getCheckFlags(symbol) & (8 /* Readonly */ | 4096 /* Late */ | 16384 /* OptionalParameter */ | 32768 /* RestParameter */));
            result.declarations = symbol.declarations;
            result.parent = symbol.parent;
            result.target = symbol;
            result.mapper = mapper;
            if (symbol.valueDeclaration) {
                result.valueDeclaration = symbol.valueDeclaration;
            }
            if (links.nameType) {
                result.nameType = links.nameType;
            }
            return result;
        }
        function getObjectTypeInstantiation(type, mapper) {
            var target = type.objectFlags & 64 /* Instantiated */ ? type.target : type;
            var node = type.objectFlags & 4 /* Reference */ ? type.node : type.symbol.declarations[0];
            var links = getNodeLinks(node);
            var typeParameters = links.outerTypeParameters;
            if (!typeParameters) {
                // The first time an anonymous type is instantiated we compute and store a list of the type
                // parameters that are in scope (and therefore potentially referenced). For type literals that
                // aren't the right hand side of a generic type alias declaration we optimize by reducing the
                // set of type parameters to those that are possibly referenced in the literal.
                var declaration_1 = node;
                if (ts.isInJSFile(declaration_1)) {
                    var paramTag = ts.findAncestor(declaration_1, ts.isJSDocParameterTag);
                    if (paramTag) {
                        var paramSymbol = ts.getParameterSymbolFromJSDoc(paramTag);
                        if (paramSymbol) {
                            declaration_1 = paramSymbol.valueDeclaration;
                        }
                    }
                }
                var outerTypeParameters = getOuterTypeParameters(declaration_1, /*includeThisTypes*/ true);
                if (isJSConstructor(declaration_1)) {
                    var templateTagParameters = getTypeParametersFromDeclaration(declaration_1);
                    outerTypeParameters = ts.addRange(outerTypeParameters, templateTagParameters);
                }
                typeParameters = outerTypeParameters || ts.emptyArray;
                typeParameters = (target.objectFlags & 4 /* Reference */ || target.symbol.flags & 2048 /* TypeLiteral */) && !target.aliasTypeArguments ?
                    ts.filter(typeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, declaration_1); }) :
                    typeParameters;
                links.outerTypeParameters = typeParameters;
                if (typeParameters.length) {
                    links.instantiations = ts.createMap();
                    links.instantiations.set(getTypeListId(typeParameters), target);
                }
            }
            if (typeParameters.length) {
                // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the
                // mapper to the type parameters to produce the effective list of type arguments, and compute the
                // instantiation cache key from the type IDs of the type arguments.
                var combinedMapper_1 = combineTypeMappers(type.mapper, mapper);
                var typeArguments = ts.map(typeParameters, function (t) { return getMappedType(t, combinedMapper_1); });
                var id = getTypeListId(typeArguments);
                var result = links.instantiations.get(id);
                if (!result) {
                    var newMapper = createTypeMapper(typeParameters, typeArguments);
                    result = target.objectFlags & 4 /* Reference */ ? createDeferredTypeReference(type.target, type.node, newMapper) :
                        target.objectFlags & 32 /* Mapped */ ? instantiateMappedType(target, newMapper) :
                            instantiateAnonymousType(target, newMapper);
                    links.instantiations.set(id, result);
                }
                return result;
            }
            return type;
        }
        function maybeTypeParameterReference(node) {
            return !(node.kind === 153 /* QualifiedName */ ||
                node.parent.kind === 169 /* TypeReference */ && node.parent.typeArguments && node === node.parent.typeName ||
                node.parent.kind === 188 /* ImportType */ && node.parent.typeArguments && node === node.parent.qualifier);
        }
        function isTypeParameterPossiblyReferenced(tp, node) {
            // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks
            // between the node and the type parameter declaration, if the node contains actual references to the
            // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced.
            if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) {
                var container = tp.symbol.declarations[0].parent;
                for (var n = node; n !== container; n = n.parent) {
                    if (!n || n.kind === 223 /* Block */ || n.kind === 180 /* ConditionalType */ && ts.forEachChild(n.extendsType, containsReference)) {
                        return true;
                    }
                }
                return !!ts.forEachChild(node, containsReference);
            }
            return true;
            function containsReference(node) {
                switch (node.kind) {
                    case 183 /* ThisType */:
                        return !!tp.isThisType;
                    case 75 /* Identifier */:
                        return !tp.isThisType && ts.isPartOfTypeNode(node) && maybeTypeParameterReference(node) &&
                            getTypeFromTypeNodeWorker(node) === tp; // use worker because we're looking for === equality
                    case 172 /* TypeQuery */:
                        return true;
                }
                return !!ts.forEachChild(node, containsReference);
            }
        }
        function getHomomorphicTypeVariable(type) {
            var constraintType = getConstraintTypeFromMappedType(type);
            if (constraintType.flags & 4194304 /* Index */) {
                var typeVariable = getActualTypeVariable(constraintType.type);
                if (typeVariable.flags & 262144 /* TypeParameter */) {
                    return typeVariable;
                }
            }
            return undefined;
        }
        function instantiateMappedType(type, mapper) {
            // For a homomorphic mapped type { [P in keyof T]: X }, where T is some type variable, the mapping
            // operation depends on T as follows:
            // * If T is a primitive type no mapping is performed and the result is simply T.
            // * If T is a union type we distribute the mapped type over the union.
            // * If T is an array we map to an array where the element type has been transformed.
            // * If T is a tuple we map to a tuple where the element types have been transformed.
            // * Otherwise we map to an object type where the type of each property has been transformed.
            // For example, when T is instantiated to a union type A | B, we produce { [P in keyof A]: X } |
            // { [P in keyof B]: X }, and when when T is instantiated to a union type A | undefined, we produce
            // { [P in keyof A]: X } | undefined.
            var typeVariable = getHomomorphicTypeVariable(type);
            if (typeVariable) {
                var mappedTypeVariable = instantiateType(typeVariable, mapper);
                if (typeVariable !== mappedTypeVariable) {
                    return mapType(getReducedType(mappedTypeVariable), function (t) {
                        if (t.flags & (3 /* AnyOrUnknown */ | 58982400 /* InstantiableNonPrimitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && t !== wildcardType && t !== errorType) {
                            var replacementMapper = prependTypeMapping(typeVariable, t, mapper);
                            return isArrayType(t) ? instantiateMappedArrayType(t, type, replacementMapper) :
                                isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) :
                                    instantiateAnonymousType(type, replacementMapper);
                        }
                        return t;
                    });
                }
            }
            return instantiateAnonymousType(type, mapper);
        }
        function getModifiedReadonlyState(state, modifiers) {
            return modifiers & 1 /* IncludeReadonly */ ? true : modifiers & 2 /* ExcludeReadonly */ ? false : state;
        }
        function instantiateMappedArrayType(arrayType, mappedType, mapper) {
            var elementType = instantiateMappedTypeTemplate(mappedType, numberType, /*isOptional*/ true, mapper);
            return elementType === errorType ? errorType :
                createArrayType(elementType, getModifiedReadonlyState(isReadonlyArrayType(arrayType), getMappedTypeModifiers(mappedType)));
        }
        function instantiateMappedTupleType(tupleType, mappedType, mapper) {
            var minLength = tupleType.target.minLength;
            var elementTypes = ts.map(getTypeArguments(tupleType), function (_, i) {
                return instantiateMappedTypeTemplate(mappedType, getLiteralType("" + i), i >= minLength, mapper);
            });
            var modifiers = getMappedTypeModifiers(mappedType);
            var newMinLength = modifiers & 4 /* IncludeOptional */ ? 0 :
                modifiers & 8 /* ExcludeOptional */ ? getTypeReferenceArity(tupleType) - (tupleType.target.hasRestElement ? 1 : 0) :
                    minLength;
            var newReadonly = getModifiedReadonlyState(tupleType.target.readonly, modifiers);
            return ts.contains(elementTypes, errorType) ? errorType :
                createTupleType(elementTypes, newMinLength, tupleType.target.hasRestElement, newReadonly, tupleType.target.associatedNames);
        }
        function instantiateMappedTypeTemplate(type, key, isOptional, mapper) {
            var templateMapper = appendTypeMapping(mapper, getTypeParameterFromMappedType(type), key);
            var propType = instantiateType(getTemplateTypeFromMappedType(type.target || type), templateMapper);
            var modifiers = getMappedTypeModifiers(type);
            return strictNullChecks && modifiers & 4 /* IncludeOptional */ && !maybeTypeOfKind(propType, 32768 /* Undefined */ | 16384 /* Void */) ? getOptionalType(propType) :
                strictNullChecks && modifiers & 8 /* ExcludeOptional */ && isOptional ? getTypeWithFacts(propType, 524288 /* NEUndefined */) :
                    propType;
        }
        function instantiateAnonymousType(type, mapper) {
            var result = createObjectType(type.objectFlags | 64 /* Instantiated */, type.symbol);
            if (type.objectFlags & 32 /* Mapped */) {
                result.declaration = type.declaration;
                // C.f. instantiateSignature
                var origTypeParameter = getTypeParameterFromMappedType(type);
                var freshTypeParameter = cloneTypeParameter(origTypeParameter);
                result.typeParameter = freshTypeParameter;
                mapper = combineTypeMappers(makeUnaryTypeMapper(origTypeParameter, freshTypeParameter), mapper);
                freshTypeParameter.mapper = mapper;
            }
            result.target = type;
            result.mapper = mapper;
            result.aliasSymbol = type.aliasSymbol;
            result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper);
            return result;
        }
        function getConditionalTypeInstantiation(type, mapper) {
            var root = type.root;
            if (root.outerTypeParameters) {
                // We are instantiating a conditional type that has one or more type parameters in scope. Apply the
                // mapper to the type parameters to produce the effective list of type arguments, and compute the
                // instantiation cache key from the type IDs of the type arguments.
                var typeArguments = ts.map(root.outerTypeParameters, function (t) { return getMappedType(t, mapper); });
                var id = getTypeListId(typeArguments);
                var result = root.instantiations.get(id);
                if (!result) {
                    var newMapper = createTypeMapper(root.outerTypeParameters, typeArguments);
                    result = instantiateConditionalType(root, newMapper);
                    root.instantiations.set(id, result);
                }
                return result;
            }
            return type;
        }
        function instantiateConditionalType(root, mapper) {
            // Check if we have a conditional type where the check type is a naked type parameter. If so,
            // the conditional type is distributive over union types and when T is instantiated to a union
            // type A | B, we produce (A extends U ? X : Y) | (B extends U ? X : Y).
            if (root.isDistributive) {
                var checkType_1 = root.checkType;
                var instantiatedType = getMappedType(checkType_1, mapper);
                if (checkType_1 !== instantiatedType && instantiatedType.flags & (1048576 /* Union */ | 131072 /* Never */)) {
                    return mapType(instantiatedType, function (t) { return getConditionalType(root, prependTypeMapping(checkType_1, t, mapper)); });
                }
            }
            return getConditionalType(root, mapper);
        }
        function instantiateType(type, mapper) {
            if (!type || !mapper) {
                return type;
            }
            if (instantiationDepth === 50 || instantiationCount >= 5000000) {
                // We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing
                // with a combination of infinite generic types that perpetually generate new type identities. We stop
                // the recursion here by yielding the error type.
                error(currentNode, ts.Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
                return errorType;
            }
            totalInstantiationCount++;
            instantiationCount++;
            instantiationDepth++;
            var result = instantiateTypeWorker(type, mapper);
            instantiationDepth--;
            return result;
        }
        /**
         * This can be used to avoid the penalty on instantiation depth for types which result from immediate
         * simplification. It essentially removes the depth increase done in `instantiateType`.
         */
        function instantiateTypeWithoutDepthIncrease(type, mapper) {
            instantiationDepth--;
            var result = instantiateType(type, mapper);
            instantiationDepth++;
            return result;
        }
        function instantiateTypeWorker(type, mapper) {
            var flags = type.flags;
            if (flags & 262144 /* TypeParameter */) {
                return getMappedType(type, mapper);
            }
            if (flags & 524288 /* Object */) {
                var objectFlags = type.objectFlags;
                if (objectFlags & 16 /* Anonymous */) {
                    // If the anonymous type originates in a declaration of a function, method, class, or
                    // interface, in an object type literal, or in an object literal expression, we may need
                    // to instantiate the type because it might reference a type parameter.
                    return couldContainTypeVariables(type) ?
                        getObjectTypeInstantiation(type, mapper) : type;
                }
                if (objectFlags & 32 /* Mapped */) {
                    return getObjectTypeInstantiation(type, mapper);
                }
                if (objectFlags & 4 /* Reference */) {
                    if (type.node) {
                        return getObjectTypeInstantiation(type, mapper);
                    }
                    var resolvedTypeArguments = type.resolvedTypeArguments;
                    var newTypeArguments = instantiateTypes(resolvedTypeArguments, mapper);
                    return newTypeArguments !== resolvedTypeArguments ? createTypeReference(type.target, newTypeArguments) : type;
                }
                return type;
            }
            if ((flags & 2097152 /* Intersection */) || (flags & 1048576 /* Union */ && !(flags & 131068 /* Primitive */))) {
                if (!couldContainTypeVariables(type)) {
                    return type;
                }
                var types = type.types;
                var newTypes = instantiateTypes(types, mapper);
                return newTypes === types
                    ? type
                    : (flags & 2097152 /* Intersection */)
                        ? getIntersectionType(newTypes, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper))
                        : getUnionType(newTypes, 1 /* Literal */, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
            }
            if (flags & 4194304 /* Index */) {
                return getIndexType(instantiateType(type.type, mapper));
            }
            if (flags & 8388608 /* IndexedAccess */) {
                return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper), /*accessNode*/ undefined, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
            }
            if (flags & 16777216 /* Conditional */) {
                return getConditionalTypeInstantiation(type, combineTypeMappers(type.mapper, mapper));
            }
            if (flags & 33554432 /* Substitution */) {
                var maybeVariable = instantiateType(type.baseType, mapper);
                if (maybeVariable.flags & 8650752 /* TypeVariable */) {
                    return getSubstitutionType(maybeVariable, instantiateType(type.substitute, mapper));
                }
                else {
                    var sub = instantiateType(type.substitute, mapper);
                    if (sub.flags & 3 /* AnyOrUnknown */ || isTypeAssignableTo(getRestrictiveInstantiation(maybeVariable), getRestrictiveInstantiation(sub))) {
                        return maybeVariable;
                    }
                    return sub;
                }
            }
            return type;
        }
        function getPermissiveInstantiation(type) {
            return type.flags & (131068 /* Primitive */ | 3 /* AnyOrUnknown */ | 131072 /* Never */) ? type :
                type.permissiveInstantiation || (type.permissiveInstantiation = instantiateType(type, permissiveMapper));
        }
        function getRestrictiveInstantiation(type) {
            if (type.flags & (131068 /* Primitive */ | 3 /* AnyOrUnknown */ | 131072 /* Never */)) {
                return type;
            }
            if (type.restrictiveInstantiation) {
                return type.restrictiveInstantiation;
            }
            type.restrictiveInstantiation = instantiateType(type, restrictiveMapper);
            // We set the following so we don't attempt to set the restrictive instance of a restrictive instance
            // which is redundant - we'll produce new type identities, but all type params have already been mapped.
            // This also gives us a way to detect restrictive instances upon comparisons and _disable_ the "distributeive constraint"
            // assignability check for them, which is distinctly unsafe, as once you have a restrctive instance, all the type parameters
            // are constrained to `unknown` and produce tons of false positives/negatives!
            type.restrictiveInstantiation.restrictiveInstantiation = type.restrictiveInstantiation;
            return type.restrictiveInstantiation;
        }
        function instantiateIndexInfo(info, mapper) {
            return info && createIndexInfo(instantiateType(info.type, mapper), info.isReadonly, info.declaration);
        }
        // Returns true if the given expression contains (at any level of nesting) a function or arrow expression
        // that is subject to contextual typing.
        function isContextSensitive(node) {
            ts.Debug.assert(node.kind !== 161 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            switch (node.kind) {
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 161 /* MethodDeclaration */:
                case 244 /* FunctionDeclaration */: // Function declarations can have context when annotated with a jsdoc @type
                    return isContextSensitiveFunctionLikeDeclaration(node);
                case 193 /* ObjectLiteralExpression */:
                    return ts.some(node.properties, isContextSensitive);
                case 192 /* ArrayLiteralExpression */:
                    return ts.some(node.elements, isContextSensitive);
                case 210 /* ConditionalExpression */:
                    return isContextSensitive(node.whenTrue) ||
                        isContextSensitive(node.whenFalse);
                case 209 /* BinaryExpression */:
                    return (node.operatorToken.kind === 56 /* BarBarToken */ || node.operatorToken.kind === 60 /* QuestionQuestionToken */) &&
                        (isContextSensitive(node.left) || isContextSensitive(node.right));
                case 281 /* PropertyAssignment */:
                    return isContextSensitive(node.initializer);
                case 200 /* ParenthesizedExpression */:
                    return isContextSensitive(node.expression);
                case 274 /* JsxAttributes */:
                    return ts.some(node.properties, isContextSensitive) || ts.isJsxOpeningElement(node.parent) && ts.some(node.parent.parent.children, isContextSensitive);
                case 273 /* JsxAttribute */: {
                    // If there is no initializer, JSX attribute has a boolean value of true which is not context sensitive.
                    var initializer = node.initializer;
                    return !!initializer && isContextSensitive(initializer);
                }
                case 276 /* JsxExpression */: {
                    // It is possible to that node.expression is undefined (e.g <div x={} />)
                    var expression = node.expression;
                    return !!expression && isContextSensitive(expression);
                }
            }
            return false;
        }
        function isContextSensitiveFunctionLikeDeclaration(node) {
            return (!ts.isFunctionDeclaration(node) || ts.isInJSFile(node) && !!getTypeForDeclarationFromJSDocComment(node)) &&
                (hasContextSensitiveParameters(node) || hasContextSensitiveReturnExpression(node));
        }
        function hasContextSensitiveParameters(node) {
            // Functions with type parameters are not context sensitive.
            if (!node.typeParameters) {
                // Functions with any parameters that lack type annotations are context sensitive.
                if (ts.some(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) {
                    return true;
                }
                if (node.kind !== 202 /* ArrowFunction */) {
                    // If the first parameter is not an explicit 'this' parameter, then the function has
                    // an implicit 'this' parameter which is subject to contextual typing.
                    var parameter = ts.firstOrUndefined(node.parameters);
                    if (!(parameter && ts.parameterIsThisKeyword(parameter))) {
                        return true;
                    }
                }
            }
            return false;
        }
        function hasContextSensitiveReturnExpression(node) {
            // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value.
            return !node.typeParameters && !ts.getEffectiveReturnTypeNode(node) && !!node.body && node.body.kind !== 223 /* Block */ && isContextSensitive(node.body);
        }
        function isContextSensitiveFunctionOrObjectLiteralMethod(func) {
            return (ts.isInJSFile(func) && ts.isFunctionDeclaration(func) || isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) &&
                isContextSensitiveFunctionLikeDeclaration(func);
        }
        function getTypeWithoutSignatures(type) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (resolved.constructSignatures.length || resolved.callSignatures.length) {
                    var result = createObjectType(16 /* Anonymous */, type.symbol);
                    result.members = resolved.members;
                    result.properties = resolved.properties;
                    result.callSignatures = ts.emptyArray;
                    result.constructSignatures = ts.emptyArray;
                    return result;
                }
            }
            else if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, getTypeWithoutSignatures));
            }
            return type;
        }
        // TYPE CHECKING
        function isTypeIdenticalTo(source, target) {
            return isTypeRelatedTo(source, target, identityRelation);
        }
        function compareTypesIdentical(source, target) {
            return isTypeRelatedTo(source, target, identityRelation) ? -1 /* True */ : 0 /* False */;
        }
        function compareTypesAssignable(source, target) {
            return isTypeRelatedTo(source, target, assignableRelation) ? -1 /* True */ : 0 /* False */;
        }
        function compareTypesSubtypeOf(source, target) {
            return isTypeRelatedTo(source, target, subtypeRelation) ? -1 /* True */ : 0 /* False */;
        }
        function isTypeSubtypeOf(source, target) {
            return isTypeRelatedTo(source, target, subtypeRelation);
        }
        function isTypeAssignableTo(source, target) {
            return isTypeRelatedTo(source, target, assignableRelation);
        }
        // An object type S is considered to be derived from an object type T if
        // S is a union type and every constituent of S is derived from T,
        // T is a union type and S is derived from at least one constituent of T, or
        // S is a type variable with a base constraint that is derived from T,
        // T is one of the global types Object and Function and S is a subtype of T, or
        // T occurs directly or indirectly in an 'extends' clause of S.
        // Note that this check ignores type parameters and only considers the
        // inheritance hierarchy.
        function isTypeDerivedFrom(source, target) {
            return source.flags & 1048576 /* Union */ ? ts.every(source.types, function (t) { return isTypeDerivedFrom(t, target); }) :
                target.flags & 1048576 /* Union */ ? ts.some(target.types, function (t) { return isTypeDerivedFrom(source, t); }) :
                    source.flags & 58982400 /* InstantiableNonPrimitive */ ? isTypeDerivedFrom(getBaseConstraintOfType(source) || unknownType, target) :
                        target === globalObjectType ? !!(source.flags & (524288 /* Object */ | 67108864 /* NonPrimitive */)) :
                            target === globalFunctionType ? !!(source.flags & 524288 /* Object */) && isFunctionObjectType(source) :
                                hasBaseType(source, getTargetType(target));
        }
        /**
         * This is *not* a bi-directional relationship.
         * If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
         *
         * A type S is comparable to a type T if some (but not necessarily all) of the possible values of S are also possible values of T.
         * It is used to check following cases:
         *   - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`).
         *   - the types of `case` clause expressions and their respective `switch` expressions.
         *   - the type of an expression in a type assertion with the type being asserted.
         */
        function isTypeComparableTo(source, target) {
            return isTypeRelatedTo(source, target, comparableRelation);
        }
        function areTypesComparable(type1, type2) {
            return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1);
        }
        function checkTypeAssignableTo(source, target, errorNode, headMessage, containingMessageChain, errorOutputObject) {
            return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain, errorOutputObject);
        }
        /**
         * Like `checkTypeAssignableTo`, but if it would issue an error, instead performs structural comparisons of the types using the given expression node to
         * attempt to issue more specific errors on, for example, specific object literal properties or tuple members.
         */
        function checkTypeAssignableToAndOptionallyElaborate(source, target, errorNode, expr, headMessage, containingMessageChain) {
            return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain, /*errorOutputContainer*/ undefined);
        }
        function checkTypeRelatedToAndOptionallyElaborate(source, target, relation, errorNode, expr, headMessage, containingMessageChain, errorOutputContainer) {
            if (isTypeRelatedTo(source, target, relation))
                return true;
            if (!errorNode || !elaborateError(expr, source, target, relation, headMessage, containingMessageChain, errorOutputContainer)) {
                return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer);
            }
            return false;
        }
        function isOrHasGenericConditional(type) {
            return !!(type.flags & 16777216 /* Conditional */ || (type.flags & 2097152 /* Intersection */ && ts.some(type.types, isOrHasGenericConditional)));
        }
        function elaborateError(node, source, target, relation, headMessage, containingMessageChain, errorOutputContainer) {
            if (!node || isOrHasGenericConditional(target))
                return false;
            if (!checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined)
                && elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage, containingMessageChain, errorOutputContainer)) {
                return true;
            }
            switch (node.kind) {
                case 276 /* JsxExpression */:
                case 200 /* ParenthesizedExpression */:
                    return elaborateError(node.expression, source, target, relation, headMessage, containingMessageChain, errorOutputContainer);
                case 209 /* BinaryExpression */:
                    switch (node.operatorToken.kind) {
                        case 62 /* EqualsToken */:
                        case 27 /* CommaToken */:
                            return elaborateError(node.right, source, target, relation, headMessage, containingMessageChain, errorOutputContainer);
                    }
                    break;
                case 193 /* ObjectLiteralExpression */:
                    return elaborateObjectLiteral(node, source, target, relation, containingMessageChain, errorOutputContainer);
                case 192 /* ArrayLiteralExpression */:
                    return elaborateArrayLiteral(node, source, target, relation, containingMessageChain, errorOutputContainer);
                case 274 /* JsxAttributes */:
                    return elaborateJsxComponents(node, source, target, relation, containingMessageChain, errorOutputContainer);
                case 202 /* ArrowFunction */:
                    return elaborateArrowFunction(node, source, target, relation, containingMessageChain, errorOutputContainer);
            }
            return false;
        }
        function elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage, containingMessageChain, errorOutputContainer) {
            var callSignatures = getSignaturesOfType(source, 0 /* Call */);
            var constructSignatures = getSignaturesOfType(source, 1 /* Construct */);
            for (var _i = 0, _a = [constructSignatures, callSignatures]; _i < _a.length; _i++) {
                var signatures = _a[_i];
                if (ts.some(signatures, function (s) {
                    var returnType = getReturnTypeOfSignature(s);
                    return !(returnType.flags & (1 /* Any */ | 131072 /* Never */)) && checkTypeRelatedTo(returnType, target, relation, /*errorNode*/ undefined);
                })) {
                    var resultObj = errorOutputContainer || {};
                    checkTypeAssignableTo(source, target, node, headMessage, containingMessageChain, resultObj);
                    var diagnostic = resultObj.errors[resultObj.errors.length - 1];
                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(node, signatures === constructSignatures ? ts.Diagnostics.Did_you_mean_to_use_new_with_this_expression : ts.Diagnostics.Did_you_mean_to_call_this_expression));
                    return true;
                }
            }
            return false;
        }
        function elaborateArrowFunction(node, source, target, relation, containingMessageChain, errorOutputContainer) {
            // Don't elaborate blocks
            if (ts.isBlock(node.body)) {
                return false;
            }
            // Or functions with annotated parameter types
            if (ts.some(node.parameters, ts.hasType)) {
                return false;
            }
            var sourceSig = getSingleCallSignature(source);
            if (!sourceSig) {
                return false;
            }
            var targetSignatures = getSignaturesOfType(target, 0 /* Call */);
            if (!ts.length(targetSignatures)) {
                return false;
            }
            var returnExpression = node.body;
            var sourceReturn = getReturnTypeOfSignature(sourceSig);
            var targetReturn = getUnionType(ts.map(targetSignatures, getReturnTypeOfSignature));
            if (!checkTypeRelatedTo(sourceReturn, targetReturn, relation, /*errorNode*/ undefined)) {
                var elaborated = returnExpression && elaborateError(returnExpression, sourceReturn, targetReturn, relation, /*headMessage*/ undefined, containingMessageChain, errorOutputContainer);
                if (elaborated) {
                    return elaborated;
                }
                var resultObj = errorOutputContainer || {};
                checkTypeRelatedTo(sourceReturn, targetReturn, relation, returnExpression, /*message*/ undefined, containingMessageChain, resultObj);
                if (resultObj.errors) {
                    if (target.symbol && ts.length(target.symbol.declarations)) {
                        ts.addRelatedInfo(resultObj.errors[resultObj.errors.length - 1], ts.createDiagnosticForNode(target.symbol.declarations[0], ts.Diagnostics.The_expected_type_comes_from_the_return_type_of_this_signature));
                    }
                    if ((ts.getFunctionFlags(node) & 2 /* Async */) === 0
                        // exclude cases where source itself is promisy - this way we don't make a suggestion when relating
                        // an IPromise and a Promise that are slightly different
                        && !getTypeOfPropertyOfType(sourceReturn, "then")
                        && checkTypeRelatedTo(createPromiseType(sourceReturn), targetReturn, relation, /*errorNode*/ undefined)) {
                        ts.addRelatedInfo(resultObj.errors[resultObj.errors.length - 1], ts.createDiagnosticForNode(node, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async));
                    }
                    return true;
                }
            }
            return false;
        }
        function getBestMatchIndexedAccessTypeOrUndefined(source, target, nameType) {
            var idx = getIndexedAccessTypeOrUndefined(target, nameType);
            if (idx) {
                return idx;
            }
            if (target.flags & 1048576 /* Union */) {
                var best = getBestMatchingType(source, target);
                if (best) {
                    return getIndexedAccessTypeOrUndefined(best, nameType);
                }
            }
        }
        function checkExpressionForMutableLocationWithContextualType(next, sourcePropType) {
            next.contextualType = sourcePropType;
            try {
                return checkExpressionForMutableLocation(next, 1 /* Contextual */, sourcePropType);
            }
            finally {
                next.contextualType = undefined;
            }
        }
        /**
         * For every element returned from the iterator, checks that element to issue an error on a property of that element's type
         * If that element would issue an error, we first attempt to dive into that element's inner expression and issue a more specific error by recuring into `elaborateError`
         * Otherwise, we issue an error on _every_ element which fail the assignability check
         */
        function elaborateElementwise(iterator, source, target, relation, containingMessageChain, errorOutputContainer) {
            // Assignability failure - check each prop individually, and if that fails, fall back on the bad error span
            var reportedError = false;
            for (var status = iterator.next(); !status.done; status = iterator.next()) {
                var _a = status.value, prop = _a.errorNode, next = _a.innerExpression, nameType = _a.nameType, errorMessage = _a.errorMessage;
                var targetPropType = getBestMatchIndexedAccessTypeOrUndefined(source, target, nameType);
                if (!targetPropType || targetPropType.flags & 8388608 /* IndexedAccess */)
                    continue; // Don't elaborate on indexes on generic variables
                var sourcePropType = getIndexedAccessTypeOrUndefined(source, nameType);
                if (sourcePropType && !checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) {
                    var elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined, containingMessageChain, errorOutputContainer);
                    if (elaborated) {
                        reportedError = true;
                    }
                    else {
                        // Issue error on the prop itself, since the prop couldn't elaborate the error
                        var resultObj = errorOutputContainer || {};
                        // Use the expression type, if available
                        var specificSource = next ? checkExpressionForMutableLocationWithContextualType(next, sourcePropType) : sourcePropType;
                        var result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage, containingMessageChain, resultObj);
                        if (result && specificSource !== sourcePropType) {
                            // If for whatever reason the expression type doesn't yield an error, make sure we still issue an error on the sourcePropType
                            checkTypeRelatedTo(sourcePropType, targetPropType, relation, prop, errorMessage, containingMessageChain, resultObj);
                        }
                        if (resultObj.errors) {
                            var reportedDiag = resultObj.errors[resultObj.errors.length - 1];
                            var propertyName = isTypeUsableAsPropertyName(nameType) ? getPropertyNameFromType(nameType) : undefined;
                            var targetProp = propertyName !== undefined ? getPropertyOfType(target, propertyName) : undefined;
                            var issuedElaboration = false;
                            if (!targetProp) {
                                var indexInfo = isTypeAssignableToKind(nameType, 296 /* NumberLike */) && getIndexInfoOfType(target, 1 /* Number */) ||
                                    getIndexInfoOfType(target, 0 /* String */) ||
                                    undefined;
                                if (indexInfo && indexInfo.declaration && !ts.getSourceFileOfNode(indexInfo.declaration).hasNoDefaultLib) {
                                    issuedElaboration = true;
                                    ts.addRelatedInfo(reportedDiag, ts.createDiagnosticForNode(indexInfo.declaration, ts.Diagnostics.The_expected_type_comes_from_this_index_signature));
                                }
                            }
                            if (!issuedElaboration && (targetProp && ts.length(targetProp.declarations) || target.symbol && ts.length(target.symbol.declarations))) {
                                var targetNode = targetProp && ts.length(targetProp.declarations) ? targetProp.declarations[0] : target.symbol.declarations[0];
                                if (!ts.getSourceFileOfNode(targetNode).hasNoDefaultLib) {
                                    ts.addRelatedInfo(reportedDiag, ts.createDiagnosticForNode(targetNode, ts.Diagnostics.The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1, propertyName && !(nameType.flags & 8192 /* UniqueESSymbol */) ? ts.unescapeLeadingUnderscores(propertyName) : typeToString(nameType), typeToString(target)));
                                }
                            }
                        }
                        reportedError = true;
                    }
                }
            }
            return reportedError;
        }
        function generateJsxAttributes(node) {
            var _i, _a, prop;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!ts.length(node.properties))
                            return [2 /*return*/];
                        _i = 0, _a = node.properties;
                        _b.label = 1;
                    case 1:
                        if (!(_i < _a.length)) return [3 /*break*/, 4];
                        prop = _a[_i];
                        if (ts.isJsxSpreadAttribute(prop))
                            return [3 /*break*/, 3];
                        return [4 /*yield*/, { errorNode: prop.name, innerExpression: prop.initializer, nameType: getLiteralType(ts.idText(prop.name)) }];
                    case 2:
                        _b.sent();
                        _b.label = 3;
                    case 3:
                        _i++;
                        return [3 /*break*/, 1];
                    case 4: return [2 /*return*/];
                }
            });
        }
        function generateJsxChildren(node, getInvalidTextDiagnostic) {
            var memberOffset, i, child, nameType, elem;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!ts.length(node.children))
                            return [2 /*return*/];
                        memberOffset = 0;
                        i = 0;
                        _a.label = 1;
                    case 1:
                        if (!(i < node.children.length)) return [3 /*break*/, 5];
                        child = node.children[i];
                        nameType = getLiteralType(i - memberOffset);
                        elem = getElaborationElementForJsxChild(child, nameType, getInvalidTextDiagnostic);
                        if (!elem) return [3 /*break*/, 3];
                        return [4 /*yield*/, elem];
                    case 2:
                        _a.sent();
                        return [3 /*break*/, 4];
                    case 3:
                        memberOffset++;
                        _a.label = 4;
                    case 4:
                        i++;
                        return [3 /*break*/, 1];
                    case 5: return [2 /*return*/];
                }
            });
        }
        function getElaborationElementForJsxChild(child, nameType, getInvalidTextDiagnostic) {
            switch (child.kind) {
                case 276 /* JsxExpression */:
                    // child is of the type of the expression
                    return { errorNode: child, innerExpression: child.expression, nameType: nameType };
                case 11 /* JsxText */:
                    if (child.containsOnlyTriviaWhiteSpaces) {
                        break; // Whitespace only jsx text isn't real jsx text
                    }
                    // child is a string
                    return { errorNode: child, innerExpression: undefined, nameType: nameType, errorMessage: getInvalidTextDiagnostic() };
                case 266 /* JsxElement */:
                case 267 /* JsxSelfClosingElement */:
                case 270 /* JsxFragment */:
                    // child is of type JSX.Element
                    return { errorNode: child, innerExpression: child, nameType: nameType };
                default:
                    return ts.Debug.assertNever(child, "Found invalid jsx child");
            }
        }
        function getSemanticJsxChildren(children) {
            return ts.filter(children, function (i) { return !ts.isJsxText(i) || !i.containsOnlyTriviaWhiteSpaces; });
        }
        function elaborateJsxComponents(node, source, target, relation, containingMessageChain, errorOutputContainer) {
            var result = elaborateElementwise(generateJsxAttributes(node), source, target, relation, containingMessageChain, errorOutputContainer);
            var invalidTextDiagnostic;
            if (ts.isJsxOpeningElement(node.parent) && ts.isJsxElement(node.parent.parent)) {
                var containingElement = node.parent.parent;
                var childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
                var childrenPropName = childPropName === undefined ? "children" : ts.unescapeLeadingUnderscores(childPropName);
                var childrenNameType = getLiteralType(childrenPropName);
                var childrenTargetType = getIndexedAccessType(target, childrenNameType);
                var validChildren = getSemanticJsxChildren(containingElement.children);
                if (!ts.length(validChildren)) {
                    return result;
                }
                var moreThanOneRealChildren = ts.length(validChildren) > 1;
                var arrayLikeTargetParts = filterType(childrenTargetType, isArrayOrTupleLikeType);
                var nonArrayLikeTargetParts = filterType(childrenTargetType, function (t) { return !isArrayOrTupleLikeType(t); });
                if (moreThanOneRealChildren) {
                    if (arrayLikeTargetParts !== neverType) {
                        var realSource = createTupleType(checkJsxChildren(containingElement, 0 /* Normal */));
                        var children = generateJsxChildren(containingElement, getInvalidTextualChildDiagnostic);
                        result = elaborateElementwise(children, realSource, arrayLikeTargetParts, relation, containingMessageChain, errorOutputContainer) || result;
                    }
                    else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) {
                        // arity mismatch
                        result = true;
                        var diag = error(containingElement.openingElement.tagName, ts.Diagnostics.This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided, childrenPropName, typeToString(childrenTargetType));
                        if (errorOutputContainer && errorOutputContainer.skipLogging) {
                            (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                        }
                    }
                }
                else {
                    if (nonArrayLikeTargetParts !== neverType) {
                        var child = validChildren[0];
                        var elem_1 = getElaborationElementForJsxChild(child, childrenNameType, getInvalidTextualChildDiagnostic);
                        if (elem_1) {
                            result = elaborateElementwise((function () { return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0: return [4 /*yield*/, elem_1];
                                    case 1:
                                        _a.sent();
                                        return [2 /*return*/];
                                }
                            }); })(), source, target, relation, containingMessageChain, errorOutputContainer) || result;
                        }
                    }
                    else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) {
                        // arity mismatch
                        result = true;
                        var diag = error(containingElement.openingElement.tagName, ts.Diagnostics.This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided, childrenPropName, typeToString(childrenTargetType));
                        if (errorOutputContainer && errorOutputContainer.skipLogging) {
                            (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                        }
                    }
                }
            }
            return result;
            function getInvalidTextualChildDiagnostic() {
                if (!invalidTextDiagnostic) {
                    var tagNameText = ts.getTextOfNode(node.parent.tagName);
                    var childPropName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
                    var childrenPropName = childPropName === undefined ? "children" : ts.unescapeLeadingUnderscores(childPropName);
                    var childrenTargetType = getIndexedAccessType(target, getLiteralType(childrenPropName));
                    var diagnostic = ts.Diagnostics._0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2;
                    invalidTextDiagnostic = __assign(__assign({}, diagnostic), { key: "!!ALREADY FORMATTED!!", message: ts.formatMessage(/*_dummy*/ undefined, diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) });
                }
                return invalidTextDiagnostic;
            }
        }
        function generateLimitedTupleElements(node, target) {
            var len, i, elem, nameType;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        len = ts.length(node.elements);
                        if (!len)
                            return [2 /*return*/];
                        i = 0;
                        _a.label = 1;
                    case 1:
                        if (!(i < len)) return [3 /*break*/, 4];
                        // Skip elements which do not exist in the target - a length error on the tuple overall is likely better than an error on a mismatched index signature
                        if (isTupleLikeType(target) && !getPropertyOfType(target, ("" + i)))
                            return [3 /*break*/, 3];
                        elem = node.elements[i];
                        if (ts.isOmittedExpression(elem))
                            return [3 /*break*/, 3];
                        nameType = getLiteralType(i);
                        return [4 /*yield*/, { errorNode: elem, innerExpression: elem, nameType: nameType }];
                    case 2:
                        _a.sent();
                        _a.label = 3;
                    case 3:
                        i++;
                        return [3 /*break*/, 1];
                    case 4: return [2 /*return*/];
                }
            });
        }
        function elaborateArrayLiteral(node, source, target, relation, containingMessageChain, errorOutputContainer) {
            if (target.flags & 131068 /* Primitive */)
                return false;
            if (isTupleLikeType(source)) {
                return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation, containingMessageChain, errorOutputContainer);
            }
            // recreate a tuple from the elements, if possible
            // Since we're re-doing the expression type, we need to reapply the contextual type
            var oldContext = node.contextualType;
            node.contextualType = target;
            try {
                var tupleizedType = checkArrayLiteral(node, 1 /* Contextual */, /*forceTuple*/ true);
                node.contextualType = oldContext;
                if (isTupleLikeType(tupleizedType)) {
                    return elaborateElementwise(generateLimitedTupleElements(node, target), tupleizedType, target, relation, containingMessageChain, errorOutputContainer);
                }
                return false;
            }
            finally {
                node.contextualType = oldContext;
            }
        }
        function generateObjectLiteralElements(node) {
            var _i, _a, prop, type, _b;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        if (!ts.length(node.properties))
                            return [2 /*return*/];
                        _i = 0, _a = node.properties;
                        _c.label = 1;
                    case 1:
                        if (!(_i < _a.length)) return [3 /*break*/, 8];
                        prop = _a[_i];
                        if (ts.isSpreadAssignment(prop))
                            return [3 /*break*/, 7];
                        type = getLiteralTypeFromProperty(getSymbolOfNode(prop), 8576 /* StringOrNumberLiteralOrUnique */);
                        if (!type || (type.flags & 131072 /* Never */)) {
                            return [3 /*break*/, 7];
                        }
                        _b = prop.kind;
                        switch (_b) {
                            case 164 /* SetAccessor */: return [3 /*break*/, 2];
                            case 163 /* GetAccessor */: return [3 /*break*/, 2];
                            case 161 /* MethodDeclaration */: return [3 /*break*/, 2];
                            case 282 /* ShorthandPropertyAssignment */: return [3 /*break*/, 2];
                            case 281 /* PropertyAssignment */: return [3 /*break*/, 4];
                        }
                        return [3 /*break*/, 6];
                    case 2: return [4 /*yield*/, { errorNode: prop.name, innerExpression: undefined, nameType: type }];
                    case 3:
                        _c.sent();
                        return [3 /*break*/, 7];
                    case 4: return [4 /*yield*/, { errorNode: prop.name, innerExpression: prop.initializer, nameType: type, errorMessage: ts.isComputedNonLiteralName(prop.name) ? ts.Diagnostics.Type_of_computed_property_s_value_is_0_which_is_not_assignable_to_type_1 : undefined }];
                    case 5:
                        _c.sent();
                        return [3 /*break*/, 7];
                    case 6:
                        ts.Debug.assertNever(prop);
                        _c.label = 7;
                    case 7:
                        _i++;
                        return [3 /*break*/, 1];
                    case 8: return [2 /*return*/];
                }
            });
        }
        function elaborateObjectLiteral(node, source, target, relation, containingMessageChain, errorOutputContainer) {
            if (target.flags & 131068 /* Primitive */)
                return false;
            return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation, containingMessageChain, errorOutputContainer);
        }
        /**
         * This is *not* a bi-directional relationship.
         * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'.
         */
        function checkTypeComparableTo(source, target, errorNode, headMessage, containingMessageChain) {
            return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain);
        }
        function isSignatureAssignableTo(source, target, ignoreReturnTypes) {
            return compareSignaturesRelated(source, target, ignoreReturnTypes ? 4 /* IgnoreReturnTypes */ : 0, /*reportErrors*/ false, 
            /*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== 0 /* False */;
        }
        /**
         * Returns true if `s` is `(...args: any[]) => any` or `(this: any, ...args: any[]) => any`
         */
        function isAnySignature(s) {
            return !s.typeParameters && (!s.thisParameter || isTypeAny(getTypeOfParameter(s.thisParameter))) && s.parameters.length === 1 &&
                signatureHasRestParameter(s) && (getTypeOfParameter(s.parameters[0]) === anyArrayType || isTypeAny(getTypeOfParameter(s.parameters[0]))) &&
                isTypeAny(getReturnTypeOfSignature(s));
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesRelated(source, target, checkMode, reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) {
            // TODO (drosen): De-duplicate code between related functions.
            if (source === target) {
                return -1 /* True */;
            }
            if (isAnySignature(target)) {
                return -1 /* True */;
            }
            var targetCount = getParameterCount(target);
            var sourceHasMoreParameters = !hasEffectiveRestParameter(target) &&
                (checkMode & 8 /* StrictArity */ ? hasEffectiveRestParameter(source) || getParameterCount(source) > targetCount : getMinArgumentCount(source) > targetCount);
            if (sourceHasMoreParameters) {
                return 0 /* False */;
            }
            if (source.typeParameters && source.typeParameters !== target.typeParameters) {
                target = getCanonicalSignature(target);
                source = instantiateSignatureInContextOf(source, target, /*inferenceContext*/ undefined, compareTypes);
            }
            var sourceCount = getParameterCount(source);
            var sourceRestType = getNonArrayRestType(source);
            var targetRestType = getNonArrayRestType(target);
            if (sourceRestType || targetRestType) {
                void instantiateType(sourceRestType || targetRestType, reportUnreliableMarkers);
            }
            if (sourceRestType && targetRestType && sourceCount !== targetCount) {
                // We're not able to relate misaligned complex rest parameters
                return 0 /* False */;
            }
            var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */;
            var strictVariance = !(checkMode & 3 /* Callback */) && strictFunctionTypes && kind !== 161 /* MethodDeclaration */ &&
                kind !== 160 /* MethodSignature */ && kind !== 162 /* Constructor */;
            var result = -1 /* True */;
            var sourceThisType = getThisTypeOfSignature(source);
            if (sourceThisType && sourceThisType !== voidType) {
                var targetThisType = getThisTypeOfSignature(target);
                if (targetThisType) {
                    // void sources are assignable to anything.
                    var related = !strictVariance && compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false)
                        || compareTypes(targetThisType, sourceThisType, reportErrors);
                    if (!related) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.The_this_types_of_each_signature_are_incompatible);
                        }
                        return 0 /* False */;
                    }
                    result &= related;
                }
            }
            var paramCount = sourceRestType || targetRestType ? Math.min(sourceCount, targetCount) : Math.max(sourceCount, targetCount);
            var restIndex = sourceRestType || targetRestType ? paramCount - 1 : -1;
            for (var i = 0; i < paramCount; i++) {
                var sourceType = i === restIndex ? getRestTypeAtPosition(source, i) : getTypeAtPosition(source, i);
                var targetType = i === restIndex ? getRestTypeAtPosition(target, i) : getTypeAtPosition(target, i);
                // In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
                // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
                // they naturally relate only contra-variantly). However, if the source and target parameters both have
                // function types with a single call signature, we know we are relating two callback parameters. In
                // that case it is sufficient to only relate the parameters of the signatures co-variantly because,
                // similar to return values, callback parameters are output positions. This means that a Promise<T>,
                // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant)
                // with respect to T.
                var sourceSig = checkMode & 3 /* Callback */ ? undefined : getSingleCallSignature(getNonNullableType(sourceType));
                var targetSig = checkMode & 3 /* Callback */ ? undefined : getSingleCallSignature(getNonNullableType(targetType));
                var callbacks = sourceSig && targetSig && !getTypePredicateOfSignature(sourceSig) && !getTypePredicateOfSignature(targetSig) &&
                    (getFalsyFlags(sourceType) & 98304 /* Nullable */) === (getFalsyFlags(targetType) & 98304 /* Nullable */);
                var related = callbacks ?
                    compareSignaturesRelated(targetSig, sourceSig, (checkMode & 8 /* StrictArity */) | (strictVariance ? 2 /* StrictCallback */ : 1 /* BivariantCallback */), reportErrors, errorReporter, incompatibleErrorReporter, compareTypes, reportUnreliableMarkers) :
                    !(checkMode & 3 /* Callback */) && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors);
                // With strict arity, (x: number | undefined) => void is a subtype of (x?: number | undefined) => void
                if (related && checkMode & 8 /* StrictArity */ && i >= getMinArgumentCount(source) && i < getMinArgumentCount(target) && compareTypes(sourceType, targetType, /*reportErrors*/ false)) {
                    related = 0 /* False */;
                }
                if (!related) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, ts.unescapeLeadingUnderscores(getParameterNameAtPosition(source, i)), ts.unescapeLeadingUnderscores(getParameterNameAtPosition(target, i)));
                    }
                    return 0 /* False */;
                }
                result &= related;
            }
            if (!(checkMode & 4 /* IgnoreReturnTypes */)) {
                // If a signature resolution is already in-flight, skip issuing a circularity error
                // here and just use the `any` type directly
                var targetReturnType = isResolvingReturnTypeOfSignature(target) ? anyType
                    : target.declaration && isJSConstructor(target.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(target.declaration.symbol))
                        : getReturnTypeOfSignature(target);
                if (targetReturnType === voidType) {
                    return result;
                }
                var sourceReturnType = isResolvingReturnTypeOfSignature(source) ? anyType
                    : source.declaration && isJSConstructor(source.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(source.declaration.symbol))
                        : getReturnTypeOfSignature(source);
                // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions
                var targetTypePredicate = getTypePredicateOfSignature(target);
                if (targetTypePredicate) {
                    var sourceTypePredicate = getTypePredicateOfSignature(source);
                    if (sourceTypePredicate) {
                        result &= compareTypePredicateRelatedTo(sourceTypePredicate, targetTypePredicate, reportErrors, errorReporter, compareTypes);
                    }
                    else if (ts.isIdentifierTypePredicate(targetTypePredicate)) {
                        if (reportErrors) {
                            errorReporter(ts.Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source));
                        }
                        return 0 /* False */;
                    }
                }
                else {
                    // When relating callback signatures, we still need to relate return types bi-variantly as otherwise
                    // the containing type wouldn't be co-variant. For example, interface Foo<T> { add(cb: () => T): void }
                    // wouldn't be co-variant for T without this rule.
                    result &= checkMode & 1 /* BivariantCallback */ && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) ||
                        compareTypes(sourceReturnType, targetReturnType, reportErrors);
                    if (!result && reportErrors && incompatibleErrorReporter) {
                        incompatibleErrorReporter(sourceReturnType, targetReturnType);
                    }
                }
            }
            return result;
        }
        function compareTypePredicateRelatedTo(source, target, reportErrors, errorReporter, compareTypes) {
            if (source.kind !== target.kind) {
                if (reportErrors) {
                    errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard);
                    errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
                }
                return 0 /* False */;
            }
            if (source.kind === 1 /* Identifier */ || source.kind === 3 /* AssertsIdentifier */) {
                if (source.parameterIndex !== target.parameterIndex) {
                    if (reportErrors) {
                        errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, source.parameterName, target.parameterName);
                        errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
                    }
                    return 0 /* False */;
                }
            }
            var related = source.type === target.type ? -1 /* True */ :
                source.type && target.type ? compareTypes(source.type, target.type, reportErrors) :
                    0 /* False */;
            if (related === 0 /* False */ && reportErrors) {
                errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target));
            }
            return related;
        }
        function isImplementationCompatibleWithOverload(implementation, overload) {
            var erasedSource = getErasedSignature(implementation);
            var erasedTarget = getErasedSignature(overload);
            // First see if the return types are compatible in either direction.
            var sourceReturnType = getReturnTypeOfSignature(erasedSource);
            var targetReturnType = getReturnTypeOfSignature(erasedTarget);
            if (targetReturnType === voidType
                || isTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation)
                || isTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation)) {
                return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true);
            }
            return false;
        }
        function isEmptyResolvedType(t) {
            return t !== anyFunctionType &&
                t.properties.length === 0 &&
                t.callSignatures.length === 0 &&
                t.constructSignatures.length === 0 &&
                !t.stringIndexInfo &&
                !t.numberIndexInfo;
        }
        function isEmptyObjectType(type) {
            return type.flags & 524288 /* Object */ ? !isGenericMappedType(type) && isEmptyResolvedType(resolveStructuredTypeMembers(type)) :
                type.flags & 67108864 /* NonPrimitive */ ? true :
                    type.flags & 1048576 /* Union */ ? ts.some(type.types, isEmptyObjectType) :
                        type.flags & 2097152 /* Intersection */ ? ts.every(type.types, isEmptyObjectType) :
                            false;
        }
        function isEmptyAnonymousObjectType(type) {
            return !!(ts.getObjectFlags(type) & 16 /* Anonymous */) && isEmptyObjectType(type);
        }
        function isStringIndexSignatureOnlyType(type) {
            return type.flags & 524288 /* Object */ && !isGenericMappedType(type) && getPropertiesOfType(type).length === 0 && getIndexInfoOfType(type, 0 /* String */) && !getIndexInfoOfType(type, 1 /* Number */) ||
                type.flags & 3145728 /* UnionOrIntersection */ && ts.every(type.types, isStringIndexSignatureOnlyType) ||
                false;
        }
        function isEnumTypeRelatedTo(sourceSymbol, targetSymbol, errorReporter) {
            if (sourceSymbol === targetSymbol) {
                return true;
            }
            var id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol);
            var entry = enumRelation.get(id);
            if (entry !== undefined && !(!(entry & 4 /* Reported */) && entry & 2 /* Failed */ && errorReporter)) {
                return !!(entry & 1 /* Succeeded */);
            }
            if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & 256 /* RegularEnum */) || !(targetSymbol.flags & 256 /* RegularEnum */)) {
                enumRelation.set(id, 2 /* Failed */ | 4 /* Reported */);
                return false;
            }
            var targetEnumType = getTypeOfSymbol(targetSymbol);
            for (var _i = 0, _a = getPropertiesOfType(getTypeOfSymbol(sourceSymbol)); _i < _a.length; _i++) {
                var property = _a[_i];
                if (property.flags & 8 /* EnumMember */) {
                    var targetProperty = getPropertyOfType(targetEnumType, property.escapedName);
                    if (!targetProperty || !(targetProperty.flags & 8 /* EnumMember */)) {
                        if (errorReporter) {
                            errorReporter(ts.Diagnostics.Property_0_is_missing_in_type_1, ts.symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, 64 /* UseFullyQualifiedType */));
                            enumRelation.set(id, 2 /* Failed */ | 4 /* Reported */);
                        }
                        else {
                            enumRelation.set(id, 2 /* Failed */);
                        }
                        return false;
                    }
                }
            }
            enumRelation.set(id, 1 /* Succeeded */);
            return true;
        }
        function isSimpleTypeRelatedTo(source, target, relation, errorReporter) {
            var s = source.flags;
            var t = target.flags;
            if (t & 3 /* AnyOrUnknown */ || s & 131072 /* Never */ || source === wildcardType)
                return true;
            if (t & 131072 /* Never */)
                return false;
            if (s & 132 /* StringLike */ && t & 4 /* String */)
                return true;
            if (s & 128 /* StringLiteral */ && s & 1024 /* EnumLiteral */ &&
                t & 128 /* StringLiteral */ && !(t & 1024 /* EnumLiteral */) &&
                source.value === target.value)
                return true;
            if (s & 296 /* NumberLike */ && t & 8 /* Number */)
                return true;
            if (s & 256 /* NumberLiteral */ && s & 1024 /* EnumLiteral */ &&
                t & 256 /* NumberLiteral */ && !(t & 1024 /* EnumLiteral */) &&
                source.value === target.value)
                return true;
            if (s & 2112 /* BigIntLike */ && t & 64 /* BigInt */)
                return true;
            if (s & 528 /* BooleanLike */ && t & 16 /* Boolean */)
                return true;
            if (s & 12288 /* ESSymbolLike */ && t & 4096 /* ESSymbol */)
                return true;
            if (s & 32 /* Enum */ && t & 32 /* Enum */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
                return true;
            if (s & 1024 /* EnumLiteral */ && t & 1024 /* EnumLiteral */) {
                if (s & 1048576 /* Union */ && t & 1048576 /* Union */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter))
                    return true;
                if (s & 2944 /* Literal */ && t & 2944 /* Literal */ &&
                    source.value === target.value &&
                    isEnumTypeRelatedTo(getParentOfSymbol(source.symbol), getParentOfSymbol(target.symbol), errorReporter))
                    return true;
            }
            if (s & 32768 /* Undefined */ && (!strictNullChecks || t & (32768 /* Undefined */ | 16384 /* Void */)))
                return true;
            if (s & 65536 /* Null */ && (!strictNullChecks || t & 65536 /* Null */))
                return true;
            if (s & 524288 /* Object */ && t & 67108864 /* NonPrimitive */)
                return true;
            if (relation === assignableRelation || relation === comparableRelation) {
                if (s & 1 /* Any */)
                    return true;
                // Type number or any numeric literal type is assignable to any numeric enum type or any
                // numeric enum literal type. This rule exists for backwards compatibility reasons because
                // bit-flag enum types sometimes look like literal enum types with numeric literal values.
                if (s & (8 /* Number */ | 256 /* NumberLiteral */) && !(s & 1024 /* EnumLiteral */) && (t & 32 /* Enum */ || t & 256 /* NumberLiteral */ && t & 1024 /* EnumLiteral */))
                    return true;
            }
            return false;
        }
        function isTypeRelatedTo(source, target, relation) {
            if (isFreshLiteralType(source)) {
                source = source.regularType;
            }
            if (isFreshLiteralType(target)) {
                target = target.regularType;
            }
            if (source === target) {
                return true;
            }
            if (relation !== identityRelation) {
                if (relation === comparableRelation && !(target.flags & 131072 /* Never */) && isSimpleTypeRelatedTo(target, source, relation) || isSimpleTypeRelatedTo(source, target, relation)) {
                    return true;
                }
            }
            else {
                if (!(source.flags & 3145728 /* UnionOrIntersection */) && !(target.flags & 3145728 /* UnionOrIntersection */) &&
                    source.flags !== target.flags && !(source.flags & 66584576 /* Substructure */))
                    return false;
            }
            if (source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */) {
                var related = relation.get(getRelationKey(source, target, 0 /* None */, relation));
                if (related !== undefined) {
                    return !!(related & 1 /* Succeeded */);
                }
            }
            if (source.flags & 66846720 /* StructuredOrInstantiable */ || target.flags & 66846720 /* StructuredOrInstantiable */) {
                return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined);
            }
            return false;
        }
        function isIgnoredJsxProperty(source, sourceProp) {
            return ts.getObjectFlags(source) & 4096 /* JsxAttributes */ && !isUnhyphenatedJsxName(sourceProp.escapedName);
        }
        function getNormalizedType(type, writing) {
            while (true) {
                var t = isFreshLiteralType(type) ? type.regularType :
                    ts.getObjectFlags(type) & 4 /* Reference */ && type.node ? createTypeReference(type.target, getTypeArguments(type)) :
                        type.flags & 3145728 /* UnionOrIntersection */ ? getReducedType(type) :
                            type.flags & 33554432 /* Substitution */ ? writing ? type.baseType : type.substitute :
                                type.flags & 25165824 /* Simplifiable */ ? getSimplifiedType(type, writing) :
                                    type;
                if (t === type)
                    break;
                type = t;
            }
            return type;
        }
        /**
         * Checks if 'source' is related to 'target' (e.g.: is a assignable to).
         * @param source The left-hand-side of the relation.
         * @param target The right-hand-side of the relation.
         * @param relation The relation considered. One of 'identityRelation', 'subtypeRelation', 'assignableRelation', or 'comparableRelation'.
         * Used as both to determine which checks are performed and as a cache of previously computed results.
         * @param errorNode The suggested node upon which all errors will be reported, if defined. This may or may not be the actual node used.
         * @param headMessage If the error chain should be prepended by a head message, then headMessage will be used.
         * @param containingMessageChain A chain of errors to prepend any new errors found.
         * @param errorOutputContainer Return the diagnostic. Do not log if 'skipLogging' is truthy.
         */
        function checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer) {
            var errorInfo;
            var relatedInfo;
            var maybeKeys;
            var sourceStack;
            var targetStack;
            var maybeCount = 0;
            var depth = 0;
            var expandingFlags = 0 /* None */;
            var overflow = false;
            var overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid
            var lastSkippedInfo;
            var incompatibleStack = [];
            var inPropertyCheck = false;
            ts.Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
            var result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage);
            if (incompatibleStack.length) {
                reportIncompatibleStack();
            }
            if (overflow) {
                var diag = error(errorNode || currentNode, ts.Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
                if (errorOutputContainer) {
                    (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                }
            }
            else if (errorInfo) {
                if (containingMessageChain) {
                    var chain = containingMessageChain();
                    if (chain) {
                        ts.concatenateDiagnosticMessageChains(chain, errorInfo);
                        errorInfo = chain;
                    }
                }
                var relatedInformation = void 0;
                // Check if we should issue an extra diagnostic to produce a quickfix for a slightly incorrect import statement
                if (headMessage && errorNode && !result && source.symbol) {
                    var links = getSymbolLinks(source.symbol);
                    if (links.originatingImport && !ts.isImportCall(links.originatingImport)) {
                        var helpfulRetry = checkTypeRelatedTo(getTypeOfSymbol(links.target), target, relation, /*errorNode*/ undefined);
                        if (helpfulRetry) {
                            // Likely an incorrect import. Issue a helpful diagnostic to produce a quickfix to change the import
                            var diag_1 = ts.createDiagnosticForNode(links.originatingImport, ts.Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead);
                            relatedInformation = ts.append(relatedInformation, diag_1); // Cause the error to appear with the error that triggered it
                        }
                    }
                }
                var diag = ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo, relatedInformation);
                if (relatedInfo) {
                    ts.addRelatedInfo.apply(void 0, __spreadArrays([diag], relatedInfo));
                }
                if (errorOutputContainer) {
                    (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                }
                if (!errorOutputContainer || !errorOutputContainer.skipLogging) {
                    diagnostics.add(diag);
                }
            }
            if (errorNode && errorOutputContainer && errorOutputContainer.skipLogging && result === 0 /* False */) {
                ts.Debug.assert(!!errorOutputContainer.errors, "missed opportunity to interact with error.");
            }
            return result !== 0 /* False */;
            function resetErrorInfo(saved) {
                errorInfo = saved.errorInfo;
                lastSkippedInfo = saved.lastSkippedInfo;
                incompatibleStack = saved.incompatibleStack;
                overrideNextErrorInfo = saved.overrideNextErrorInfo;
                relatedInfo = saved.relatedInfo;
            }
            function captureErrorCalculationState() {
                return {
                    errorInfo: errorInfo,
                    lastSkippedInfo: lastSkippedInfo,
                    incompatibleStack: incompatibleStack.slice(),
                    overrideNextErrorInfo: overrideNextErrorInfo,
                    relatedInfo: !relatedInfo ? undefined : relatedInfo.slice()
                };
            }
            function reportIncompatibleError(message, arg0, arg1, arg2, arg3) {
                overrideNextErrorInfo++; // Suppress the next relation error
                lastSkippedInfo = undefined; // Reset skipped info cache
                incompatibleStack.push([message, arg0, arg1, arg2, arg3]);
            }
            function reportIncompatibleStack() {
                var stack = incompatibleStack;
                incompatibleStack = [];
                var info = lastSkippedInfo;
                lastSkippedInfo = undefined;
                if (stack.length === 1) {
                    reportError.apply(void 0, stack[0]);
                    if (info) {
                        // Actually do the last relation error
                        reportRelationError.apply(void 0, __spreadArrays([/*headMessage*/ undefined], info));
                    }
                    return;
                }
                // The first error will be the innermost, while the last will be the outermost - so by popping off the end,
                // we can build from left to right
                var path = "";
                var secondaryRootErrors = [];
                while (stack.length) {
                    var _a = stack.pop(), msg = _a[0], args = _a.slice(1);
                    switch (msg.code) {
                        case ts.Diagnostics.Types_of_property_0_are_incompatible.code: {
                            // Parenthesize a `new` if there is one
                            if (path.indexOf("new ") === 0) {
                                path = "(" + path + ")";
                            }
                            var str = "" + args[0];
                            // If leading, just print back the arg (irrespective of if it's a valid identifier)
                            if (path.length === 0) {
                                path = "" + str;
                            }
                            // Otherwise write a dotted name if possible
                            else if (ts.isIdentifierText(str, compilerOptions.target)) {
                                path = path + "." + str;
                            }
                            // Failing that, check if the name is already a computed name
                            else if (str[0] === "[" && str[str.length - 1] === "]") {
                                path = "" + path + str;
                            }
                            // And finally write out a computed name as a last resort
                            else {
                                path = path + "[" + str + "]";
                            }
                            break;
                        }
                        case ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible.code:
                        case ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code:
                        case ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code:
                        case ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code: {
                            if (path.length === 0) {
                                // Don't flatten signature compatability errors at the start of a chain - instead prefer
                                // to unify (the with no arguments bit is excessive for printback) and print them back
                                var mappedMsg = msg;
                                if (msg.code === ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) {
                                    mappedMsg = ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible;
                                }
                                else if (msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code) {
                                    mappedMsg = ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible;
                                }
                                secondaryRootErrors.unshift([mappedMsg, args[0], args[1]]);
                            }
                            else {
                                var prefix = (msg.code === ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible.code ||
                                    msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code)
                                    ? "new "
                                    : "";
                                var params = (msg.code === ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code ||
                                    msg.code === ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1.code)
                                    ? ""
                                    : "...";
                                path = "" + prefix + path + "(" + params + ")";
                            }
                            break;
                        }
                        default:
                            return ts.Debug.fail("Unhandled Diagnostic: " + msg.code);
                    }
                }
                if (path) {
                    reportError(path[path.length - 1] === ")"
                        ? ts.Diagnostics.The_types_returned_by_0_are_incompatible_between_these_types
                        : ts.Diagnostics.The_types_of_0_are_incompatible_between_these_types, path);
                }
                else {
                    // Remove the innermost secondary error as it will duplicate the error already reported by `reportRelationError` on entry
                    secondaryRootErrors.shift();
                }
                for (var _i = 0, secondaryRootErrors_1 = secondaryRootErrors; _i < secondaryRootErrors_1.length; _i++) {
                    var _b = secondaryRootErrors_1[_i], msg = _b[0], args = _b.slice(1);
                    var originalValue = msg.elidedInCompatabilityPyramid;
                    msg.elidedInCompatabilityPyramid = false; // Teporarily override elision to ensure error is reported
                    reportError.apply(void 0, __spreadArrays([msg], args));
                    msg.elidedInCompatabilityPyramid = originalValue;
                }
                if (info) {
                    // Actually do the last relation error
                    reportRelationError.apply(void 0, __spreadArrays([/*headMessage*/ undefined], info));
                }
            }
            function reportError(message, arg0, arg1, arg2, arg3) {
                ts.Debug.assert(!!errorNode);
                if (incompatibleStack.length)
                    reportIncompatibleStack();
                if (message.elidedInCompatabilityPyramid)
                    return;
                errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2, arg3);
            }
            function associateRelatedInfo(info) {
                ts.Debug.assert(!!errorInfo);
                if (!relatedInfo) {
                    relatedInfo = [info];
                }
                else {
                    relatedInfo.push(info);
                }
            }
            function reportRelationError(message, source, target) {
                if (incompatibleStack.length)
                    reportIncompatibleStack();
                var _a = getTypeNamesForErrorDisplay(source, target), sourceType = _a[0], targetType = _a[1];
                if (target.flags & 262144 /* TypeParameter */) {
                    var constraint = getBaseConstraintOfType(target);
                    var constraintElab = constraint && isTypeAssignableTo(source, constraint);
                    if (constraintElab) {
                        reportError(ts.Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2, sourceType, targetType, typeToString(constraint));
                    }
                    else {
                        reportError(ts.Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1, targetType, sourceType);
                    }
                }
                if (!message) {
                    if (relation === comparableRelation) {
                        message = ts.Diagnostics.Type_0_is_not_comparable_to_type_1;
                    }
                    else if (sourceType === targetType) {
                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated;
                    }
                    else {
                        message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1;
                    }
                }
                reportError(message, sourceType, targetType);
            }
            function tryElaborateErrorsForPrimitivesAndObjects(source, target) {
                var sourceType = symbolValueDeclarationIsContextSensitive(source.symbol) ? typeToString(source, source.symbol.valueDeclaration) : typeToString(source);
                var targetType = symbolValueDeclarationIsContextSensitive(target.symbol) ? typeToString(target, target.symbol.valueDeclaration) : typeToString(target);
                if ((globalStringType === source && stringType === target) ||
                    (globalNumberType === source && numberType === target) ||
                    (globalBooleanType === source && booleanType === target) ||
                    (getGlobalESSymbolType(/*reportErrors*/ false) === source && esSymbolType === target)) {
                    reportError(ts.Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType);
                }
            }
            /**
             * Try and elaborate array and tuple errors. Returns false
             * if we have found an elaboration, or we should ignore
             * any other elaborations when relating the `source` and
             * `target` types.
             */
            function tryElaborateArrayLikeErrors(source, target, reportErrors) {
                /**
                 * The spec for elaboration is:
                 * - If the source is a readonly tuple and the target is a mutable array or tuple, elaborate on mutability and skip property elaborations.
                 * - If the source is a tuple then skip property elaborations if the target is an array or tuple.
                 * - If the source is a readonly array and the target is a mutable array or tuple, elaborate on mutability and skip property elaborations.
                 * - If the source an array then skip property elaborations if the target is a tuple.
                 */
                if (isTupleType(source)) {
                    if (source.target.readonly && isMutableArrayOrTuple(target)) {
                        if (reportErrors) {
                            reportError(ts.Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
                        }
                        return false;
                    }
                    return isTupleType(target) || isArrayType(target);
                }
                if (isReadonlyArrayType(source) && isMutableArrayOrTuple(target)) {
                    if (reportErrors) {
                        reportError(ts.Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
                    }
                    return false;
                }
                if (isTupleType(target)) {
                    return isArrayType(source);
                }
                return true;
            }
            /**
             * Compare two types and return
             * * Ternary.True if they are related with no assumptions,
             * * Ternary.Maybe if they are related with assumptions of other relationships, or
             * * Ternary.False if they are not related.
             */
            function isRelatedTo(originalSource, originalTarget, reportErrors, headMessage, intersectionState) {
                if (reportErrors === void 0) { reportErrors = false; }
                if (intersectionState === void 0) { intersectionState = 0 /* None */; }
                // Before normalization: if `source` is type an object type, and `target` is primitive,
                // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result
                if (originalSource.flags & 524288 /* Object */ && originalTarget.flags & 131068 /* Primitive */) {
                    if (isSimpleTypeRelatedTo(originalSource, originalTarget, relation, reportErrors ? reportError : undefined)) {
                        return -1 /* True */;
                    }
                    reportErrorResults(originalSource, originalTarget, 0 /* False */, !!(ts.getObjectFlags(originalSource) & 4096 /* JsxAttributes */));
                    return 0 /* False */;
                }
                // Normalize the source and target types: Turn fresh literal types into regular literal types,
                // turn deferred type references into regular type references, simplify indexed access and
                // conditional types, and resolve substitution types to either the substitution (on the source
                // side) or the type variable (on the target side).
                var source = getNormalizedType(originalSource, /*writing*/ false);
                var target = getNormalizedType(originalTarget, /*writing*/ true);
                if (source === target)
                    return -1 /* True */;
                if (relation === identityRelation) {
                    return isIdenticalTo(source, target);
                }
                // We fastpath comparing a type parameter to exactly its constraint, as this is _super_ common,
                // and otherwise, for type parameters in large unions, causes us to need to compare the union to itself,
                // as we break down the _target_ union first, _then_ get the source constraint - so for every
                // member of the target, we attempt to find a match in the source. This avoids that in cases where
                // the target is exactly the constraint.
                if (source.flags & 262144 /* TypeParameter */ && getConstraintOfType(source) === target) {
                    return -1 /* True */;
                }
                // Try to see if we're relating something like `Foo` -> `Bar | null | undefined`.
                // If so, reporting the `null` and `undefined` in the type is hardly useful.
                // First, see if we're even relating an object type to a union.
                // Then see if the target is stripped down to a single non-union type.
                // Note
                //  * We actually want to remove null and undefined naively here (rather than using getNonNullableType),
                //    since we don't want to end up with a worse error like "`Foo` is not assignable to `NonNullable<T>`"
                //    when dealing with generics.
                //  * We also don't deal with primitive source types, since we already halt elaboration below.
                if (target.flags & 1048576 /* Union */ && source.flags & 524288 /* Object */ &&
                    target.types.length <= 3 && maybeTypeOfKind(target, 98304 /* Nullable */)) {
                    var nullStrippedTarget = extractTypesOfKind(target, ~98304 /* Nullable */);
                    if (!(nullStrippedTarget.flags & (1048576 /* Union */ | 131072 /* Never */))) {
                        if (source === nullStrippedTarget)
                            return -1 /* True */;
                        target = nullStrippedTarget;
                    }
                }
                if (relation === comparableRelation && !(target.flags & 131072 /* Never */) && isSimpleTypeRelatedTo(target, source, relation) ||
                    isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined))
                    return -1 /* True */;
                var isComparingJsxAttributes = !!(ts.getObjectFlags(source) & 4096 /* JsxAttributes */);
                var isPerformingExcessPropertyChecks = !(intersectionState & 2 /* Target */) && (isObjectLiteralType(source) && ts.getObjectFlags(source) & 32768 /* FreshLiteral */);
                if (isPerformingExcessPropertyChecks) {
                    if (hasExcessProperties(source, target, reportErrors)) {
                        if (reportErrors) {
                            reportRelationError(headMessage, source, target);
                        }
                        return 0 /* False */;
                    }
                }
                var isPerformingCommonPropertyChecks = relation !== comparableRelation && !(intersectionState & 2 /* Target */) &&
                    source.flags & (131068 /* Primitive */ | 524288 /* Object */ | 2097152 /* Intersection */) && source !== globalObjectType &&
                    target.flags & (524288 /* Object */ | 2097152 /* Intersection */) && isWeakType(target) &&
                    (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source));
                if (isPerformingCommonPropertyChecks && !hasCommonProperties(source, target, isComparingJsxAttributes)) {
                    if (reportErrors) {
                        var calls = getSignaturesOfType(source, 0 /* Call */);
                        var constructs = getSignaturesOfType(source, 1 /* Construct */);
                        if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) ||
                            constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) {
                            reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target));
                        }
                        else {
                            reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target));
                        }
                    }
                    return 0 /* False */;
                }
                var result = 0 /* False */;
                var saveErrorInfo = captureErrorCalculationState();
                // Note that these checks are specifically ordered to produce correct results. In particular,
                // we need to deconstruct unions before intersections (because unions are always at the top),
                // and we need to handle "each" relations before "some" relations for the same kind of type.
                if (source.flags & 1048576 /* Union */) {
                    result = relation === comparableRelation ?
                        someTypeRelatedToType(source, target, reportErrors && !(source.flags & 131068 /* Primitive */), intersectionState) :
                        eachTypeRelatedToType(source, target, reportErrors && !(source.flags & 131068 /* Primitive */), intersectionState);
                }
                else {
                    if (target.flags & 1048576 /* Union */) {
                        result = typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), target, reportErrors && !(source.flags & 131068 /* Primitive */) && !(target.flags & 131068 /* Primitive */));
                    }
                    else if (target.flags & 2097152 /* Intersection */) {
                        result = typeRelatedToEachType(getRegularTypeOfObjectLiteral(source), target, reportErrors, 2 /* Target */);
                    }
                    else if (source.flags & 2097152 /* Intersection */) {
                        // Check to see if any constituents of the intersection are immediately related to the target.
                        //
                        // Don't report errors though. Checking whether a constituent is related to the source is not actually
                        // useful and leads to some confusing error messages. Instead it is better to let the below checks
                        // take care of this, or to not elaborate at all. For instance,
                        //
                        //    - For an object type (such as 'C = A & B'), users are usually more interested in structural errors.
                        //
                        //    - For a union type (such as '(A | B) = (C & D)'), it's better to hold onto the whole intersection
                        //          than to report that 'D' is not assignable to 'A' or 'B'.
                        //
                        //    - For a primitive type or type parameter (such as 'number = A & B') there is no point in
                        //          breaking the intersection apart.
                        result = someTypeRelatedToType(source, target, /*reportErrors*/ false, 1 /* Source */);
                    }
                    if (!result && (source.flags & 66846720 /* StructuredOrInstantiable */ || target.flags & 66846720 /* StructuredOrInstantiable */)) {
                        if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState)) {
                            resetErrorInfo(saveErrorInfo);
                        }
                    }
                }
                if (!result && source.flags & (2097152 /* Intersection */ | 262144 /* TypeParameter */)) {
                    // The combined constraint of an intersection type is the intersection of the constraints of
                    // the constituents. When an intersection type contains instantiable types with union type
                    // constraints, there are situations where we need to examine the combined constraint. One is
                    // when the target is a union type. Another is when the intersection contains types belonging
                    // to one of the disjoint domains. For example, given type variables T and U, each with the
                    // constraint 'string | number', the combined constraint of 'T & U' is 'string | number' and
                    // we need to check this constraint against a union on the target side. Also, given a type
                    // variable V constrained to 'string | number', 'V & number' has a combined constraint of
                    // 'string & number | number & number' which reduces to just 'number'.
                    // This also handles type parameters, as a type parameter with a union constraint compared against a union
                    // needs to have its constraint hoisted into an intersection with said type parameter, this way
                    // the type param can be compared with itself in the target (with the influence of its constraint to match other parts)
                    // For example, if `T extends 1 | 2` and `U extends 2 | 3` and we compare `T & U` to `T & U & (1 | 2 | 3)`
                    var constraint = getEffectiveConstraintOfIntersection(source.flags & 2097152 /* Intersection */ ? source.types : [source], !!(target.flags & 1048576 /* Union */));
                    if (constraint && (source.flags & 2097152 /* Intersection */ || target.flags & 1048576 /* Union */)) {
                        if (everyType(constraint, function (c) { return c !== source; })) { // Skip comparison if expansion contains the source itself
                            // TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this
                            if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
                                resetErrorInfo(saveErrorInfo);
                            }
                        }
                    }
                }
                // For certain combinations involving intersections and optional, excess, or mismatched properties we need
                // an extra property check where the intersection is viewed as a single object. The following are motivating
                // examples that all should be errors, but aren't without this extra property check:
                //
                //   let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 };  // Nested excess property
                //
                //   declare let wrong: { a: { y: string } };
                //   let weak: { a?: { x?: number } } & { c?: string } = wrong;  // Nested weak object type
                //
                //   function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
                //     x = y;  // Mismatched property in source intersection
                //   }
                //
                // We suppress recursive intersection property checks because they can generate lots of work when relating
                // recursive intersections that are structurally similar but not exactly identical. See #37854.
                if (result && !inPropertyCheck && (target.flags & 2097152 /* Intersection */ && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
                    isNonGenericObjectType(target) && !isArrayType(target) && !isTupleType(target) && source.flags & 2097152 /* Intersection */ && getApparentType(source).flags & 3670016 /* StructuredType */ && !ts.some(source.types, function (t) { return !!(ts.getObjectFlags(t) & 2097152 /* NonInferrableType */); }))) {
                    inPropertyCheck = true;
                    result &= recursiveTypeRelatedTo(source, target, reportErrors, 4 /* PropertyCheck */);
                    inPropertyCheck = false;
                }
                reportErrorResults(source, target, result, isComparingJsxAttributes);
                return result;
                function reportErrorResults(source, target, result, isComparingJsxAttributes) {
                    if (!result && reportErrors) {
                        source = originalSource.aliasSymbol ? originalSource : source;
                        target = originalTarget.aliasSymbol ? originalTarget : target;
                        var maybeSuppress = overrideNextErrorInfo > 0;
                        if (maybeSuppress) {
                            overrideNextErrorInfo--;
                        }
                        if (source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */) {
                            var currentError = errorInfo;
                            tryElaborateArrayLikeErrors(source, target, reportErrors);
                            if (errorInfo !== currentError) {
                                maybeSuppress = !!errorInfo;
                            }
                        }
                        if (source.flags & 524288 /* Object */ && target.flags & 131068 /* Primitive */) {
                            tryElaborateErrorsForPrimitivesAndObjects(source, target);
                        }
                        else if (source.symbol && source.flags & 524288 /* Object */ && globalObjectType === source) {
                            reportError(ts.Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead);
                        }
                        else if (isComparingJsxAttributes && target.flags & 2097152 /* Intersection */) {
                            var targetTypes = target.types;
                            var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode);
                            var intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode);
                            if (intrinsicAttributes !== errorType && intrinsicClassAttributes !== errorType &&
                                (ts.contains(targetTypes, intrinsicAttributes) || ts.contains(targetTypes, intrinsicClassAttributes))) {
                                // do not report top error
                                return result;
                            }
                        }
                        else {
                            errorInfo = elaborateNeverIntersection(errorInfo, originalTarget);
                        }
                        if (!headMessage && maybeSuppress) {
                            lastSkippedInfo = [source, target];
                            // Used by, eg, missing property checking to replace the top-level message with a more informative one
                            return result;
                        }
                        reportRelationError(headMessage, source, target);
                    }
                }
            }
            function isIdenticalTo(source, target) {
                var flags = source.flags & target.flags;
                if (!(flags & 66584576 /* Substructure */)) {
                    return 0 /* False */;
                }
                if (flags & 3145728 /* UnionOrIntersection */) {
                    var result_5 = eachTypeRelatedToSomeType(source, target);
                    if (result_5) {
                        result_5 &= eachTypeRelatedToSomeType(target, source);
                    }
                    return result_5;
                }
                return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, 0 /* None */);
            }
            function getTypeOfPropertyInTypes(types, name) {
                var appendPropType = function (propTypes, type) {
                    type = getApparentType(type);
                    var prop = type.flags & 3145728 /* UnionOrIntersection */ ? getPropertyOfUnionOrIntersectionType(type, name) : getPropertyOfObjectType(type, name);
                    var propType = prop && getTypeOfSymbol(prop) || isNumericLiteralName(name) && getIndexTypeOfType(type, 1 /* Number */) || getIndexTypeOfType(type, 0 /* String */) || undefinedType;
                    return ts.append(propTypes, propType);
                };
                return getUnionType(ts.reduceLeft(types, appendPropType, /*initial*/ undefined) || ts.emptyArray);
            }
            function hasExcessProperties(source, target, reportErrors) {
                if (!isExcessPropertyCheckTarget(target) || !noImplicitAny && ts.getObjectFlags(target) & 16384 /* JSLiteral */) {
                    return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny
                }
                var isComparingJsxAttributes = !!(ts.getObjectFlags(source) & 4096 /* JsxAttributes */);
                if ((relation === assignableRelation || relation === comparableRelation) &&
                    (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) {
                    return false;
                }
                var reducedTarget = target;
                var checkTypes;
                if (target.flags & 1048576 /* Union */) {
                    reducedTarget = findMatchingDiscriminantType(source, target, isRelatedTo) || filterPrimitivesIfContainsNonPrimitive(target);
                    checkTypes = reducedTarget.flags & 1048576 /* Union */ ? reducedTarget.types : [reducedTarget];
                }
                var _loop_13 = function (prop) {
                    if (shouldCheckAsExcessProperty(prop, source.symbol) && !isIgnoredJsxProperty(source, prop)) {
                        if (!isKnownProperty(reducedTarget, prop.escapedName, isComparingJsxAttributes)) {
                            if (reportErrors) {
                                // Report error in terms of object types in the target as those are the only ones
                                // we check in isKnownProperty.
                                var errorTarget = filterType(reducedTarget, isExcessPropertyCheckTarget);
                                // We know *exactly* where things went wrong when comparing the types.
                                // Use this property as the error node as this will be more helpful in
                                // reasoning about what went wrong.
                                if (!errorNode)
                                    return { value: ts.Debug.fail() };
                                if (ts.isJsxAttributes(errorNode) || ts.isJsxOpeningLikeElement(errorNode) || ts.isJsxOpeningLikeElement(errorNode.parent)) {
                                    // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal.
                                    // However, using an object-literal error message will be very confusing to the users so we give different a message.
                                    // TODO: Spelling suggestions for excess jsx attributes (needs new diagnostic messages)
                                    if (prop.valueDeclaration && ts.isJsxAttribute(prop.valueDeclaration) && ts.getSourceFileOfNode(errorNode) === ts.getSourceFileOfNode(prop.valueDeclaration.name)) {
                                        // Note that extraneous children (as in `<NoChild>extra</NoChild>`) don't pass this check,
                                        // since `children` is a SyntaxKind.PropertySignature instead of a SyntaxKind.JsxAttribute.
                                        errorNode = prop.valueDeclaration.name;
                                    }
                                    reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(errorTarget));
                                }
                                else {
                                    // use the property's value declaration if the property is assigned inside the literal itself
                                    var objectLiteralDeclaration_1 = source.symbol && ts.firstOrUndefined(source.symbol.declarations);
                                    var suggestion = void 0;
                                    if (prop.valueDeclaration && ts.findAncestor(prop.valueDeclaration, function (d) { return d === objectLiteralDeclaration_1; }) && ts.getSourceFileOfNode(objectLiteralDeclaration_1) === ts.getSourceFileOfNode(errorNode)) {
                                        var propDeclaration = prop.valueDeclaration;
                                        ts.Debug.assertNode(propDeclaration, ts.isObjectLiteralElementLike);
                                        errorNode = propDeclaration;
                                        var name = propDeclaration.name;
                                        if (ts.isIdentifier(name)) {
                                            suggestion = getSuggestionForNonexistentProperty(name, errorTarget);
                                        }
                                    }
                                    if (suggestion !== undefined) {
                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, symbolToString(prop), typeToString(errorTarget), suggestion);
                                    }
                                    else {
                                        reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(errorTarget));
                                    }
                                }
                            }
                            return { value: true };
                        }
                        if (checkTypes && !isRelatedTo(getTypeOfSymbol(prop), getTypeOfPropertyInTypes(checkTypes, prop.escapedName), reportErrors)) {
                            if (reportErrors) {
                                reportIncompatibleError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(prop));
                            }
                            return { value: true };
                        }
                    }
                };
                for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                    var prop = _a[_i];
                    var state_5 = _loop_13(prop);
                    if (typeof state_5 === "object")
                        return state_5.value;
                }
                return false;
            }
            function shouldCheckAsExcessProperty(prop, container) {
                return prop.valueDeclaration && container.valueDeclaration && prop.valueDeclaration.parent === container.valueDeclaration;
            }
            function eachTypeRelatedToSomeType(source, target) {
                var result = -1 /* True */;
                var sourceTypes = source.types;
                for (var _i = 0, sourceTypes_1 = sourceTypes; _i < sourceTypes_1.length; _i++) {
                    var sourceType = sourceTypes_1[_i];
                    var related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function typeRelatedToSomeType(source, target, reportErrors) {
                var targetTypes = target.types;
                if (target.flags & 1048576 /* Union */ && containsType(targetTypes, source)) {
                    return -1 /* True */;
                }
                for (var _i = 0, targetTypes_1 = targetTypes; _i < targetTypes_1.length; _i++) {
                    var type = targetTypes_1[_i];
                    var related = isRelatedTo(source, type, /*reportErrors*/ false);
                    if (related) {
                        return related;
                    }
                }
                if (reportErrors) {
                    var bestMatchingType = getBestMatchingType(source, target, isRelatedTo);
                    isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
                }
                return 0 /* False */;
            }
            function typeRelatedToEachType(source, target, reportErrors, intersectionState) {
                var result = -1 /* True */;
                var targetTypes = target.types;
                for (var _i = 0, targetTypes_2 = targetTypes; _i < targetTypes_2.length; _i++) {
                    var targetType = targetTypes_2[_i];
                    var related = isRelatedTo(source, targetType, reportErrors, /*headMessage*/ undefined, intersectionState);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function someTypeRelatedToType(source, target, reportErrors, intersectionState) {
                var sourceTypes = source.types;
                if (source.flags & 1048576 /* Union */ && containsType(sourceTypes, target)) {
                    return -1 /* True */;
                }
                var len = sourceTypes.length;
                for (var i = 0; i < len; i++) {
                    var related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1, /*headMessage*/ undefined, intersectionState);
                    if (related) {
                        return related;
                    }
                }
                return 0 /* False */;
            }
            function eachTypeRelatedToType(source, target, reportErrors, intersectionState) {
                var result = -1 /* True */;
                var sourceTypes = source.types;
                for (var i = 0; i < sourceTypes.length; i++) {
                    var sourceType = sourceTypes[i];
                    if (target.flags & 1048576 /* Union */ && target.types.length === sourceTypes.length) {
                        // many unions are mappings of one another; in such cases, simply comparing members at the same index can shortcut the comparison
                        var related_1 = isRelatedTo(sourceType, target.types[i], /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
                        if (related_1) {
                            result &= related_1;
                            continue;
                        }
                    }
                    var related = isRelatedTo(sourceType, target, reportErrors, /*headMessage*/ undefined, intersectionState);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function typeArgumentsRelatedTo(sources, targets, variances, reportErrors, intersectionState) {
                if (sources === void 0) { sources = ts.emptyArray; }
                if (targets === void 0) { targets = ts.emptyArray; }
                if (variances === void 0) { variances = ts.emptyArray; }
                if (sources.length !== targets.length && relation === identityRelation) {
                    return 0 /* False */;
                }
                var length = sources.length <= targets.length ? sources.length : targets.length;
                var result = -1 /* True */;
                for (var i = 0; i < length; i++) {
                    // When variance information isn't available we default to covariance. This happens
                    // in the process of computing variance information for recursive types and when
                    // comparing 'this' type arguments.
                    var varianceFlags = i < variances.length ? variances[i] : 1 /* Covariant */;
                    var variance = varianceFlags & 7 /* VarianceMask */;
                    // We ignore arguments for independent type parameters (because they're never witnessed).
                    if (variance !== 4 /* Independent */) {
                        var s = sources[i];
                        var t = targets[i];
                        var related = -1 /* True */;
                        if (varianceFlags & 8 /* Unmeasurable */) {
                            // Even an `Unmeasurable` variance works out without a structural check if the source and target are _identical_.
                            // We can't simply assume invariance, because `Unmeasurable` marks nonlinear relations, for example, a relation tained by
                            // the `-?` modifier in a mapped type (where, no matter how the inputs are related, the outputs still might not be)
                            related = relation === identityRelation ? isRelatedTo(s, t, /*reportErrors*/ false) : compareTypesIdentical(s, t);
                        }
                        else if (variance === 1 /* Covariant */) {
                            related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState);
                        }
                        else if (variance === 2 /* Contravariant */) {
                            related = isRelatedTo(t, s, reportErrors, /*headMessage*/ undefined, intersectionState);
                        }
                        else if (variance === 3 /* Bivariant */) {
                            // In the bivariant case we first compare contravariantly without reporting
                            // errors. Then, if that doesn't succeed, we compare covariantly with error
                            // reporting. Thus, error elaboration will be based on the the covariant check,
                            // which is generally easier to reason about.
                            related = isRelatedTo(t, s, /*reportErrors*/ false);
                            if (!related) {
                                related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState);
                            }
                        }
                        else {
                            // In the invariant case we first compare covariantly, and only when that
                            // succeeds do we proceed to compare contravariantly. Thus, error elaboration
                            // will typically be based on the covariant check.
                            related = isRelatedTo(s, t, reportErrors, /*headMessage*/ undefined, intersectionState);
                            if (related) {
                                related &= isRelatedTo(t, s, reportErrors, /*headMessage*/ undefined, intersectionState);
                            }
                        }
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                return result;
            }
            // Determine if possibly recursive types are related. First, check if the result is already available in the global cache.
            // Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
            // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
            // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
            // and issue an error. Otherwise, actually compare the structure of the two types.
            function recursiveTypeRelatedTo(source, target, reportErrors, intersectionState) {
                if (overflow) {
                    return 0 /* False */;
                }
                var id = getRelationKey(source, target, intersectionState | (inPropertyCheck ? 8 /* InPropertyCheck */ : 0), relation);
                var entry = relation.get(id);
                if (entry !== undefined) {
                    if (reportErrors && entry & 2 /* Failed */ && !(entry & 4 /* Reported */)) {
                        // We are elaborating errors and the cached result is an unreported failure. The result will be reported
                        // as a failure, and should be updated as a reported failure by the bottom of this function.
                    }
                    else {
                        if (outofbandVarianceMarkerHandler) {
                            // We're in the middle of variance checking - integrate any unmeasurable/unreliable flags from this cached component
                            var saved = entry & 24 /* ReportsMask */;
                            if (saved & 8 /* ReportsUnmeasurable */) {
                                instantiateType(source, makeFunctionTypeMapper(reportUnmeasurableMarkers));
                            }
                            if (saved & 16 /* ReportsUnreliable */) {
                                instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers));
                            }
                        }
                        return entry & 1 /* Succeeded */ ? -1 /* True */ : 0 /* False */;
                    }
                }
                if (!maybeKeys) {
                    maybeKeys = [];
                    sourceStack = [];
                    targetStack = [];
                }
                else {
                    for (var i = 0; i < maybeCount; i++) {
                        // If source and target are already being compared, consider them related with assumptions
                        if (id === maybeKeys[i]) {
                            return 1 /* Maybe */;
                        }
                    }
                    if (depth === 100) {
                        overflow = true;
                        return 0 /* False */;
                    }
                }
                var maybeStart = maybeCount;
                maybeKeys[maybeCount] = id;
                maybeCount++;
                sourceStack[depth] = source;
                targetStack[depth] = target;
                depth++;
                var saveExpandingFlags = expandingFlags;
                if (!(expandingFlags & 1 /* Source */) && isDeeplyNestedType(source, sourceStack, depth))
                    expandingFlags |= 1 /* Source */;
                if (!(expandingFlags & 2 /* Target */) && isDeeplyNestedType(target, targetStack, depth))
                    expandingFlags |= 2 /* Target */;
                var originalHandler;
                var propagatingVarianceFlags = 0;
                if (outofbandVarianceMarkerHandler) {
                    originalHandler = outofbandVarianceMarkerHandler;
                    outofbandVarianceMarkerHandler = function (onlyUnreliable) {
                        propagatingVarianceFlags |= onlyUnreliable ? 16 /* ReportsUnreliable */ : 8 /* ReportsUnmeasurable */;
                        return originalHandler(onlyUnreliable);
                    };
                }
                var result = expandingFlags !== 3 /* Both */ ? structuredTypeRelatedTo(source, target, reportErrors, intersectionState) : 1 /* Maybe */;
                if (outofbandVarianceMarkerHandler) {
                    outofbandVarianceMarkerHandler = originalHandler;
                }
                expandingFlags = saveExpandingFlags;
                depth--;
                if (result) {
                    if (result === -1 /* True */ || depth === 0) {
                        // If result is definitely true, record all maybe keys as having succeeded
                        for (var i = maybeStart; i < maybeCount; i++) {
                            relation.set(maybeKeys[i], 1 /* Succeeded */ | propagatingVarianceFlags);
                        }
                        maybeCount = maybeStart;
                    }
                }
                else {
                    // A false result goes straight into global cache (when something is false under
                    // assumptions it will also be false without assumptions)
                    relation.set(id, (reportErrors ? 4 /* Reported */ : 0) | 2 /* Failed */ | propagatingVarianceFlags);
                    maybeCount = maybeStart;
                }
                return result;
            }
            function structuredTypeRelatedTo(source, target, reportErrors, intersectionState) {
                if (intersectionState & 4 /* PropertyCheck */) {
                    return propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, 0 /* None */);
                }
                var flags = source.flags & target.flags;
                if (relation === identityRelation && !(flags & 524288 /* Object */)) {
                    if (flags & 4194304 /* Index */) {
                        return isRelatedTo(source.type, target.type, /*reportErrors*/ false);
                    }
                    var result_6 = 0 /* False */;
                    if (flags & 8388608 /* IndexedAccess */) {
                        if (result_6 = isRelatedTo(source.objectType, target.objectType, /*reportErrors*/ false)) {
                            if (result_6 &= isRelatedTo(source.indexType, target.indexType, /*reportErrors*/ false)) {
                                return result_6;
                            }
                        }
                    }
                    if (flags & 16777216 /* Conditional */) {
                        if (source.root.isDistributive === target.root.isDistributive) {
                            if (result_6 = isRelatedTo(source.checkType, target.checkType, /*reportErrors*/ false)) {
                                if (result_6 &= isRelatedTo(source.extendsType, target.extendsType, /*reportErrors*/ false)) {
                                    if (result_6 &= isRelatedTo(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target), /*reportErrors*/ false)) {
                                        if (result_6 &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), /*reportErrors*/ false)) {
                                            return result_6;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (flags & 33554432 /* Substitution */) {
                        return isRelatedTo(source.substitute, target.substitute, /*reportErrors*/ false);
                    }
                    return 0 /* False */;
                }
                var result;
                var originalErrorInfo;
                var varianceCheckFailed = false;
                var saveErrorInfo = captureErrorCalculationState();
                // We limit alias variance probing to only object and conditional types since their alias behavior
                // is more predictable than other, interned types, which may or may not have an alias depending on
                // the order in which things were checked.
                if (source.flags & (524288 /* Object */ | 16777216 /* Conditional */) && source.aliasSymbol &&
                    source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol &&
                    !(source.aliasTypeArgumentsContainsMarker || target.aliasTypeArgumentsContainsMarker)) {
                    var variances = getAliasVariances(source.aliasSymbol);
                    if (variances === ts.emptyArray) {
                        return 1 /* Maybe */;
                    }
                    var varianceResult = relateVariances(source.aliasTypeArguments, target.aliasTypeArguments, variances, intersectionState);
                    if (varianceResult !== undefined) {
                        return varianceResult;
                    }
                }
                if (target.flags & 262144 /* TypeParameter */) {
                    // A source type { [P in Q]: X } is related to a target type T if keyof T is related to Q and X is related to T[Q].
                    if (ts.getObjectFlags(source) & 32 /* Mapped */ && isRelatedTo(getIndexType(target), getConstraintTypeFromMappedType(source))) {
                        if (!(getMappedTypeModifiers(source) & 4 /* IncludeOptional */)) {
                            var templateType = getTemplateTypeFromMappedType(source);
                            var indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source));
                            if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) {
                                return result;
                            }
                        }
                    }
                }
                else if (target.flags & 4194304 /* Index */) {
                    // A keyof S is related to a keyof T if T is related to S.
                    if (source.flags & 4194304 /* Index */) {
                        if (result = isRelatedTo(target.type, source.type, /*reportErrors*/ false)) {
                            return result;
                        }
                    }
                    // A type S is assignable to keyof T if S is assignable to keyof C, where C is the
                    // simplified form of T or, if T doesn't simplify, the constraint of T.
                    var constraint = getSimplifiedTypeOrConstraint(target.type);
                    if (constraint) {
                        // We require Ternary.True here such that circular constraints don't cause
                        // false positives. For example, given 'T extends { [K in keyof T]: string }',
                        // 'keyof T' has itself as its constraint and produces a Ternary.Maybe when
                        // related to other types.
                        if (isRelatedTo(source, getIndexType(constraint, target.stringsOnly), reportErrors) === -1 /* True */) {
                            return -1 /* True */;
                        }
                    }
                }
                else if (target.flags & 8388608 /* IndexedAccess */) {
                    // A type S is related to a type T[K] if S is related to C, where C is the base
                    // constraint of T[K] for writing.
                    if (relation !== identityRelation) {
                        var objectType = target.objectType;
                        var indexType = target.indexType;
                        var baseObjectType = getBaseConstraintOfType(objectType) || objectType;
                        var baseIndexType = getBaseConstraintOfType(indexType) || indexType;
                        if (!isGenericObjectType(baseObjectType) && !isGenericIndexType(baseIndexType)) {
                            var accessFlags = 2 /* Writing */ | (baseObjectType !== objectType ? 1 /* NoIndexSignatures */ : 0);
                            var constraint = getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, /*accessNode*/ undefined, accessFlags);
                            if (constraint && (result = isRelatedTo(source, constraint, reportErrors))) {
                                return result;
                            }
                        }
                    }
                }
                else if (isGenericMappedType(target)) {
                    // A source type T is related to a target type { [P in X]: T[P] }
                    var template = getTemplateTypeFromMappedType(target);
                    var modifiers = getMappedTypeModifiers(target);
                    if (!(modifiers & 8 /* ExcludeOptional */)) {
                        if (template.flags & 8388608 /* IndexedAccess */ && template.objectType === source &&
                            template.indexType === getTypeParameterFromMappedType(target)) {
                            return -1 /* True */;
                        }
                        if (!isGenericMappedType(source)) {
                            var targetConstraint = getConstraintTypeFromMappedType(target);
                            var sourceKeys = getIndexType(source, /*stringsOnly*/ undefined, /*noIndexSignatures*/ true);
                            var includeOptional = modifiers & 4 /* IncludeOptional */;
                            var filteredByApplicability = includeOptional ? intersectTypes(targetConstraint, sourceKeys) : undefined;
                            // A source type T is related to a target type { [P in Q]: X } if Q is related to keyof T and T[Q] is related to X.
                            // A source type T is related to a target type { [P in Q]?: X } if some constituent Q' of Q is related to keyof T and T[Q'] is related to X.
                            if (includeOptional
                                ? !(filteredByApplicability.flags & 131072 /* Never */)
                                : isRelatedTo(targetConstraint, sourceKeys)) {
                                var typeParameter = getTypeParameterFromMappedType(target);
                                var indexingType = filteredByApplicability ? getIntersectionType([filteredByApplicability, typeParameter]) : typeParameter;
                                var indexedAccessType = getIndexedAccessType(source, indexingType);
                                var templateType = getTemplateTypeFromMappedType(target);
                                if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
                                    return result;
                                }
                            }
                            originalErrorInfo = errorInfo;
                            resetErrorInfo(saveErrorInfo);
                        }
                    }
                }
                if (source.flags & 8650752 /* TypeVariable */) {
                    if (source.flags & 8388608 /* IndexedAccess */ && target.flags & 8388608 /* IndexedAccess */) {
                        // A type S[K] is related to a type T[J] if S is related to T and K is related to J.
                        if (result = isRelatedTo(source.objectType, target.objectType, reportErrors)) {
                            result &= isRelatedTo(source.indexType, target.indexType, reportErrors);
                        }
                        if (result) {
                            resetErrorInfo(saveErrorInfo);
                            return result;
                        }
                    }
                    else {
                        var constraint = getConstraintOfType(source);
                        if (!constraint || (source.flags & 262144 /* TypeParameter */ && constraint.flags & 1 /* Any */)) {
                            // A type variable with no constraint is not related to the non-primitive object type.
                            if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~67108864 /* NonPrimitive */))) {
                                resetErrorInfo(saveErrorInfo);
                                return result;
                            }
                        }
                        // hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
                        else if (result = isRelatedTo(constraint, target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
                            resetErrorInfo(saveErrorInfo);
                            return result;
                        }
                        // slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
                        else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, reportErrors, /*headMessage*/ undefined, intersectionState)) {
                            resetErrorInfo(saveErrorInfo);
                            return result;
                        }
                    }
                }
                else if (source.flags & 4194304 /* Index */) {
                    if (result = isRelatedTo(keyofConstraintType, target, reportErrors)) {
                        resetErrorInfo(saveErrorInfo);
                        return result;
                    }
                }
                else if (source.flags & 16777216 /* Conditional */) {
                    if (target.flags & 16777216 /* Conditional */) {
                        // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if
                        // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2,
                        // and Y1 is related to Y2.
                        var sourceParams = source.root.inferTypeParameters;
                        var sourceExtends = source.extendsType;
                        var mapper = void 0;
                        if (sourceParams) {
                            // If the source has infer type parameters, we instantiate them in the context of the target
                            var ctx = createInferenceContext(sourceParams, /*signature*/ undefined, 0 /* None */, isRelatedTo);
                            inferTypes(ctx.inferences, target.extendsType, sourceExtends, 128 /* NoConstraints */ | 256 /* AlwaysStrict */);
                            sourceExtends = instantiateType(sourceExtends, ctx.mapper);
                            mapper = ctx.mapper;
                        }
                        if (isTypeIdenticalTo(sourceExtends, target.extendsType) &&
                            (isRelatedTo(source.checkType, target.checkType) || isRelatedTo(target.checkType, source.checkType))) {
                            if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source), mapper), getTrueTypeFromConditionalType(target), reportErrors)) {
                                result &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), reportErrors);
                            }
                            if (result) {
                                resetErrorInfo(saveErrorInfo);
                                return result;
                            }
                        }
                    }
                    else {
                        // conditionals aren't related to one another via distributive constraint as it is much too inaccurate and allows way
                        // more assignments than are desirable (since it maps the source check type to its constraint, it loses information)
                        var distributiveConstraint = getConstraintOfDistributiveConditionalType(source);
                        if (distributiveConstraint) {
                            if (result = isRelatedTo(distributiveConstraint, target, reportErrors)) {
                                resetErrorInfo(saveErrorInfo);
                                return result;
                            }
                        }
                    }
                    // conditionals _can_ be related to one another via normal constraint, as, eg, `A extends B ? O : never` should be assignable to `O`
                    // when `O` is a conditional (`never` is trivially aissgnable to `O`, as is `O`!).
                    var defaultConstraint = getDefaultConstraintOfConditionalType(source);
                    if (defaultConstraint) {
                        if (result = isRelatedTo(defaultConstraint, target, reportErrors)) {
                            resetErrorInfo(saveErrorInfo);
                            return result;
                        }
                    }
                }
                else {
                    // An empty object type is related to any mapped type that includes a '?' modifier.
                    if (relation !== subtypeRelation && relation !== strictSubtypeRelation && isPartialMappedType(target) && isEmptyObjectType(source)) {
                        return -1 /* True */;
                    }
                    if (isGenericMappedType(target)) {
                        if (isGenericMappedType(source)) {
                            if (result = mappedTypeRelatedTo(source, target, reportErrors)) {
                                resetErrorInfo(saveErrorInfo);
                                return result;
                            }
                        }
                        return 0 /* False */;
                    }
                    var sourceIsPrimitive = !!(source.flags & 131068 /* Primitive */);
                    if (relation !== identityRelation) {
                        source = getApparentType(source);
                    }
                    else if (isGenericMappedType(source)) {
                        return 0 /* False */;
                    }
                    if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && source.target === target.target &&
                        !(ts.getObjectFlags(source) & 8192 /* MarkerType */ || ts.getObjectFlags(target) & 8192 /* MarkerType */)) {
                        // We have type references to the same generic type, and the type references are not marker
                        // type references (which are intended by be compared structurally). Obtain the variance
                        // information for the type parameters and relate the type arguments accordingly.
                        var variances = getVariances(source.target);
                        // We return Ternary.Maybe for a recursive invocation of getVariances (signalled by emptyArray). This
                        // effectively means we measure variance only from type parameter occurrences that aren't nested in
                        // recursive instantiations of the generic type.
                        if (variances === ts.emptyArray) {
                            return 1 /* Maybe */;
                        }
                        var varianceResult = relateVariances(getTypeArguments(source), getTypeArguments(target), variances, intersectionState);
                        if (varianceResult !== undefined) {
                            return varianceResult;
                        }
                    }
                    else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
                        if (relation !== identityRelation) {
                            return isRelatedTo(getIndexTypeOfType(source, 1 /* Number */) || anyType, getIndexTypeOfType(target, 1 /* Number */) || anyType, reportErrors);
                        }
                        else {
                            // By flags alone, we know that the `target` is a readonly array while the source is a normal array or tuple
                            // or `target` is an array and source is a tuple - in both cases the types cannot be identical, by construction
                            return 0 /* False */;
                        }
                    }
                    // Consider a fresh empty object literal type "closed" under the subtype relationship - this way `{} <- {[idx: string]: any} <- fresh({})`
                    // and not `{} <- fresh({}) <- {[idx: string]: any}`
                    else if ((relation === subtypeRelation || relation === strictSubtypeRelation) && isEmptyObjectType(target) && ts.getObjectFlags(target) & 32768 /* FreshLiteral */ && !isEmptyObjectType(source)) {
                        return 0 /* False */;
                    }
                    // Even if relationship doesn't hold for unions, intersections, or generic type references,
                    // it may hold in a structural comparison.
                    // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates
                    // to X. Failing both of those we want to check if the aggregation of A and B's members structurally
                    // relates to X. Thus, we include intersection types on the source side here.
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */) && target.flags & 524288 /* Object */) {
                        // Report structural errors only if we haven't reported any errors yet
                        var reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo.errorInfo && !sourceIsPrimitive;
                        result = propertiesRelatedTo(source, target, reportStructuralErrors, /*excludedProperties*/ undefined, intersectionState);
                        if (result) {
                            result &= signaturesRelatedTo(source, target, 0 /* Call */, reportStructuralErrors);
                            if (result) {
                                result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportStructuralErrors);
                                if (result) {
                                    result &= indexTypesRelatedTo(source, target, 0 /* String */, sourceIsPrimitive, reportStructuralErrors, intersectionState);
                                    if (result) {
                                        result &= indexTypesRelatedTo(source, target, 1 /* Number */, sourceIsPrimitive, reportStructuralErrors, intersectionState);
                                    }
                                }
                            }
                        }
                        if (varianceCheckFailed && result) {
                            errorInfo = originalErrorInfo || errorInfo || saveErrorInfo.errorInfo; // Use variance error (there is no structural one) and return false
                        }
                        else if (result) {
                            return result;
                        }
                    }
                    // If S is an object type and T is a discriminated union, S may be related to T if
                    // there exists a constituent of T for every combination of the discriminants of S
                    // with respect to T. We do not report errors here, as we will use the existing
                    // error result from checking each constituent of the union.
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */) && target.flags & 1048576 /* Union */) {
                        var objectOnlyTarget = extractTypesOfKind(target, 524288 /* Object */ | 2097152 /* Intersection */ | 33554432 /* Substitution */);
                        if (objectOnlyTarget.flags & 1048576 /* Union */) {
                            var result_7 = typeRelatedToDiscriminatedType(source, objectOnlyTarget);
                            if (result_7) {
                                return result_7;
                            }
                        }
                    }
                }
                return 0 /* False */;
                function relateVariances(sourceTypeArguments, targetTypeArguments, variances, intersectionState) {
                    if (result = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors, intersectionState)) {
                        return result;
                    }
                    if (ts.some(variances, function (v) { return !!(v & 24 /* AllowsStructuralFallback */); })) {
                        // If some type parameter was `Unmeasurable` or `Unreliable`, and we couldn't pass by assuming it was identical, then we
                        // have to allow a structural fallback check
                        // We elide the variance-based error elaborations, since those might not be too helpful, since we'll potentially
                        // be assuming identity of the type parameter.
                        originalErrorInfo = undefined;
                        resetErrorInfo(saveErrorInfo);
                        return undefined;
                    }
                    var allowStructuralFallback = targetTypeArguments && hasCovariantVoidArgument(targetTypeArguments, variances);
                    varianceCheckFailed = !allowStructuralFallback;
                    // The type arguments did not relate appropriately, but it may be because we have no variance
                    // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type
                    // arguments). It might also be the case that the target type has a 'void' type argument for
                    // a covariant type parameter that is only used in return positions within the generic type
                    // (in which case any type argument is permitted on the source side). In those cases we proceed
                    // with a structural comparison. Otherwise, we know for certain the instantiations aren't
                    // related and we can return here.
                    if (variances !== ts.emptyArray && !allowStructuralFallback) {
                        // In some cases generic types that are covariant in regular type checking mode become
                        // invariant in --strictFunctionTypes mode because one or more type parameters are used in
                        // both co- and contravariant positions. In order to make it easier to diagnose *why* such
                        // types are invariant, if any of the type parameters are invariant we reset the reported
                        // errors and instead force a structural comparison (which will include elaborations that
                        // reveal the reason).
                        // We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`,
                        // we can return `False` early here to skip calculating the structural error message we don't need.
                        if (varianceCheckFailed && !(reportErrors && ts.some(variances, function (v) { return (v & 7 /* VarianceMask */) === 0 /* Invariant */; }))) {
                            return 0 /* False */;
                        }
                        // We remember the original error information so we can restore it in case the structural
                        // comparison unexpectedly succeeds. This can happen when the structural comparison result
                        // is a Ternary.Maybe for example caused by the recursion depth limiter.
                        originalErrorInfo = errorInfo;
                        resetErrorInfo(saveErrorInfo);
                    }
                }
            }
            function reportUnmeasurableMarkers(p) {
                if (outofbandVarianceMarkerHandler && (p === markerSuperType || p === markerSubType || p === markerOtherType)) {
                    outofbandVarianceMarkerHandler(/*onlyUnreliable*/ false);
                }
                return p;
            }
            function reportUnreliableMarkers(p) {
                if (outofbandVarianceMarkerHandler && (p === markerSuperType || p === markerSubType || p === markerOtherType)) {
                    outofbandVarianceMarkerHandler(/*onlyUnreliable*/ true);
                }
                return p;
            }
            // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is
            // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice
            // that S and T are contra-variant whereas X and Y are co-variant.
            function mappedTypeRelatedTo(source, target, reportErrors) {
                var modifiersRelated = relation === comparableRelation || (relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) :
                    getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target));
                if (modifiersRelated) {
                    var result_8;
                    var targetConstraint = getConstraintTypeFromMappedType(target);
                    var sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), makeFunctionTypeMapper(getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMarkers : reportUnreliableMarkers));
                    if (result_8 = isRelatedTo(targetConstraint, sourceConstraint, reportErrors)) {
                        var mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]);
                        return result_8 & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors);
                    }
                }
                return 0 /* False */;
            }
            function typeRelatedToDiscriminatedType(source, target) {
                // 1. Generate the combinations of discriminant properties & types 'source' can satisfy.
                //    a. If the number of combinations is above a set limit, the comparison is too complex.
                // 2. Filter 'target' to the subset of types whose discriminants exist in the matrix.
                //    a. If 'target' does not satisfy all discriminants in the matrix, 'source' is not related.
                // 3. For each type in the filtered 'target', determine if all non-discriminant properties of
                //    'target' are related to a property in 'source'.
                //
                // NOTE: See ~/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithDiscriminatedUnion.ts
                //       for examples.
                var sourceProperties = getPropertiesOfType(source);
                var sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
                if (!sourcePropertiesFiltered)
                    return 0 /* False */;
                // Though we could compute the number of combinations as we generate
                // the matrix, this would incur additional memory overhead due to
                // array allocations. To reduce this overhead, we first compute
                // the number of combinations to ensure we will not surpass our
                // fixed limit before incurring the cost of any allocations:
                var numCombinations = 1;
                for (var _i = 0, sourcePropertiesFiltered_1 = sourcePropertiesFiltered; _i < sourcePropertiesFiltered_1.length; _i++) {
                    var sourceProperty = sourcePropertiesFiltered_1[_i];
                    numCombinations *= countTypes(getTypeOfSymbol(sourceProperty));
                    if (numCombinations > 25) {
                        // We've reached the complexity limit.
                        return 0 /* False */;
                    }
                }
                // Compute the set of types for each discriminant property.
                var sourceDiscriminantTypes = new Array(sourcePropertiesFiltered.length);
                var excludedProperties = ts.createUnderscoreEscapedMap();
                for (var i = 0; i < sourcePropertiesFiltered.length; i++) {
                    var sourceProperty = sourcePropertiesFiltered[i];
                    var sourcePropertyType = getTypeOfSymbol(sourceProperty);
                    sourceDiscriminantTypes[i] = sourcePropertyType.flags & 1048576 /* Union */
                        ? sourcePropertyType.types
                        : [sourcePropertyType];
                    excludedProperties.set(sourceProperty.escapedName, true);
                }
                // Match each combination of the cartesian product of discriminant properties to one or more
                // constituents of 'target'. If any combination does not have a match then 'source' is not relatable.
                var discriminantCombinations = ts.cartesianProduct(sourceDiscriminantTypes);
                var matchingTypes = [];
                var _loop_14 = function (combination) {
                    var hasMatch = false;
                    outer: for (var _i = 0, _a = target.types; _i < _a.length; _i++) {
                        var type = _a[_i];
                        var _loop_15 = function (i) {
                            var sourceProperty = sourcePropertiesFiltered[i];
                            var targetProperty = getPropertyOfType(type, sourceProperty.escapedName);
                            if (!targetProperty)
                                return "continue-outer";
                            if (sourceProperty === targetProperty)
                                return "continue";
                            // We compare the source property to the target in the context of a single discriminant type.
                            var related = propertyRelatedTo(source, target, sourceProperty, targetProperty, function (_) { return combination[i]; }, /*reportErrors*/ false, 0 /* None */, /*skipOptional*/ strictNullChecks || relation === comparableRelation);
                            // If the target property could not be found, or if the properties were not related,
                            // then this constituent is not a match.
                            if (!related) {
                                return "continue-outer";
                            }
                        };
                        for (var i = 0; i < sourcePropertiesFiltered.length; i++) {
                            var state_7 = _loop_15(i);
                            switch (state_7) {
                                case "continue-outer": continue outer;
                            }
                        }
                        ts.pushIfUnique(matchingTypes, type, ts.equateValues);
                        hasMatch = true;
                    }
                    if (!hasMatch) {
                        return { value: 0 /* False */ };
                    }
                };
                for (var _a = 0, discriminantCombinations_1 = discriminantCombinations; _a < discriminantCombinations_1.length; _a++) {
                    var combination = discriminantCombinations_1[_a];
                    var state_6 = _loop_14(combination);
                    if (typeof state_6 === "object")
                        return state_6.value;
                }
                // Compare the remaining non-discriminant properties of each match.
                var result = -1 /* True */;
                for (var _b = 0, matchingTypes_1 = matchingTypes; _b < matchingTypes_1.length; _b++) {
                    var type = matchingTypes_1[_b];
                    result &= propertiesRelatedTo(source, type, /*reportErrors*/ false, excludedProperties, 0 /* None */);
                    if (result) {
                        result &= signaturesRelatedTo(source, type, 0 /* Call */, /*reportStructuralErrors*/ false);
                        if (result) {
                            result &= signaturesRelatedTo(source, type, 1 /* Construct */, /*reportStructuralErrors*/ false);
                            if (result) {
                                result &= indexTypesRelatedTo(source, type, 0 /* String */, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, 0 /* None */);
                                if (result) {
                                    result &= indexTypesRelatedTo(source, type, 1 /* Number */, /*sourceIsPrimitive*/ false, /*reportStructuralErrors*/ false, 0 /* None */);
                                }
                            }
                        }
                    }
                    if (!result) {
                        return result;
                    }
                }
                return result;
            }
            function excludeProperties(properties, excludedProperties) {
                if (!excludedProperties || properties.length === 0)
                    return properties;
                var result;
                for (var i = 0; i < properties.length; i++) {
                    if (!excludedProperties.has(properties[i].escapedName)) {
                        if (result) {
                            result.push(properties[i]);
                        }
                    }
                    else if (!result) {
                        result = properties.slice(0, i);
                    }
                }
                return result || properties;
            }
            function isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState) {
                var targetIsOptional = strictNullChecks && !!(ts.getCheckFlags(targetProp) & 48 /* Partial */);
                var source = getTypeOfSourceProperty(sourceProp);
                if (ts.getCheckFlags(targetProp) & 65536 /* DeferredType */ && !getSymbolLinks(targetProp).type) {
                    // Rather than resolving (and normalizing) the type, relate constituent-by-constituent without performing normalization or seconadary passes
                    var links = getSymbolLinks(targetProp);
                    ts.Debug.assertIsDefined(links.deferralParent);
                    ts.Debug.assertIsDefined(links.deferralConstituents);
                    var unionParent = !!(links.deferralParent.flags & 1048576 /* Union */);
                    var result_9 = unionParent ? 0 /* False */ : -1 /* True */;
                    var targetTypes = links.deferralConstituents;
                    for (var _i = 0, targetTypes_3 = targetTypes; _i < targetTypes_3.length; _i++) {
                        var targetType = targetTypes_3[_i];
                        var related = isRelatedTo(source, targetType, /*reportErrors*/ false, /*headMessage*/ undefined, unionParent ? 0 : 2 /* Target */);
                        if (!unionParent) {
                            if (!related) {
                                // Can't assign to a target individually - have to fallback to assigning to the _whole_ intersection (which forces normalization)
                                return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
                            }
                            result_9 &= related;
                        }
                        else {
                            if (related) {
                                return related;
                            }
                        }
                    }
                    if (unionParent && !result_9 && targetIsOptional) {
                        result_9 = isRelatedTo(source, undefinedType);
                    }
                    if (unionParent && !result_9 && reportErrors) {
                        // The easiest way to get the right errors here is to un-defer (which may be costly)
                        // If it turns out this is too costly too often, we can replicate the error handling logic within
                        // typeRelatedToSomeType without the discriminatable type branch (as that requires a manifest union
                        // type on which to hand discriminable properties, which we are expressly trying to avoid here)
                        return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors);
                    }
                    return result_9;
                }
                else {
                    return isRelatedTo(source, addOptionality(getTypeOfSymbol(targetProp), targetIsOptional), reportErrors, /*headMessage*/ undefined, intersectionState);
                }
            }
            function propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState, skipOptional) {
                var sourcePropFlags = ts.getDeclarationModifierFlagsFromSymbol(sourceProp);
                var targetPropFlags = ts.getDeclarationModifierFlagsFromSymbol(targetProp);
                if (sourcePropFlags & 8 /* Private */ || targetPropFlags & 8 /* Private */) {
                    if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) {
                        if (reportErrors) {
                            if (sourcePropFlags & 8 /* Private */ && targetPropFlags & 8 /* Private */) {
                                reportError(ts.Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
                            }
                            else {
                                reportError(ts.Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), typeToString(sourcePropFlags & 8 /* Private */ ? source : target), typeToString(sourcePropFlags & 8 /* Private */ ? target : source));
                            }
                        }
                        return 0 /* False */;
                    }
                }
                else if (targetPropFlags & 16 /* Protected */) {
                    if (!isValidOverrideOf(sourceProp, targetProp)) {
                        if (reportErrors) {
                            reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target));
                        }
                        return 0 /* False */;
                    }
                }
                else if (sourcePropFlags & 16 /* Protected */) {
                    if (reportErrors) {
                        reportError(ts.Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                    }
                    return 0 /* False */;
                }
                // If the target comes from a partial union prop, allow `undefined` in the target type
                var related = isPropertySymbolTypeRelated(sourceProp, targetProp, getTypeOfSourceProperty, reportErrors, intersectionState);
                if (!related) {
                    if (reportErrors) {
                        reportIncompatibleError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp));
                    }
                    return 0 /* False */;
                }
                // When checking for comparability, be more lenient with optional properties.
                if (!skipOptional && sourceProp.flags & 16777216 /* Optional */ && !(targetProp.flags & 16777216 /* Optional */)) {
                    // TypeScript 1.0 spec (April 2014): 3.8.3
                    // S is a subtype of a type T, and T is a supertype of S if ...
                    // S' and T are object types and, for each member M in T..
                    // M is a property and S' contains a property N where
                    // if M is a required property, N is also a required property
                    // (M - property in T)
                    // (N - property in S)
                    if (reportErrors) {
                        reportError(ts.Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target));
                    }
                    return 0 /* False */;
                }
                return related;
            }
            function reportUnmatchedProperty(source, target, unmatchedProperty, requireOptionalProperties) {
                var shouldSkipElaboration = false;
                // give specific error in case where private names have the same description
                if (unmatchedProperty.valueDeclaration
                    && ts.isNamedDeclaration(unmatchedProperty.valueDeclaration)
                    && ts.isPrivateIdentifier(unmatchedProperty.valueDeclaration.name)
                    && source.symbol
                    && source.symbol.flags & 32 /* Class */) {
                    var privateIdentifierDescription = unmatchedProperty.valueDeclaration.name.escapedText;
                    var symbolTableKey = ts.getSymbolNameForPrivateIdentifier(source.symbol, privateIdentifierDescription);
                    if (symbolTableKey && getPropertyOfType(source, symbolTableKey)) {
                        var sourceName = ts.getDeclarationName(source.symbol.valueDeclaration);
                        var targetName = ts.getDeclarationName(target.symbol.valueDeclaration);
                        reportError(ts.Diagnostics.Property_0_in_type_1_refers_to_a_different_member_that_cannot_be_accessed_from_within_type_2, diagnosticName(privateIdentifierDescription), diagnosticName(sourceName.escapedText === "" ? anon : sourceName), diagnosticName(targetName.escapedText === "" ? anon : targetName));
                        return;
                    }
                }
                var props = ts.arrayFrom(getUnmatchedProperties(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false));
                if (!headMessage || (headMessage.code !== ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code &&
                    headMessage.code !== ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass.code)) {
                    shouldSkipElaboration = true; // Retain top-level error for interface implementing issues, otherwise omit it
                }
                if (props.length === 1) {
                    var propName = symbolToString(unmatchedProperty);
                    reportError.apply(void 0, __spreadArrays([ts.Diagnostics.Property_0_is_missing_in_type_1_but_required_in_type_2, propName], getTypeNamesForErrorDisplay(source, target)));
                    if (ts.length(unmatchedProperty.declarations)) {
                        associateRelatedInfo(ts.createDiagnosticForNode(unmatchedProperty.declarations[0], ts.Diagnostics._0_is_declared_here, propName));
                    }
                    if (shouldSkipElaboration && errorInfo) {
                        overrideNextErrorInfo++;
                    }
                }
                else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) {
                    if (props.length > 5) { // arbitrary cutoff for too-long list form
                        reportError(ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), ts.map(props.slice(0, 4), function (p) { return symbolToString(p); }).join(", "), props.length - 4);
                    }
                    else {
                        reportError(ts.Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), ts.map(props, function (p) { return symbolToString(p); }).join(", "));
                    }
                    if (shouldSkipElaboration && errorInfo) {
                        overrideNextErrorInfo++;
                    }
                }
                // No array like or unmatched property error - just issue top level error (errorInfo = undefined)
            }
            function propertiesRelatedTo(source, target, reportErrors, excludedProperties, intersectionState) {
                if (relation === identityRelation) {
                    return propertiesIdenticalTo(source, target, excludedProperties);
                }
                var requireOptionalProperties = (relation === subtypeRelation || relation === strictSubtypeRelation) && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source) && !isTupleType(source);
                var unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties, /*matchDiscriminantProperties*/ false);
                if (unmatchedProperty) {
                    if (reportErrors) {
                        reportUnmatchedProperty(source, target, unmatchedProperty, requireOptionalProperties);
                    }
                    return 0 /* False */;
                }
                if (isObjectLiteralType(target)) {
                    for (var _i = 0, _a = excludeProperties(getPropertiesOfType(source), excludedProperties); _i < _a.length; _i++) {
                        var sourceProp = _a[_i];
                        if (!getPropertyOfObjectType(target, sourceProp.escapedName)) {
                            var sourceType = getTypeOfSymbol(sourceProp);
                            if (!(sourceType === undefinedType || sourceType === undefinedWideningType || sourceType === optionalType)) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target));
                                }
                                return 0 /* False */;
                            }
                        }
                    }
                }
                var result = -1 /* True */;
                if (isTupleType(target)) {
                    var targetRestType = getRestTypeOfTupleType(target);
                    if (targetRestType) {
                        if (!isTupleType(source)) {
                            return 0 /* False */;
                        }
                        var sourceRestType = getRestTypeOfTupleType(source);
                        if (sourceRestType && !isRelatedTo(sourceRestType, targetRestType, reportErrors)) {
                            if (reportErrors) {
                                reportError(ts.Diagnostics.Rest_signatures_are_incompatible);
                            }
                            return 0 /* False */;
                        }
                        var targetCount = getTypeReferenceArity(target) - 1;
                        var sourceCount = getTypeReferenceArity(source) - (sourceRestType ? 1 : 0);
                        var sourceTypeArguments = getTypeArguments(source);
                        for (var i = targetCount; i < sourceCount; i++) {
                            var related = isRelatedTo(sourceTypeArguments[i], targetRestType, reportErrors);
                            if (!related) {
                                if (reportErrors) {
                                    reportError(ts.Diagnostics.Property_0_is_incompatible_with_rest_element_type, "" + i);
                                }
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                    }
                }
                // We only call this for union target types when we're attempting to do excess property checking - in those cases, we want to get _all possible props_
                // from the target union, across all members
                var properties = getPropertiesOfType(target);
                var numericNamesOnly = isTupleType(source) && isTupleType(target);
                for (var _b = 0, _c = excludeProperties(properties, excludedProperties); _b < _c.length; _b++) {
                    var targetProp = _c[_b];
                    var name = targetProp.escapedName;
                    if (!(targetProp.flags & 4194304 /* Prototype */) && (!numericNamesOnly || isNumericLiteralName(name) || name === "length")) {
                        var sourceProp = getPropertyOfType(source, name);
                        if (sourceProp && sourceProp !== targetProp) {
                            var related = propertyRelatedTo(source, target, sourceProp, targetProp, getTypeOfSymbol, reportErrors, intersectionState, relation === comparableRelation);
                            if (!related) {
                                return 0 /* False */;
                            }
                            result &= related;
                        }
                    }
                }
                return result;
            }
            function propertiesIdenticalTo(source, target, excludedProperties) {
                if (!(source.flags & 524288 /* Object */ && target.flags & 524288 /* Object */)) {
                    return 0 /* False */;
                }
                var sourceProperties = excludeProperties(getPropertiesOfObjectType(source), excludedProperties);
                var targetProperties = excludeProperties(getPropertiesOfObjectType(target), excludedProperties);
                if (sourceProperties.length !== targetProperties.length) {
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                for (var _i = 0, sourceProperties_1 = sourceProperties; _i < sourceProperties_1.length; _i++) {
                    var sourceProp = sourceProperties_1[_i];
                    var targetProp = getPropertyOfObjectType(target, sourceProp.escapedName);
                    if (!targetProp) {
                        return 0 /* False */;
                    }
                    var related = compareProperties(sourceProp, targetProp, isRelatedTo);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function signaturesRelatedTo(source, target, kind, reportErrors) {
                if (relation === identityRelation) {
                    return signaturesIdenticalTo(source, target, kind);
                }
                if (target === anyFunctionType || source === anyFunctionType) {
                    return -1 /* True */;
                }
                var sourceIsJSConstructor = source.symbol && isJSConstructor(source.symbol.valueDeclaration);
                var targetIsJSConstructor = target.symbol && isJSConstructor(target.symbol.valueDeclaration);
                var sourceSignatures = getSignaturesOfType(source, (sourceIsJSConstructor && kind === 1 /* Construct */) ?
                    0 /* Call */ : kind);
                var targetSignatures = getSignaturesOfType(target, (targetIsJSConstructor && kind === 1 /* Construct */) ?
                    0 /* Call */ : kind);
                if (kind === 1 /* Construct */ && sourceSignatures.length && targetSignatures.length) {
                    if (ts.isAbstractConstructorType(source) && !ts.isAbstractConstructorType(target)) {
                        // An abstract constructor type is not assignable to a non-abstract constructor type
                        // as it would otherwise be possible to new an abstract class. Note that the assignability
                        // check we perform for an extends clause excludes construct signatures from the target,
                        // so this check never proceeds.
                        if (reportErrors) {
                            reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type);
                        }
                        return 0 /* False */;
                    }
                    if (!constructorVisibilitiesAreCompatible(sourceSignatures[0], targetSignatures[0], reportErrors)) {
                        return 0 /* False */;
                    }
                }
                var result = -1 /* True */;
                var saveErrorInfo = captureErrorCalculationState();
                var incompatibleReporter = kind === 1 /* Construct */ ? reportIncompatibleConstructSignatureReturn : reportIncompatibleCallSignatureReturn;
                if (ts.getObjectFlags(source) & 64 /* Instantiated */ && ts.getObjectFlags(target) & 64 /* Instantiated */ && source.symbol === target.symbol) {
                    // We have instantiations of the same anonymous type (which typically will be the type of a
                    // method). Simply do a pairwise comparison of the signatures in the two signature lists instead
                    // of the much more expensive N * M comparison matrix we explore below. We erase type parameters
                    // as they are known to always be the same.
                    for (var i = 0; i < targetSignatures.length; i++) {
                        var related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors, incompatibleReporter(sourceSignatures[i], targetSignatures[i]));
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                else if (sourceSignatures.length === 1 && targetSignatures.length === 1) {
                    // For simple functions (functions with a single signature) we only erase type parameters for
                    // the comparable relation. Otherwise, if the source signature is generic, we instantiate it
                    // in the context of the target signature before checking the relationship. Ideally we'd do
                    // this regardless of the number of signatures, but the potential costs are prohibitive due
                    // to the quadratic nature of the logic below.
                    var eraseGenerics = relation === comparableRelation || !!compilerOptions.noStrictGenericChecks;
                    result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors, incompatibleReporter(sourceSignatures[0], targetSignatures[0]));
                }
                else {
                    outer: for (var _i = 0, targetSignatures_1 = targetSignatures; _i < targetSignatures_1.length; _i++) {
                        var t = targetSignatures_1[_i];
                        // Only elaborate errors from the first failure
                        var shouldElaborateErrors = reportErrors;
                        for (var _a = 0, sourceSignatures_1 = sourceSignatures; _a < sourceSignatures_1.length; _a++) {
                            var s = sourceSignatures_1[_a];
                            var related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors, incompatibleReporter(s, t));
                            if (related) {
                                result &= related;
                                resetErrorInfo(saveErrorInfo);
                                continue outer;
                            }
                            shouldElaborateErrors = false;
                        }
                        if (shouldElaborateErrors) {
                            reportError(ts.Diagnostics.Type_0_provides_no_match_for_the_signature_1, typeToString(source), signatureToString(t, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, kind));
                        }
                        return 0 /* False */;
                    }
                }
                return result;
            }
            function reportIncompatibleCallSignatureReturn(siga, sigb) {
                if (siga.parameters.length === 0 && sigb.parameters.length === 0) {
                    return function (source, target) { return reportIncompatibleError(ts.Diagnostics.Call_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); };
                }
                return function (source, target) { return reportIncompatibleError(ts.Diagnostics.Call_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); };
            }
            function reportIncompatibleConstructSignatureReturn(siga, sigb) {
                if (siga.parameters.length === 0 && sigb.parameters.length === 0) {
                    return function (source, target) { return reportIncompatibleError(ts.Diagnostics.Construct_signatures_with_no_arguments_have_incompatible_return_types_0_and_1, typeToString(source), typeToString(target)); };
                }
                return function (source, target) { return reportIncompatibleError(ts.Diagnostics.Construct_signature_return_types_0_and_1_are_incompatible, typeToString(source), typeToString(target)); };
            }
            /**
             * See signatureAssignableTo, compareSignaturesIdentical
             */
            function signatureRelatedTo(source, target, erase, reportErrors, incompatibleReporter) {
                return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, relation === strictSubtypeRelation ? 8 /* StrictArity */ : 0, reportErrors, reportError, incompatibleReporter, isRelatedTo, makeFunctionTypeMapper(reportUnreliableMarkers));
            }
            function signaturesIdenticalTo(source, target, kind) {
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                if (sourceSignatures.length !== targetSignatures.length) {
                    return 0 /* False */;
                }
                var result = -1 /* True */;
                for (var i = 0; i < sourceSignatures.length; i++) {
                    var related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
                    if (!related) {
                        return 0 /* False */;
                    }
                    result &= related;
                }
                return result;
            }
            function eachPropertyRelatedTo(source, target, kind, reportErrors) {
                var result = -1 /* True */;
                var props = source.flags & 2097152 /* Intersection */ ? getPropertiesOfUnionOrIntersectionType(source) : getPropertiesOfObjectType(source);
                for (var _i = 0, props_2 = props; _i < props_2.length; _i++) {
                    var prop = props_2[_i];
                    // Skip over ignored JSX and symbol-named members
                    if (isIgnoredJsxProperty(source, prop)) {
                        continue;
                    }
                    var nameType = getSymbolLinks(prop).nameType;
                    if (nameType && nameType.flags & 8192 /* UniqueESSymbol */) {
                        continue;
                    }
                    if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) {
                        var related = isRelatedTo(getTypeOfSymbol(prop), target, reportErrors);
                        if (!related) {
                            if (reportErrors) {
                                reportError(ts.Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop));
                            }
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
                return result;
            }
            function indexTypeRelatedTo(sourceType, targetType, reportErrors) {
                var related = isRelatedTo(sourceType, targetType, reportErrors);
                if (!related && reportErrors) {
                    reportError(ts.Diagnostics.Index_signatures_are_incompatible);
                }
                return related;
            }
            function indexTypesRelatedTo(source, target, kind, sourceIsPrimitive, reportErrors, intersectionState) {
                if (relation === identityRelation) {
                    return indexTypesIdenticalTo(source, target, kind);
                }
                var targetType = getIndexTypeOfType(target, kind);
                if (!targetType || targetType.flags & 1 /* Any */ && !sourceIsPrimitive) {
                    // Index signature of type any permits assignment from everything but primitives
                    return -1 /* True */;
                }
                if (isGenericMappedType(source)) {
                    // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U }
                    // if T is related to U.
                    return kind === 0 /* String */ ? isRelatedTo(getTemplateTypeFromMappedType(source), targetType, reportErrors) : 0 /* False */;
                }
                var indexType = getIndexTypeOfType(source, kind) || kind === 1 /* Number */ && getIndexTypeOfType(source, 0 /* String */);
                if (indexType) {
                    return indexTypeRelatedTo(indexType, targetType, reportErrors);
                }
                if (!(intersectionState & 1 /* Source */) && isObjectTypeWithInferableIndex(source)) {
                    // Intersection constituents are never considered to have an inferred index signature
                    var related = eachPropertyRelatedTo(source, targetType, kind, reportErrors);
                    if (related && kind === 0 /* String */) {
                        var numberIndexType = getIndexTypeOfType(source, 1 /* Number */);
                        if (numberIndexType) {
                            related &= indexTypeRelatedTo(numberIndexType, targetType, reportErrors);
                        }
                    }
                    return related;
                }
                if (reportErrors) {
                    reportError(ts.Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source));
                }
                return 0 /* False */;
            }
            function indexTypesIdenticalTo(source, target, indexKind) {
                var targetInfo = getIndexInfoOfType(target, indexKind);
                var sourceInfo = getIndexInfoOfType(source, indexKind);
                if (!sourceInfo && !targetInfo) {
                    return -1 /* True */;
                }
                if (sourceInfo && targetInfo && sourceInfo.isReadonly === targetInfo.isReadonly) {
                    return isRelatedTo(sourceInfo.type, targetInfo.type);
                }
                return 0 /* False */;
            }
            function constructorVisibilitiesAreCompatible(sourceSignature, targetSignature, reportErrors) {
                if (!sourceSignature.declaration || !targetSignature.declaration) {
                    return true;
                }
                var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
                var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24 /* NonPublicAccessibilityModifier */);
                // A public, protected and private signature is assignable to a private signature.
                if (targetAccessibility === 8 /* Private */) {
                    return true;
                }
                // A public and protected signature is assignable to a protected signature.
                if (targetAccessibility === 16 /* Protected */ && sourceAccessibility !== 8 /* Private */) {
                    return true;
                }
                // Only a public signature is assignable to public signature.
                if (targetAccessibility !== 16 /* Protected */ && !sourceAccessibility) {
                    return true;
                }
                if (reportErrors) {
                    reportError(ts.Diagnostics.Cannot_assign_a_0_constructor_type_to_a_1_constructor_type, visibilityToString(sourceAccessibility), visibilityToString(targetAccessibility));
                }
                return false;
            }
        }
        function getBestMatchingType(source, target, isRelatedTo) {
            if (isRelatedTo === void 0) { isRelatedTo = compareTypesAssignable; }
            return findMatchingDiscriminantType(source, target, isRelatedTo, /*skipPartial*/ true) ||
                findMatchingTypeReferenceOrTypeAliasReference(source, target) ||
                findBestTypeForObjectLiteral(source, target) ||
                findBestTypeForInvokable(source, target) ||
                findMostOverlappyType(source, target);
        }
        function discriminateTypeByDiscriminableItems(target, discriminators, related, defaultValue, skipPartial) {
            // undefined=unknown, true=discriminated, false=not discriminated
            // The state of each type progresses from left to right. Discriminated types stop at 'true'.
            var discriminable = target.types.map(function (_) { return undefined; });
            for (var _i = 0, discriminators_1 = discriminators; _i < discriminators_1.length; _i++) {
                var _a = discriminators_1[_i], getDiscriminatingType = _a[0], propertyName = _a[1];
                var targetProp = getUnionOrIntersectionProperty(target, propertyName);
                if (skipPartial && targetProp && ts.getCheckFlags(targetProp) & 16 /* ReadPartial */) {
                    continue;
                }
                var i = 0;
                for (var _b = 0, _c = target.types; _b < _c.length; _b++) {
                    var type = _c[_b];
                    var targetType = getTypeOfPropertyOfType(type, propertyName);
                    if (targetType && related(getDiscriminatingType(), targetType)) {
                        discriminable[i] = discriminable[i] === undefined ? true : discriminable[i];
                    }
                    else {
                        discriminable[i] = false;
                    }
                    i++;
                }
            }
            var match = discriminable.indexOf(/*searchElement*/ true);
            // make sure exactly 1 matches before returning it
            return match === -1 || discriminable.indexOf(/*searchElement*/ true, match + 1) !== -1 ? defaultValue : target.types[match];
        }
        /**
         * A type is 'weak' if it is an object type with at least one optional property
         * and no required properties, call/construct signatures or index signatures
         */
        function isWeakType(type) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 &&
                    !resolved.stringIndexInfo && !resolved.numberIndexInfo &&
                    resolved.properties.length > 0 &&
                    ts.every(resolved.properties, function (p) { return !!(p.flags & 16777216 /* Optional */); });
            }
            if (type.flags & 2097152 /* Intersection */) {
                return ts.every(type.types, isWeakType);
            }
            return false;
        }
        function hasCommonProperties(source, target, isComparingJsxAttributes) {
            for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) {
                var prop = _a[_i];
                if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) {
                    return true;
                }
            }
            return false;
        }
        // Return a type reference where the source type parameter is replaced with the target marker
        // type, and flag the result as a marker type reference.
        function getMarkerTypeReference(type, source, target) {
            var result = createTypeReference(type, ts.map(type.typeParameters, function (t) { return t === source ? target : t; }));
            result.objectFlags |= 8192 /* MarkerType */;
            return result;
        }
        function getAliasVariances(symbol) {
            var links = getSymbolLinks(symbol);
            return getVariancesWorker(links.typeParameters, links, function (_links, param, marker) {
                var type = getTypeAliasInstantiation(symbol, instantiateTypes(links.typeParameters, makeUnaryTypeMapper(param, marker)));
                type.aliasTypeArgumentsContainsMarker = true;
                return type;
            });
        }
        // Return an array containing the variance of each type parameter. The variance is effectively
        // a digest of the type comparisons that occur for each type argument when instantiations of the
        // generic type are structurally compared. We infer the variance information by comparing
        // instantiations of the generic type for type arguments with known relations. The function
        // returns the emptyArray singleton when invoked recursively for the given generic type.
        function getVariancesWorker(typeParameters, cache, createMarkerType) {
            if (typeParameters === void 0) { typeParameters = ts.emptyArray; }
            var variances = cache.variances;
            if (!variances) {
                // The emptyArray singleton is used to signal a recursive invocation.
                cache.variances = ts.emptyArray;
                variances = [];
                var _loop_16 = function (tp) {
                    var unmeasurable = false;
                    var unreliable = false;
                    var oldHandler = outofbandVarianceMarkerHandler;
                    outofbandVarianceMarkerHandler = function (onlyUnreliable) { return onlyUnreliable ? unreliable = true : unmeasurable = true; };
                    // We first compare instantiations where the type parameter is replaced with
                    // marker types that have a known subtype relationship. From this we can infer
                    // invariance, covariance, contravariance or bivariance.
                    var typeWithSuper = createMarkerType(cache, tp, markerSuperType);
                    var typeWithSub = createMarkerType(cache, tp, markerSubType);
                    var variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? 1 /* Covariant */ : 0) |
                        (isTypeAssignableTo(typeWithSuper, typeWithSub) ? 2 /* Contravariant */ : 0);
                    // If the instantiations appear to be related bivariantly it may be because the
                    // type parameter is independent (i.e. it isn't witnessed anywhere in the generic
                    // type). To determine this we compare instantiations where the type parameter is
                    // replaced with marker types that are known to be unrelated.
                    if (variance === 3 /* Bivariant */ && isTypeAssignableTo(createMarkerType(cache, tp, markerOtherType), typeWithSuper)) {
                        variance = 4 /* Independent */;
                    }
                    outofbandVarianceMarkerHandler = oldHandler;
                    if (unmeasurable || unreliable) {
                        if (unmeasurable) {
                            variance |= 8 /* Unmeasurable */;
                        }
                        if (unreliable) {
                            variance |= 16 /* Unreliable */;
                        }
                    }
                    variances.push(variance);
                };
                for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) {
                    var tp = typeParameters_1[_i];
                    _loop_16(tp);
                }
                cache.variances = variances;
            }
            return variances;
        }
        function getVariances(type) {
            // Arrays and tuples are known to be covariant, no need to spend time computing this.
            if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & 8 /* Tuple */) {
                return arrayVariances;
            }
            return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference);
        }
        // Return true if the given type reference has a 'void' type argument for a covariant type parameter.
        // See comment at call in recursiveTypeRelatedTo for when this case matters.
        function hasCovariantVoidArgument(typeArguments, variances) {
            for (var i = 0; i < variances.length; i++) {
                if ((variances[i] & 7 /* VarianceMask */) === 1 /* Covariant */ && typeArguments[i].flags & 16384 /* Void */) {
                    return true;
                }
            }
            return false;
        }
        function isUnconstrainedTypeParameter(type) {
            return type.flags & 262144 /* TypeParameter */ && !getConstraintOfTypeParameter(type);
        }
        function isNonDeferredTypeReference(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && !type.node;
        }
        function isTypeReferenceWithGenericArguments(type) {
            return isNonDeferredTypeReference(type) && ts.some(getTypeArguments(type), function (t) { return isUnconstrainedTypeParameter(t) || isTypeReferenceWithGenericArguments(t); });
        }
        /**
         * getTypeReferenceId(A<T, number, U>) returns "111=0-12=1"
         *   where A.id=111 and number.id=12
         */
        function getTypeReferenceId(type, typeParameters, depth) {
            if (depth === void 0) { depth = 0; }
            var result = "" + type.target.id;
            for (var _i = 0, _a = getTypeArguments(type); _i < _a.length; _i++) {
                var t = _a[_i];
                if (isUnconstrainedTypeParameter(t)) {
                    var index = typeParameters.indexOf(t);
                    if (index < 0) {
                        index = typeParameters.length;
                        typeParameters.push(t);
                    }
                    result += "=" + index;
                }
                else if (depth < 4 && isTypeReferenceWithGenericArguments(t)) {
                    result += "<" + getTypeReferenceId(t, typeParameters, depth + 1) + ">";
                }
                else {
                    result += "-" + t.id;
                }
            }
            return result;
        }
        /**
         * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters.
         * For other cases, the types ids are used.
         */
        function getRelationKey(source, target, intersectionState, relation) {
            if (relation === identityRelation && source.id > target.id) {
                var temp = source;
                source = target;
                target = temp;
            }
            var postFix = intersectionState ? ":" + intersectionState : "";
            if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) {
                var typeParameters = [];
                return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters) + postFix;
            }
            return source.id + "," + target.id + postFix;
        }
        // Invoke the callback for each underlying property symbol of the given symbol and return the first
        // value that isn't undefined.
        function forEachProperty(prop, callback) {
            if (ts.getCheckFlags(prop) & 6 /* Synthetic */) {
                for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    var p = getPropertyOfType(t, prop.escapedName);
                    var result = p && forEachProperty(p, callback);
                    if (result) {
                        return result;
                    }
                }
                return undefined;
            }
            return callback(prop);
        }
        // Return the declaring class type of a property or undefined if property not declared in class
        function getDeclaringClass(prop) {
            return prop.parent && prop.parent.flags & 32 /* Class */ ? getDeclaredTypeOfSymbol(getParentOfSymbol(prop)) : undefined;
        }
        // Return true if some underlying source property is declared in a class that derives
        // from the given base class.
        function isPropertyInClassDerivedFrom(prop, baseClass) {
            return forEachProperty(prop, function (sp) {
                var sourceClass = getDeclaringClass(sp);
                return sourceClass ? hasBaseType(sourceClass, baseClass) : false;
            });
        }
        // Return true if source property is a valid override of protected parts of target property.
        function isValidOverrideOf(sourceProp, targetProp) {
            return !forEachProperty(targetProp, function (tp) { return ts.getDeclarationModifierFlagsFromSymbol(tp) & 16 /* Protected */ ?
                !isPropertyInClassDerivedFrom(sourceProp, getDeclaringClass(tp)) : false; });
        }
        // Return true if the given class derives from each of the declaring classes of the protected
        // constituents of the given property.
        function isClassDerivedFromDeclaringClasses(checkClass, prop) {
            return forEachProperty(prop, function (p) { return ts.getDeclarationModifierFlagsFromSymbol(p) & 16 /* Protected */ ?
                !hasBaseType(checkClass, getDeclaringClass(p)) : false; }) ? undefined : checkClass;
        }
        // Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons
        // for 5 or more occurrences or instantiations of the type have been recorded on the given stack. It is possible,
        // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely
        // expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 5
        // levels, but unequal at some level beyond that.
        // In addition, this will also detect when an indexed access has been chained off of 5 or more times (which is essentially
        // the dual of the structural comparison), and likewise mark the type as deeply nested, potentially adding false positives
        // for finite but deeply expanding indexed accesses (eg, for `Q[P1][P2][P3][P4][P5]`).
        function isDeeplyNestedType(type, stack, depth) {
            // We track all object types that have an associated symbol (representing the origin of the type)
            if (depth >= 5 && type.flags & 524288 /* Object */ && !isObjectOrArrayLiteralType(type)) {
                var symbol = type.symbol;
                if (symbol) {
                    var count = 0;
                    for (var i = 0; i < depth; i++) {
                        var t = stack[i];
                        if (t.flags & 524288 /* Object */ && t.symbol === symbol) {
                            count++;
                            if (count >= 5)
                                return true;
                        }
                    }
                }
            }
            if (depth >= 5 && type.flags & 8388608 /* IndexedAccess */) {
                var root = getRootObjectTypeFromIndexedAccessChain(type);
                var count = 0;
                for (var i = 0; i < depth; i++) {
                    var t = stack[i];
                    if (getRootObjectTypeFromIndexedAccessChain(t) === root) {
                        count++;
                        if (count >= 5)
                            return true;
                    }
                }
            }
            return false;
        }
        /**
         * Gets the leftmost object type in a chain of indexed accesses, eg, in A[P][Q], returns A
         */
        function getRootObjectTypeFromIndexedAccessChain(type) {
            var t = type;
            while (t.flags & 8388608 /* IndexedAccess */) {
                t = t.objectType;
            }
            return t;
        }
        function isPropertyIdenticalTo(sourceProp, targetProp) {
            return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== 0 /* False */;
        }
        function compareProperties(sourceProp, targetProp, compareTypes) {
            // Two members are considered identical when
            // - they are public properties with identical names, optionality, and types,
            // - they are private or protected properties originating in the same declaration and having identical types
            if (sourceProp === targetProp) {
                return -1 /* True */;
            }
            var sourcePropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(sourceProp) & 24 /* NonPublicAccessibilityModifier */;
            var targetPropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(targetProp) & 24 /* NonPublicAccessibilityModifier */;
            if (sourcePropAccessibility !== targetPropAccessibility) {
                return 0 /* False */;
            }
            if (sourcePropAccessibility) {
                if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) {
                    return 0 /* False */;
                }
            }
            else {
                if ((sourceProp.flags & 16777216 /* Optional */) !== (targetProp.flags & 16777216 /* Optional */)) {
                    return 0 /* False */;
                }
            }
            if (isReadonlySymbol(sourceProp) !== isReadonlySymbol(targetProp)) {
                return 0 /* False */;
            }
            return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
        }
        function isMatchingSignature(source, target, partialMatch) {
            var sourceParameterCount = getParameterCount(source);
            var targetParameterCount = getParameterCount(target);
            var sourceMinArgumentCount = getMinArgumentCount(source);
            var targetMinArgumentCount = getMinArgumentCount(target);
            var sourceHasRestParameter = hasEffectiveRestParameter(source);
            var targetHasRestParameter = hasEffectiveRestParameter(target);
            // A source signature matches a target signature if the two signatures have the same number of required,
            // optional, and rest parameters.
            if (sourceParameterCount === targetParameterCount &&
                sourceMinArgumentCount === targetMinArgumentCount &&
                sourceHasRestParameter === targetHasRestParameter) {
                return true;
            }
            // A source signature partially matches a target signature if the target signature has no fewer required
            // parameters
            if (partialMatch && sourceMinArgumentCount <= targetMinArgumentCount) {
                return true;
            }
            return false;
        }
        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        function compareSignaturesIdentical(source, target, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypes) {
            // TODO (drosen): De-duplicate code between related functions.
            if (source === target) {
                return -1 /* True */;
            }
            if (!(isMatchingSignature(source, target, partialMatch))) {
                return 0 /* False */;
            }
            // Check that the two signatures have the same number of type parameters.
            if (ts.length(source.typeParameters) !== ts.length(target.typeParameters)) {
                return 0 /* False */;
            }
            // Check that type parameter constraints and defaults match. If they do, instantiate the source
            // signature with the type parameters of the target signature and continue the comparison.
            if (target.typeParameters) {
                var mapper = createTypeMapper(source.typeParameters, target.typeParameters);
                for (var i = 0; i < target.typeParameters.length; i++) {
                    var s = source.typeParameters[i];
                    var t = target.typeParameters[i];
                    if (!(s === t || compareTypes(instantiateType(getConstraintFromTypeParameter(s), mapper) || unknownType, getConstraintFromTypeParameter(t) || unknownType) &&
                        compareTypes(instantiateType(getDefaultFromTypeParameter(s), mapper) || unknownType, getDefaultFromTypeParameter(t) || unknownType))) {
                        return 0 /* False */;
                    }
                }
                source = instantiateSignature(source, mapper, /*eraseTypeParameters*/ true);
            }
            var result = -1 /* True */;
            if (!ignoreThisTypes) {
                var sourceThisType = getThisTypeOfSignature(source);
                if (sourceThisType) {
                    var targetThisType = getThisTypeOfSignature(target);
                    if (targetThisType) {
                        var related = compareTypes(sourceThisType, targetThisType);
                        if (!related) {
                            return 0 /* False */;
                        }
                        result &= related;
                    }
                }
            }
            var targetLen = getParameterCount(target);
            for (var i = 0; i < targetLen; i++) {
                var s = getTypeAtPosition(source, i);
                var t = getTypeAtPosition(target, i);
                var related = compareTypes(t, s);
                if (!related) {
                    return 0 /* False */;
                }
                result &= related;
            }
            if (!ignoreReturnTypes) {
                var sourceTypePredicate = getTypePredicateOfSignature(source);
                var targetTypePredicate = getTypePredicateOfSignature(target);
                result &= sourceTypePredicate || targetTypePredicate ?
                    compareTypePredicatesIdentical(sourceTypePredicate, targetTypePredicate, compareTypes) :
                    compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
            }
            return result;
        }
        function compareTypePredicatesIdentical(source, target, compareTypes) {
            return !(source && target && typePredicateKindsMatch(source, target)) ? 0 /* False */ :
                source.type === target.type ? -1 /* True */ :
                    source.type && target.type ? compareTypes(source.type, target.type) :
                        0 /* False */;
        }
        function literalTypesWithSameBaseType(types) {
            var commonBaseType;
            for (var _i = 0, types_12 = types; _i < types_12.length; _i++) {
                var t = types_12[_i];
                var baseType = getBaseTypeOfLiteralType(t);
                if (!commonBaseType) {
                    commonBaseType = baseType;
                }
                if (baseType === t || baseType !== commonBaseType) {
                    return false;
                }
            }
            return true;
        }
        // When the candidate types are all literal types with the same base type, return a union
        // of those literal types. Otherwise, return the leftmost type for which no type to the
        // right is a supertype.
        function getSupertypeOrUnion(types) {
            return literalTypesWithSameBaseType(types) ?
                getUnionType(types) :
                ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(s, t) ? t : s; });
        }
        function getCommonSupertype(types) {
            if (!strictNullChecks) {
                return getSupertypeOrUnion(types);
            }
            var primaryTypes = ts.filter(types, function (t) { return !(t.flags & 98304 /* Nullable */); });
            return primaryTypes.length ?
                getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & 98304 /* Nullable */) :
                getUnionType(types, 2 /* Subtype */);
        }
        // Return the leftmost type for which no type to the right is a subtype.
        function getCommonSubtype(types) {
            return ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(t, s) ? t : s; });
        }
        function isArrayType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && (type.target === globalArrayType || type.target === globalReadonlyArrayType);
        }
        function isReadonlyArrayType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */) && type.target === globalReadonlyArrayType;
        }
        function isMutableArrayOrTuple(type) {
            return isArrayType(type) && !isReadonlyArrayType(type) || isTupleType(type) && !type.target.readonly;
        }
        function getElementTypeOfArrayType(type) {
            return isArrayType(type) ? getTypeArguments(type)[0] : undefined;
        }
        function isArrayLikeType(type) {
            // A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
            // or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
            return isArrayType(type) || !(type.flags & 98304 /* Nullable */) && isTypeAssignableTo(type, anyReadonlyArrayType);
        }
        function isEmptyArrayLiteralType(type) {
            var elementType = isArrayType(type) ? getTypeArguments(type)[0] : undefined;
            return elementType === undefinedWideningType || elementType === implicitNeverType;
        }
        function isTupleLikeType(type) {
            return isTupleType(type) || !!getPropertyOfType(type, "0");
        }
        function isArrayOrTupleLikeType(type) {
            return isArrayLikeType(type) || isTupleLikeType(type);
        }
        function getTupleElementType(type, index) {
            var propType = getTypeOfPropertyOfType(type, "" + index);
            if (propType) {
                return propType;
            }
            if (everyType(type, isTupleType)) {
                return mapType(type, function (t) { return getRestTypeOfTupleType(t) || undefinedType; });
            }
            return undefined;
        }
        function isNeitherUnitTypeNorNever(type) {
            return !(type.flags & (109440 /* Unit */ | 131072 /* Never */));
        }
        function isUnitType(type) {
            return !!(type.flags & 109440 /* Unit */);
        }
        function isLiteralType(type) {
            return type.flags & 16 /* Boolean */ ? true :
                type.flags & 1048576 /* Union */ ? type.flags & 1024 /* EnumLiteral */ ? true : ts.every(type.types, isUnitType) :
                    isUnitType(type);
        }
        function getBaseTypeOfLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) :
                type.flags & 128 /* StringLiteral */ ? stringType :
                    type.flags & 256 /* NumberLiteral */ ? numberType :
                        type.flags & 2048 /* BigIntLiteral */ ? bigintType :
                            type.flags & 512 /* BooleanLiteral */ ? booleanType :
                                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getBaseTypeOfLiteralType)) :
                                    type;
        }
        function getWidenedLiteralType(type) {
            return type.flags & 1024 /* EnumLiteral */ && isFreshLiteralType(type) ? getBaseTypeOfEnumLiteralType(type) :
                type.flags & 128 /* StringLiteral */ && isFreshLiteralType(type) ? stringType :
                    type.flags & 256 /* NumberLiteral */ && isFreshLiteralType(type) ? numberType :
                        type.flags & 2048 /* BigIntLiteral */ && isFreshLiteralType(type) ? bigintType :
                            type.flags & 512 /* BooleanLiteral */ && isFreshLiteralType(type) ? booleanType :
                                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedLiteralType)) :
                                    type;
        }
        function getWidenedUniqueESSymbolType(type) {
            return type.flags & 8192 /* UniqueESSymbol */ ? esSymbolType :
                type.flags & 1048576 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedUniqueESSymbolType)) :
                    type;
        }
        function getWidenedLiteralLikeTypeForContextualType(type, contextualType) {
            if (!isLiteralOfContextualType(type, contextualType)) {
                type = getWidenedUniqueESSymbolType(getWidenedLiteralType(type));
            }
            return type;
        }
        function getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(type, contextualSignatureReturnType, isAsync) {
            if (type && isUnitType(type)) {
                var contextualType = !contextualSignatureReturnType ? undefined :
                    isAsync ? getPromisedTypeOfPromise(contextualSignatureReturnType) :
                        contextualSignatureReturnType;
                type = getWidenedLiteralLikeTypeForContextualType(type, contextualType);
            }
            return type;
        }
        function getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(type, contextualSignatureReturnType, kind, isAsyncGenerator) {
            if (type && isUnitType(type)) {
                var contextualType = !contextualSignatureReturnType ? undefined :
                    getIterationTypeOfGeneratorFunctionReturnType(kind, contextualSignatureReturnType, isAsyncGenerator);
                type = getWidenedLiteralLikeTypeForContextualType(type, contextualType);
            }
            return type;
        }
        /**
         * Check if a Type was written as a tuple type literal.
         * Prefer using isTupleLikeType() unless the use of `elementTypes`/`getTypeArguments` is required.
         */
        function isTupleType(type) {
            return !!(ts.getObjectFlags(type) & 4 /* Reference */ && type.target.objectFlags & 8 /* Tuple */);
        }
        function getRestTypeOfTupleType(type) {
            return type.target.hasRestElement ? getTypeArguments(type)[type.target.typeParameters.length - 1] : undefined;
        }
        function getRestArrayTypeOfTupleType(type) {
            var restType = getRestTypeOfTupleType(type);
            return restType && createArrayType(restType);
        }
        function getLengthOfTupleType(type) {
            return getTypeReferenceArity(type) - (type.target.hasRestElement ? 1 : 0);
        }
        function isZeroBigInt(_a) {
            var value = _a.value;
            return value.base10Value === "0";
        }
        function getFalsyFlagsOfTypes(types) {
            var result = 0;
            for (var _i = 0, types_13 = types; _i < types_13.length; _i++) {
                var t = types_13[_i];
                result |= getFalsyFlags(t);
            }
            return result;
        }
        // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null
        // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns
        // no flags for all other types (including non-falsy literal types).
        function getFalsyFlags(type) {
            return type.flags & 1048576 /* Union */ ? getFalsyFlagsOfTypes(type.types) :
                type.flags & 128 /* StringLiteral */ ? type.value === "" ? 128 /* StringLiteral */ : 0 :
                    type.flags & 256 /* NumberLiteral */ ? type.value === 0 ? 256 /* NumberLiteral */ : 0 :
                        type.flags & 2048 /* BigIntLiteral */ ? isZeroBigInt(type) ? 2048 /* BigIntLiteral */ : 0 :
                            type.flags & 512 /* BooleanLiteral */ ? (type === falseType || type === regularFalseType) ? 512 /* BooleanLiteral */ : 0 :
                                type.flags & 117724 /* PossiblyFalsy */;
        }
        function removeDefinitelyFalsyTypes(type) {
            return getFalsyFlags(type) & 117632 /* DefinitelyFalsy */ ?
                filterType(type, function (t) { return !(getFalsyFlags(t) & 117632 /* DefinitelyFalsy */); }) :
                type;
        }
        function extractDefinitelyFalsyTypes(type) {
            return mapType(type, getDefinitelyFalsyPartOfType);
        }
        function getDefinitelyFalsyPartOfType(type) {
            return type.flags & 4 /* String */ ? emptyStringType :
                type.flags & 8 /* Number */ ? zeroType :
                    type.flags & 64 /* BigInt */ ? zeroBigIntType :
                        type === regularFalseType ||
                            type === falseType ||
                            type.flags & (16384 /* Void */ | 32768 /* Undefined */ | 65536 /* Null */) ||
                            type.flags & 128 /* StringLiteral */ && type.value === "" ||
                            type.flags & 256 /* NumberLiteral */ && type.value === 0 ||
                            type.flags & 2048 /* BigIntLiteral */ && isZeroBigInt(type) ? type :
                            neverType;
        }
        /**
         * Add undefined or null or both to a type if they are missing.
         * @param type - type to add undefined and/or null to if not present
         * @param flags - Either TypeFlags.Undefined or TypeFlags.Null, or both
         */
        function getNullableType(type, flags) {
            var missing = (flags & ~type.flags) & (32768 /* Undefined */ | 65536 /* Null */);
            return missing === 0 ? type :
                missing === 32768 /* Undefined */ ? getUnionType([type, undefinedType]) :
                    missing === 65536 /* Null */ ? getUnionType([type, nullType]) :
                        getUnionType([type, undefinedType, nullType]);
        }
        function getOptionalType(type) {
            ts.Debug.assert(strictNullChecks);
            return type.flags & 32768 /* Undefined */ ? type : getUnionType([type, undefinedType]);
        }
        function getGlobalNonNullableTypeInstantiation(type) {
            if (!deferredGlobalNonNullableTypeAlias) {
                deferredGlobalNonNullableTypeAlias = getGlobalSymbol("NonNullable", 524288 /* TypeAlias */, /*diagnostic*/ undefined) || unknownSymbol;
            }
            // Use NonNullable global type alias if available to improve quick info/declaration emit
            if (deferredGlobalNonNullableTypeAlias !== unknownSymbol) {
                return getTypeAliasInstantiation(deferredGlobalNonNullableTypeAlias, [type]);
            }
            return getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */); // Type alias unavailable, fall back to non-higher-order behavior
        }
        function getNonNullableType(type) {
            return strictNullChecks ? getGlobalNonNullableTypeInstantiation(type) : type;
        }
        function addOptionalTypeMarker(type) {
            return strictNullChecks ? getUnionType([type, optionalType]) : type;
        }
        function isNotOptionalTypeMarker(type) {
            return type !== optionalType;
        }
        function removeOptionalTypeMarker(type) {
            return strictNullChecks ? filterType(type, isNotOptionalTypeMarker) : type;
        }
        function propagateOptionalTypeMarker(type, node, wasOptional) {
            return wasOptional ? ts.isOutermostOptionalChain(node) ? getOptionalType(type) : addOptionalTypeMarker(type) : type;
        }
        function getOptionalExpressionType(exprType, expression) {
            return ts.isExpressionOfOptionalChainRoot(expression) ? getNonNullableType(exprType) :
                ts.isOptionalChain(expression) ? removeOptionalTypeMarker(exprType) :
                    exprType;
        }
        /**
         * Is source potentially coercible to target type under `==`.
         * Assumes that `source` is a constituent of a union, hence
         * the boolean literal flag on the LHS, but not on the RHS.
         *
         * This does not fully replicate the semantics of `==`. The
         * intention is to catch cases that are clearly not right.
         *
         * Comparing (string | number) to number should not remove the
         * string element.
         *
         * Comparing (string | number) to 1 will remove the string
         * element, though this is not sound. This is a pragmatic
         * choice.
         *
         * @see narrowTypeByEquality
         *
         * @param source
         * @param target
         */
        function isCoercibleUnderDoubleEquals(source, target) {
            return ((source.flags & (8 /* Number */ | 4 /* String */ | 512 /* BooleanLiteral */)) !== 0)
                && ((target.flags & (8 /* Number */ | 4 /* String */ | 16 /* Boolean */)) !== 0);
        }
        /**
         * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module
         * with no call or construct signatures.
         */
        function isObjectTypeWithInferableIndex(type) {
            return type.flags & 2097152 /* Intersection */ ? ts.every(type.types, isObjectTypeWithInferableIndex) :
                !!(type.symbol && (type.symbol.flags & (4096 /* ObjectLiteral */ | 2048 /* TypeLiteral */ | 384 /* Enum */ | 512 /* ValueModule */)) !== 0 &&
                    !typeHasCallOrConstructSignatures(type)) || !!(ts.getObjectFlags(type) & 2048 /* ReverseMapped */ && isObjectTypeWithInferableIndex(type.source));
        }
        function createSymbolWithType(source, type) {
            var symbol = createSymbol(source.flags, source.escapedName, ts.getCheckFlags(source) & 8 /* Readonly */);
            symbol.declarations = source.declarations;
            symbol.parent = source.parent;
            symbol.type = type;
            symbol.target = source;
            if (source.valueDeclaration) {
                symbol.valueDeclaration = source.valueDeclaration;
            }
            var nameType = getSymbolLinks(source).nameType;
            if (nameType) {
                symbol.nameType = nameType;
            }
            return symbol;
        }
        function transformTypeOfMembers(type, f) {
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var property = _a[_i];
                var original = getTypeOfSymbol(property);
                var updated = f(original);
                members.set(property.escapedName, updated === original ? property : createSymbolWithType(property, updated));
            }
            return members;
        }
        /**
         * If the the provided object literal is subject to the excess properties check,
         * create a new that is exempt. Recursively mark object literal members as exempt.
         * Leave signatures alone since they are not subject to the check.
         */
        function getRegularTypeOfObjectLiteral(type) {
            if (!(isObjectLiteralType(type) && ts.getObjectFlags(type) & 32768 /* FreshLiteral */)) {
                return type;
            }
            var regularType = type.regularType;
            if (regularType) {
                return regularType;
            }
            var resolved = type;
            var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral);
            var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo);
            regularNew.flags = resolved.flags;
            regularNew.objectFlags |= resolved.objectFlags & ~32768 /* FreshLiteral */;
            type.regularType = regularNew;
            return regularNew;
        }
        function createWideningContext(parent, propertyName, siblings) {
            return { parent: parent, propertyName: propertyName, siblings: siblings, resolvedProperties: undefined };
        }
        function getSiblingsOfContext(context) {
            if (!context.siblings) {
                var siblings_1 = [];
                for (var _i = 0, _a = getSiblingsOfContext(context.parent); _i < _a.length; _i++) {
                    var type = _a[_i];
                    if (isObjectLiteralType(type)) {
                        var prop = getPropertyOfObjectType(type, context.propertyName);
                        if (prop) {
                            forEachType(getTypeOfSymbol(prop), function (t) {
                                siblings_1.push(t);
                            });
                        }
                    }
                }
                context.siblings = siblings_1;
            }
            return context.siblings;
        }
        function getPropertiesOfContext(context) {
            if (!context.resolvedProperties) {
                var names = ts.createMap();
                for (var _i = 0, _a = getSiblingsOfContext(context); _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (isObjectLiteralType(t) && !(ts.getObjectFlags(t) & 1024 /* ContainsSpread */)) {
                        for (var _b = 0, _c = getPropertiesOfType(t); _b < _c.length; _b++) {
                            var prop = _c[_b];
                            names.set(prop.escapedName, prop);
                        }
                    }
                }
                context.resolvedProperties = ts.arrayFrom(names.values());
            }
            return context.resolvedProperties;
        }
        function getWidenedProperty(prop, context) {
            if (!(prop.flags & 4 /* Property */)) {
                // Since get accessors already widen their return value there is no need to
                // widen accessor based properties here.
                return prop;
            }
            var original = getTypeOfSymbol(prop);
            var propContext = context && createWideningContext(context, prop.escapedName, /*siblings*/ undefined);
            var widened = getWidenedTypeWithContext(original, propContext);
            return widened === original ? prop : createSymbolWithType(prop, widened);
        }
        function getUndefinedProperty(prop) {
            var cached = undefinedProperties.get(prop.escapedName);
            if (cached) {
                return cached;
            }
            var result = createSymbolWithType(prop, undefinedType);
            result.flags |= 16777216 /* Optional */;
            undefinedProperties.set(prop.escapedName, result);
            return result;
        }
        function getWidenedTypeOfObjectLiteral(type, context) {
            var members = ts.createSymbolTable();
            for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) {
                var prop = _a[_i];
                members.set(prop.escapedName, getWidenedProperty(prop, context));
            }
            if (context) {
                for (var _b = 0, _c = getPropertiesOfContext(context); _b < _c.length; _b++) {
                    var prop = _c[_b];
                    if (!members.has(prop.escapedName)) {
                        members.set(prop.escapedName, getUndefinedProperty(prop));
                    }
                }
            }
            var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */);
            var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */);
            var result = createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly), numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
            result.objectFlags |= (ts.getObjectFlags(type) & (16384 /* JSLiteral */ | 2097152 /* NonInferrableType */)); // Retain js literal flag through widening
            return result;
        }
        function getWidenedType(type) {
            return getWidenedTypeWithContext(type, /*context*/ undefined);
        }
        function getWidenedTypeWithContext(type, context) {
            if (ts.getObjectFlags(type) & 1572864 /* RequiresWidening */) {
                if (context === undefined && type.widened) {
                    return type.widened;
                }
                var result = void 0;
                if (type.flags & (1 /* Any */ | 98304 /* Nullable */)) {
                    result = anyType;
                }
                else if (isObjectLiteralType(type)) {
                    result = getWidenedTypeOfObjectLiteral(type, context);
                }
                else if (type.flags & 1048576 /* Union */) {
                    var unionContext_1 = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, type.types);
                    var widenedTypes = ts.sameMap(type.types, function (t) { return t.flags & 98304 /* Nullable */ ? t : getWidenedTypeWithContext(t, unionContext_1); });
                    // Widening an empty object literal transitions from a highly restrictive type to
                    // a highly inclusive one. For that reason we perform subtype reduction here if the
                    // union includes empty object types (e.g. reducing {} | string to just {}).
                    result = getUnionType(widenedTypes, ts.some(widenedTypes, isEmptyObjectType) ? 2 /* Subtype */ : 1 /* Literal */);
                }
                else if (type.flags & 2097152 /* Intersection */) {
                    result = getIntersectionType(ts.sameMap(type.types, getWidenedType));
                }
                else if (isArrayType(type) || isTupleType(type)) {
                    result = createTypeReference(type.target, ts.sameMap(getTypeArguments(type), getWidenedType));
                }
                if (result && context === undefined) {
                    type.widened = result;
                }
                return result || type;
            }
            return type;
        }
        /**
         * Reports implicit any errors that occur as a result of widening 'null' and 'undefined'
         * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to
         * getWidenedType. But in some cases getWidenedType is called without reporting errors
         * (type argument inference is an example).
         *
         * The return value indicates whether an error was in fact reported. The particular circumstances
         * are on a best effort basis. Currently, if the null or undefined that causes widening is inside
         * an object literal property (arbitrarily deeply), this function reports an error. If no error is
         * reported, reportImplicitAnyError is a suitable fallback to report a general error.
         */
        function reportWideningErrorsInType(type) {
            var errorReported = false;
            if (ts.getObjectFlags(type) & 524288 /* ContainsWideningType */) {
                if (type.flags & 1048576 /* Union */) {
                    if (ts.some(type.types, isEmptyObjectType)) {
                        errorReported = true;
                    }
                    else {
                        for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                            var t = _a[_i];
                            if (reportWideningErrorsInType(t)) {
                                errorReported = true;
                            }
                        }
                    }
                }
                if (isArrayType(type) || isTupleType(type)) {
                    for (var _b = 0, _c = getTypeArguments(type); _b < _c.length; _b++) {
                        var t = _c[_b];
                        if (reportWideningErrorsInType(t)) {
                            errorReported = true;
                        }
                    }
                }
                if (isObjectLiteralType(type)) {
                    for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) {
                        var p = _e[_d];
                        var t = getTypeOfSymbol(p);
                        if (ts.getObjectFlags(t) & 524288 /* ContainsWideningType */) {
                            if (!reportWideningErrorsInType(t)) {
                                error(p.valueDeclaration, ts.Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), typeToString(getWidenedType(t)));
                            }
                            errorReported = true;
                        }
                    }
                }
            }
            return errorReported;
        }
        function reportImplicitAny(declaration, type, wideningKind) {
            var typeAsString = typeToString(getWidenedType(type));
            if (ts.isInJSFile(declaration) && !ts.isCheckJsEnabledForFile(ts.getSourceFileOfNode(declaration), compilerOptions)) {
                // Only report implicit any errors/suggestions in TS and ts-check JS files
                return;
            }
            var diagnostic;
            switch (declaration.kind) {
                case 209 /* BinaryExpression */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    diagnostic = noImplicitAny ? ts.Diagnostics.Member_0_implicitly_has_an_1_type : ts.Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
                    break;
                case 156 /* Parameter */:
                    var param = declaration;
                    if (ts.isIdentifier(param.name) &&
                        (ts.isCallSignatureDeclaration(param.parent) || ts.isMethodSignature(param.parent) || ts.isFunctionTypeNode(param.parent)) &&
                        param.parent.parameters.indexOf(param) > -1 &&
                        (resolveName(param, param.name.escapedText, 788968 /* Type */, undefined, param.name.escapedText, /*isUse*/ true) ||
                            param.name.originalKeywordKind && ts.isTypeNodeKind(param.name.originalKeywordKind))) {
                        var newName = "arg" + param.parent.parameters.indexOf(param);
                        errorOrSuggestion(noImplicitAny, declaration, ts.Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1, newName, ts.declarationNameToString(param.name));
                        return;
                    }
                    diagnostic = declaration.dotDotDotToken ?
                        noImplicitAny ? ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type : ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type_but_a_better_type_may_be_inferred_from_usage :
                        noImplicitAny ? ts.Diagnostics.Parameter_0_implicitly_has_an_1_type : ts.Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
                    break;
                case 191 /* BindingElement */:
                    diagnostic = ts.Diagnostics.Binding_element_0_implicitly_has_an_1_type;
                    if (!noImplicitAny) {
                        // Don't issue a suggestion for binding elements since the codefix doesn't yet support them.
                        return;
                    }
                    break;
                case 300 /* JSDocFunctionType */:
                    error(declaration, ts.Diagnostics.Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
                    return;
                case 244 /* FunctionDeclaration */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    if (noImplicitAny && !declaration.name) {
                        if (wideningKind === 3 /* GeneratorYield */) {
                            error(declaration, ts.Diagnostics.Generator_implicitly_has_yield_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type_annotation, typeAsString);
                        }
                        else {
                            error(declaration, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
                        }
                        return;
                    }
                    diagnostic = !noImplicitAny ? ts.Diagnostics._0_implicitly_has_an_1_return_type_but_a_better_type_may_be_inferred_from_usage :
                        wideningKind === 3 /* GeneratorYield */ ? ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_yield_type :
                            ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type;
                    break;
                case 186 /* MappedType */:
                    if (noImplicitAny) {
                        error(declaration, ts.Diagnostics.Mapped_object_type_implicitly_has_an_any_template_type);
                    }
                    return;
                default:
                    diagnostic = noImplicitAny ? ts.Diagnostics.Variable_0_implicitly_has_an_1_type : ts.Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage;
            }
            errorOrSuggestion(noImplicitAny, declaration, diagnostic, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)), typeAsString);
        }
        function reportErrorsFromWidening(declaration, type, wideningKind) {
            if (produceDiagnostics && noImplicitAny && ts.getObjectFlags(type) & 524288 /* ContainsWideningType */ && (!wideningKind || !getContextualSignatureForFunctionLikeDeclaration(declaration))) {
                // Report implicit any error within type if possible, otherwise report error on declaration
                if (!reportWideningErrorsInType(type)) {
                    reportImplicitAny(declaration, type, wideningKind);
                }
            }
        }
        function applyToParameterTypes(source, target, callback) {
            var sourceCount = getParameterCount(source);
            var targetCount = getParameterCount(target);
            var sourceRestType = getEffectiveRestType(source);
            var targetRestType = getEffectiveRestType(target);
            var targetNonRestCount = targetRestType ? targetCount - 1 : targetCount;
            var paramCount = sourceRestType ? targetNonRestCount : Math.min(sourceCount, targetNonRestCount);
            var sourceThisType = getThisTypeOfSignature(source);
            if (sourceThisType) {
                var targetThisType = getThisTypeOfSignature(target);
                if (targetThisType) {
                    callback(sourceThisType, targetThisType);
                }
            }
            for (var i = 0; i < paramCount; i++) {
                callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
            }
            if (targetRestType) {
                callback(getRestTypeAtPosition(source, paramCount), targetRestType);
            }
        }
        function applyToReturnTypes(source, target, callback) {
            var sourceTypePredicate = getTypePredicateOfSignature(source);
            var targetTypePredicate = getTypePredicateOfSignature(target);
            if (sourceTypePredicate && targetTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
                callback(sourceTypePredicate.type, targetTypePredicate.type);
            }
            else {
                callback(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
            }
        }
        function createInferenceContext(typeParameters, signature, flags, compareTypes) {
            return createInferenceContextWorker(typeParameters.map(createInferenceInfo), signature, flags, compareTypes || compareTypesAssignable);
        }
        function cloneInferenceContext(context, extraFlags) {
            if (extraFlags === void 0) { extraFlags = 0; }
            return context && createInferenceContextWorker(ts.map(context.inferences, cloneInferenceInfo), context.signature, context.flags | extraFlags, context.compareTypes);
        }
        function createInferenceContextWorker(inferences, signature, flags, compareTypes) {
            var context = {
                inferences: inferences,
                signature: signature,
                flags: flags,
                compareTypes: compareTypes,
                mapper: makeFunctionTypeMapper(function (t) { return mapToInferredType(context, t, /*fix*/ true); }),
                nonFixingMapper: makeFunctionTypeMapper(function (t) { return mapToInferredType(context, t, /*fix*/ false); }),
            };
            return context;
        }
        function mapToInferredType(context, t, fix) {
            var inferences = context.inferences;
            for (var i = 0; i < inferences.length; i++) {
                var inference = inferences[i];
                if (t === inference.typeParameter) {
                    if (fix && !inference.isFixed) {
                        clearCachedInferences(inferences);
                        inference.isFixed = true;
                    }
                    return getInferredType(context, i);
                }
            }
            return t;
        }
        function clearCachedInferences(inferences) {
            for (var _i = 0, inferences_1 = inferences; _i < inferences_1.length; _i++) {
                var inference = inferences_1[_i];
                if (!inference.isFixed) {
                    inference.inferredType = undefined;
                }
            }
        }
        function createInferenceInfo(typeParameter) {
            return {
                typeParameter: typeParameter,
                candidates: undefined,
                contraCandidates: undefined,
                inferredType: undefined,
                priority: undefined,
                topLevel: true,
                isFixed: false
            };
        }
        function cloneInferenceInfo(inference) {
            return {
                typeParameter: inference.typeParameter,
                candidates: inference.candidates && inference.candidates.slice(),
                contraCandidates: inference.contraCandidates && inference.contraCandidates.slice(),
                inferredType: inference.inferredType,
                priority: inference.priority,
                topLevel: inference.topLevel,
                isFixed: inference.isFixed
            };
        }
        function cloneInferredPartOfContext(context) {
            var inferences = ts.filter(context.inferences, hasInferenceCandidates);
            return inferences.length ?
                createInferenceContextWorker(ts.map(inferences, cloneInferenceInfo), context.signature, context.flags, context.compareTypes) :
                undefined;
        }
        function getMapperFromContext(context) {
            return context && context.mapper;
        }
        // Return true if the given type could possibly reference a type parameter for which
        // we perform type inference (i.e. a type parameter of a generic function). We cache
        // results for union and intersection types for performance reasons.
        function couldContainTypeVariables(type) {
            var objectFlags = ts.getObjectFlags(type);
            if (objectFlags & 67108864 /* CouldContainTypeVariablesComputed */) {
                return !!(objectFlags & 134217728 /* CouldContainTypeVariables */);
            }
            var result = !!(type.flags & 63176704 /* Instantiable */ ||
                objectFlags & 4 /* Reference */ && (type.node || ts.forEach(getTypeArguments(type), couldContainTypeVariables)) ||
                objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && type.symbol.declarations ||
                objectFlags & (32 /* Mapped */ | 131072 /* ObjectRestType */) ||
                type.flags & 3145728 /* UnionOrIntersection */ && !(type.flags & 1024 /* EnumLiteral */) && ts.some(type.types, couldContainTypeVariables));
            if (type.flags & 3899393 /* ObjectFlagsType */) {
                type.objectFlags |= 67108864 /* CouldContainTypeVariablesComputed */ | (result ? 134217728 /* CouldContainTypeVariables */ : 0);
            }
            return result;
        }
        function isTypeParameterAtTopLevel(type, typeParameter) {
            return !!(type === typeParameter ||
                type.flags & 3145728 /* UnionOrIntersection */ && ts.some(type.types, function (t) { return isTypeParameterAtTopLevel(t, typeParameter); }) ||
                type.flags & 16777216 /* Conditional */ && (isTypeParameterAtTopLevel(getTrueTypeFromConditionalType(type), typeParameter) ||
                    isTypeParameterAtTopLevel(getFalseTypeFromConditionalType(type), typeParameter)));
        }
        /** Create an object with properties named in the string literal type. Every property has type `any` */
        function createEmptyObjectTypeFromStringLiteral(type) {
            var members = ts.createSymbolTable();
            forEachType(type, function (t) {
                if (!(t.flags & 128 /* StringLiteral */)) {
                    return;
                }
                var name = ts.escapeLeadingUnderscores(t.value);
                var literalProp = createSymbol(4 /* Property */, name);
                literalProp.type = anyType;
                if (t.symbol) {
                    literalProp.declarations = t.symbol.declarations;
                    literalProp.valueDeclaration = t.symbol.valueDeclaration;
                }
                members.set(name, literalProp);
            });
            var indexInfo = type.flags & 4 /* String */ ? createIndexInfo(emptyObjectType, /*isReadonly*/ false) : undefined;
            return createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, indexInfo, undefined);
        }
        /**
         * Infer a suitable input type for a homomorphic mapped type { [P in keyof T]: X }. We construct
         * an object type with the same set of properties as the source type, where the type of each
         * property is computed by inferring from the source property type to X for the type
         * variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for).
         */
        function inferTypeForHomomorphicMappedType(source, target, constraint) {
            var key = source.id + "," + target.id + "," + constraint.id;
            if (reverseMappedCache.has(key)) {
                return reverseMappedCache.get(key);
            }
            reverseMappedCache.set(key, undefined);
            var type = createReverseMappedType(source, target, constraint);
            reverseMappedCache.set(key, type);
            return type;
        }
        // We consider a type to be partially inferable if it isn't marked non-inferable or if it is
        // an object literal type with at least one property of an inferable type. For example, an object
        // literal { a: 123, b: x => true } is marked non-inferable because it contains a context sensitive
        // arrow function, but is considered partially inferable because property 'a' has an inferable type.
        function isPartiallyInferableType(type) {
            return !(ts.getObjectFlags(type) & 2097152 /* NonInferrableType */) ||
                isObjectLiteralType(type) && ts.some(getPropertiesOfType(type), function (prop) { return isPartiallyInferableType(getTypeOfSymbol(prop)); });
        }
        function createReverseMappedType(source, target, constraint) {
            // We consider a source type reverse mappable if it has a string index signature or if
            // it has one or more properties and is of a partially inferable type.
            if (!(getIndexInfoOfType(source, 0 /* String */) || getPropertiesOfType(source).length !== 0 && isPartiallyInferableType(source))) {
                return undefined;
            }
            // For arrays and tuples we infer new arrays and tuples where the reverse mapping has been
            // applied to the element type(s).
            if (isArrayType(source)) {
                return createArrayType(inferReverseMappedType(getTypeArguments(source)[0], target, constraint), isReadonlyArrayType(source));
            }
            if (isTupleType(source)) {
                var elementTypes = ts.map(getTypeArguments(source), function (t) { return inferReverseMappedType(t, target, constraint); });
                var minLength = getMappedTypeModifiers(target) & 4 /* IncludeOptional */ ?
                    getTypeReferenceArity(source) - (source.target.hasRestElement ? 1 : 0) : source.target.minLength;
                return createTupleType(elementTypes, minLength, source.target.hasRestElement, source.target.readonly, source.target.associatedNames);
            }
            // For all other object types we infer a new object type where the reverse mapping has been
            // applied to the type of each property.
            var reversed = createObjectType(2048 /* ReverseMapped */ | 16 /* Anonymous */, /*symbol*/ undefined);
            reversed.source = source;
            reversed.mappedType = target;
            reversed.constraintType = constraint;
            return reversed;
        }
        function getTypeOfReverseMappedSymbol(symbol) {
            return inferReverseMappedType(symbol.propertyType, symbol.mappedType, symbol.constraintType);
        }
        function inferReverseMappedType(sourceType, target, constraint) {
            var typeParameter = getIndexedAccessType(constraint.type, getTypeParameterFromMappedType(target));
            var templateType = getTemplateTypeFromMappedType(target);
            var inference = createInferenceInfo(typeParameter);
            inferTypes([inference], sourceType, templateType);
            return getTypeFromInference(inference) || unknownType;
        }
        function getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties) {
            var properties, _i, properties_2, targetProp, sourceProp, targetType, sourceType;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        properties = getPropertiesOfType(target);
                        _i = 0, properties_2 = properties;
                        _a.label = 1;
                    case 1:
                        if (!(_i < properties_2.length)) return [3 /*break*/, 6];
                        targetProp = properties_2[_i];
                        // TODO: remove this when we support static private identifier fields and find other solutions to get privateNamesAndStaticFields test to pass
                        if (isStaticPrivateIdentifierProperty(targetProp)) {
                            return [3 /*break*/, 5];
                        }
                        if (!(requireOptionalProperties || !(targetProp.flags & 16777216 /* Optional */ || ts.getCheckFlags(targetProp) & 48 /* Partial */))) return [3 /*break*/, 5];
                        sourceProp = getPropertyOfType(source, targetProp.escapedName);
                        if (!!sourceProp) return [3 /*break*/, 3];
                        return [4 /*yield*/, targetProp];
                    case 2:
                        _a.sent();
                        return [3 /*break*/, 5];
                    case 3:
                        if (!matchDiscriminantProperties) return [3 /*break*/, 5];
                        targetType = getTypeOfSymbol(targetProp);
                        if (!(targetType.flags & 109440 /* Unit */)) return [3 /*break*/, 5];
                        sourceType = getTypeOfSymbol(sourceProp);
                        if (!!(sourceType.flags & 1 /* Any */ || getRegularTypeOfLiteralType(sourceType) === getRegularTypeOfLiteralType(targetType))) return [3 /*break*/, 5];
                        return [4 /*yield*/, targetProp];
                    case 4:
                        _a.sent();
                        _a.label = 5;
                    case 5:
                        _i++;
                        return [3 /*break*/, 1];
                    case 6: return [2 /*return*/];
                }
            });
        }
        function getUnmatchedProperty(source, target, requireOptionalProperties, matchDiscriminantProperties) {
            var result = getUnmatchedProperties(source, target, requireOptionalProperties, matchDiscriminantProperties).next();
            if (!result.done)
                return result.value;
        }
        function tupleTypesDefinitelyUnrelated(source, target) {
            return target.target.minLength > source.target.minLength ||
                !getRestTypeOfTupleType(target) && (!!getRestTypeOfTupleType(source) || getLengthOfTupleType(target) < getLengthOfTupleType(source));
        }
        function typesDefinitelyUnrelated(source, target) {
            // Two tuple types with incompatible arities are definitely unrelated.
            // Two object types that each have a property that is unmatched in the other are definitely unrelated.
            return isTupleType(source) && isTupleType(target) && tupleTypesDefinitelyUnrelated(source, target) ||
                !!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true) &&
                    !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ true);
        }
        function getTypeFromInference(inference) {
            return inference.candidates ? getUnionType(inference.candidates, 2 /* Subtype */) :
                inference.contraCandidates ? getIntersectionType(inference.contraCandidates) :
                    undefined;
        }
        function hasSkipDirectInferenceFlag(node) {
            return !!getNodeLinks(node).skipDirectInference;
        }
        function isFromInferenceBlockedSource(type) {
            return !!(type.symbol && ts.some(type.symbol.declarations, hasSkipDirectInferenceFlag));
        }
        function inferTypes(inferences, originalSource, originalTarget, priority, contravariant) {
            if (priority === void 0) { priority = 0; }
            if (contravariant === void 0) { contravariant = false; }
            var symbolOrTypeStack;
            var visited;
            var bivariant = false;
            var propagationType;
            var inferencePriority = 512 /* MaxValue */;
            var allowComplexConstraintInference = true;
            inferFromTypes(originalSource, originalTarget);
            function inferFromTypes(source, target) {
                if (!couldContainTypeVariables(target)) {
                    return;
                }
                if (source === wildcardType) {
                    // We are inferring from an 'any' type. We want to infer this type for every type parameter
                    // referenced in the target type, so we record it as the propagation type and infer from the
                    // target to itself. Then, as we find candidates we substitute the propagation type.
                    var savePropagationType = propagationType;
                    propagationType = source;
                    inferFromTypes(target, target);
                    propagationType = savePropagationType;
                    return;
                }
                if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) {
                    // Source and target are types originating in the same generic type alias declaration.
                    // Simply infer from source type arguments to target type arguments.
                    inferFromTypeArguments(source.aliasTypeArguments, target.aliasTypeArguments, getAliasVariances(source.aliasSymbol));
                    return;
                }
                if (source === target && source.flags & 3145728 /* UnionOrIntersection */) {
                    // When source and target are the same union or intersection type, just relate each constituent
                    // type to itself.
                    for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                        var t = _a[_i];
                        inferFromTypes(t, t);
                    }
                    return;
                }
                if (target.flags & 1048576 /* Union */) {
                    // First, infer between identically matching source and target constituents and remove the
                    // matching types.
                    var _b = inferFromMatchingTypes(source.flags & 1048576 /* Union */ ? source.types : [source], target.types, isTypeOrBaseIdenticalTo), tempSources = _b[0], tempTargets = _b[1];
                    // Next, infer between closely matching source and target constituents and remove
                    // the matching types. Types closely match when they are instantiations of the same
                    // object type or instantiations of the same type alias.
                    var _c = inferFromMatchingTypes(tempSources, tempTargets, isTypeCloselyMatchedBy), sources = _c[0], targets = _c[1];
                    if (targets.length === 0) {
                        return;
                    }
                    target = getUnionType(targets);
                    if (sources.length === 0) {
                        // All source constituents have been matched and there is nothing further to infer from.
                        // However, simply making no inferences is undesirable because it could ultimately mean
                        // inferring a type parameter constraint. Instead, make a lower priority inference from
                        // the full source to whatever remains in the target. For example, when inferring from
                        // string to 'string | T', make a lower priority inference of string for T.
                        inferWithPriority(source, target, 1 /* NakedTypeVariable */);
                        return;
                    }
                    source = getUnionType(sources);
                }
                else if (target.flags & 2097152 /* Intersection */ && ts.some(target.types, function (t) { return !!getInferenceInfoForType(t) || (isGenericMappedType(t) && !!getInferenceInfoForType(getHomomorphicTypeVariable(t) || neverType)); })) {
                    // We reduce intersection types only when they contain naked type parameters. For example, when
                    // inferring from 'string[] & { extra: any }' to 'string[] & T' we want to remove string[] and
                    // infer { extra: any } for T. But when inferring to 'string[] & Iterable<T>' we want to keep the
                    // string[] on the source side and infer string for T.
                    // Likewise, we consider a homomorphic mapped type constrainted to the target type parameter as similar to a "naked type variable"
                    // in such scenarios.
                    if (!(source.flags & 1048576 /* Union */)) {
                        // Infer between identically matching source and target constituents and remove the matching types.
                        var _d = inferFromMatchingTypes(source.flags & 2097152 /* Intersection */ ? source.types : [source], target.types, isTypeIdenticalTo), sources = _d[0], targets = _d[1];
                        if (sources.length === 0 || targets.length === 0) {
                            return;
                        }
                        source = getIntersectionType(sources);
                        target = getIntersectionType(targets);
                    }
                }
                else if (target.flags & (8388608 /* IndexedAccess */ | 33554432 /* Substitution */)) {
                    target = getActualTypeVariable(target);
                }
                if (target.flags & 8650752 /* TypeVariable */) {
                    // If target is a type parameter, make an inference, unless the source type contains
                    // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
                    // Because the anyFunctionType is internal, it should not be exposed to the user by adding
                    // it as an inference candidate. Hopefully, a better candidate will come along that does
                    // not contain anyFunctionType when we come back to this argument for its second round
                    // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard
                    // when constructing types from type parameters that had no inference candidates).
                    if (ts.getObjectFlags(source) & 2097152 /* NonInferrableType */ || source === nonInferrableAnyType || source === silentNeverType ||
                        (priority & 32 /* ReturnType */ && (source === autoType || source === autoArrayType)) || isFromInferenceBlockedSource(source)) {
                        return;
                    }
                    var inference = getInferenceInfoForType(target);
                    if (inference) {
                        if (!inference.isFixed) {
                            if (inference.priority === undefined || priority < inference.priority) {
                                inference.candidates = undefined;
                                inference.contraCandidates = undefined;
                                inference.topLevel = true;
                                inference.priority = priority;
                            }
                            if (priority === inference.priority) {
                                var candidate = propagationType || source;
                                // We make contravariant inferences only if we are in a pure contravariant position,
                                // i.e. only if we have not descended into a bivariant position.
                                if (contravariant && !bivariant) {
                                    if (!ts.contains(inference.contraCandidates, candidate)) {
                                        inference.contraCandidates = ts.append(inference.contraCandidates, candidate);
                                        clearCachedInferences(inferences);
                                    }
                                }
                                else if (!ts.contains(inference.candidates, candidate)) {
                                    inference.candidates = ts.append(inference.candidates, candidate);
                                    clearCachedInferences(inferences);
                                }
                            }
                            if (!(priority & 32 /* ReturnType */) && target.flags & 262144 /* TypeParameter */ && inference.topLevel && !isTypeParameterAtTopLevel(originalTarget, target)) {
                                inference.topLevel = false;
                                clearCachedInferences(inferences);
                            }
                        }
                        inferencePriority = Math.min(inferencePriority, priority);
                        return;
                    }
                    else {
                        // Infer to the simplified version of an indexed access, if possible, to (hopefully) expose more bare type parameters to the inference engine
                        var simplified = getSimplifiedType(target, /*writing*/ false);
                        if (simplified !== target) {
                            invokeOnce(source, simplified, inferFromTypes);
                        }
                        else if (target.flags & 8388608 /* IndexedAccess */) {
                            var indexType = getSimplifiedType(target.indexType, /*writing*/ false);
                            // Generally simplifications of instantiable indexes are avoided to keep relationship checking correct, however if our target is an access, we can consider
                            // that key of that access to be "instantiated", since we're looking to find the infernce goal in any way we can.
                            if (indexType.flags & 63176704 /* Instantiable */) {
                                var simplified_1 = distributeIndexOverObjectType(getSimplifiedType(target.objectType, /*writing*/ false), indexType, /*writing*/ false);
                                if (simplified_1 && simplified_1 !== target) {
                                    invokeOnce(source, simplified_1, inferFromTypes);
                                }
                            }
                        }
                    }
                }
                if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && (source.target === target.target || isArrayType(source) && isArrayType(target)) &&
                    !(source.node && target.node)) {
                    // If source and target are references to the same generic type, infer from type arguments
                    inferFromTypeArguments(getTypeArguments(source), getTypeArguments(target), getVariances(source.target));
                }
                else if (source.flags & 4194304 /* Index */ && target.flags & 4194304 /* Index */) {
                    contravariant = !contravariant;
                    inferFromTypes(source.type, target.type);
                    contravariant = !contravariant;
                }
                else if ((isLiteralType(source) || source.flags & 4 /* String */) && target.flags & 4194304 /* Index */) {
                    var empty = createEmptyObjectTypeFromStringLiteral(source);
                    contravariant = !contravariant;
                    inferWithPriority(empty, target.type, 64 /* LiteralKeyof */);
                    contravariant = !contravariant;
                }
                else if (source.flags & 8388608 /* IndexedAccess */ && target.flags & 8388608 /* IndexedAccess */) {
                    inferFromTypes(source.objectType, target.objectType);
                    inferFromTypes(source.indexType, target.indexType);
                }
                else if (source.flags & 16777216 /* Conditional */ && target.flags & 16777216 /* Conditional */) {
                    inferFromTypes(source.checkType, target.checkType);
                    inferFromTypes(source.extendsType, target.extendsType);
                    inferFromTypes(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target));
                    inferFromTypes(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target));
                }
                else if (target.flags & 16777216 /* Conditional */) {
                    var savePriority = priority;
                    priority |= contravariant ? 16 /* ContravariantConditional */ : 0;
                    var targetTypes = [getTrueTypeFromConditionalType(target), getFalseTypeFromConditionalType(target)];
                    inferToMultipleTypes(source, targetTypes, target.flags);
                    priority = savePriority;
                }
                else if (target.flags & 3145728 /* UnionOrIntersection */) {
                    inferToMultipleTypes(source, target.types, target.flags);
                }
                else if (source.flags & 1048576 /* Union */) {
                    // Source is a union or intersection type, infer from each constituent type
                    var sourceTypes = source.types;
                    for (var _e = 0, sourceTypes_2 = sourceTypes; _e < sourceTypes_2.length; _e++) {
                        var sourceType = sourceTypes_2[_e];
                        inferFromTypes(sourceType, target);
                    }
                }
                else {
                    source = getReducedType(source);
                    if (!(priority & 128 /* NoConstraints */ && source.flags & (2097152 /* Intersection */ | 63176704 /* Instantiable */))) {
                        var apparentSource = getApparentType(source);
                        // getApparentType can return _any_ type, since an indexed access or conditional may simplify to any other type.
                        // If that occurs and it doesn't simplify to an object or intersection, we'll need to restart `inferFromTypes`
                        // with the simplified source.
                        if (apparentSource !== source && allowComplexConstraintInference && !(apparentSource.flags & (524288 /* Object */ | 2097152 /* Intersection */))) {
                            // TODO: The `allowComplexConstraintInference` flag is a hack! This forbids inference from complex constraints within constraints!
                            // This isn't required algorithmically, but rather is used to lower the memory burden caused by performing inference
                            // that is _too good_ in projects with complicated constraints (eg, fp-ts). In such cases, if we did not limit ourselves
                            // here, we might produce more valid inferences for types, causing us to do more checks and perform more instantiations
                            // (in addition to the extra stack depth here) which, in turn, can push the already close process over its limit.
                            // TL;DR: If we ever become generally more memory efficient (or our resource budget ever increases), we should just
                            // remove this `allowComplexConstraintInference` flag.
                            allowComplexConstraintInference = false;
                            return inferFromTypes(apparentSource, target);
                        }
                        source = apparentSource;
                    }
                    if (source.flags & (524288 /* Object */ | 2097152 /* Intersection */)) {
                        invokeOnce(source, target, inferFromObjectTypes);
                    }
                }
                if (source.flags & 25165824 /* Simplifiable */) {
                    var simplified = getSimplifiedType(source, contravariant);
                    if (simplified !== source) {
                        inferFromTypes(simplified, target);
                    }
                }
            }
            function inferWithPriority(source, target, newPriority) {
                var savePriority = priority;
                priority |= newPriority;
                inferFromTypes(source, target);
                priority = savePriority;
            }
            function invokeOnce(source, target, action) {
                var key = source.id + "," + target.id;
                var status = visited && visited.get(key);
                if (status !== undefined) {
                    inferencePriority = Math.min(inferencePriority, status);
                    return;
                }
                (visited || (visited = ts.createMap())).set(key, -1 /* Circularity */);
                var saveInferencePriority = inferencePriority;
                inferencePriority = 512 /* MaxValue */;
                action(source, target);
                visited.set(key, inferencePriority);
                inferencePriority = Math.min(inferencePriority, saveInferencePriority);
            }
            function inferFromMatchingTypes(sources, targets, matches) {
                var matchedSources;
                var matchedTargets;
                for (var _i = 0, targets_1 = targets; _i < targets_1.length; _i++) {
                    var t = targets_1[_i];
                    for (var _a = 0, sources_1 = sources; _a < sources_1.length; _a++) {
                        var s = sources_1[_a];
                        if (matches(s, t)) {
                            inferFromTypes(s, t);
                            matchedSources = ts.appendIfUnique(matchedSources, s);
                            matchedTargets = ts.appendIfUnique(matchedTargets, t);
                        }
                    }
                }
                return [
                    matchedSources ? ts.filter(sources, function (t) { return !ts.contains(matchedSources, t); }) : sources,
                    matchedTargets ? ts.filter(targets, function (t) { return !ts.contains(matchedTargets, t); }) : targets,
                ];
            }
            function inferFromTypeArguments(sourceTypes, targetTypes, variances) {
                var count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length;
                for (var i = 0; i < count; i++) {
                    if (i < variances.length && (variances[i] & 7 /* VarianceMask */) === 2 /* Contravariant */) {
                        inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
                    }
                    else {
                        inferFromTypes(sourceTypes[i], targetTypes[i]);
                    }
                }
            }
            function inferFromContravariantTypes(source, target) {
                if (strictFunctionTypes || priority & 256 /* AlwaysStrict */) {
                    contravariant = !contravariant;
                    inferFromTypes(source, target);
                    contravariant = !contravariant;
                }
                else {
                    inferFromTypes(source, target);
                }
            }
            function getInferenceInfoForType(type) {
                if (type.flags & 8650752 /* TypeVariable */) {
                    for (var _i = 0, inferences_2 = inferences; _i < inferences_2.length; _i++) {
                        var inference = inferences_2[_i];
                        if (type === inference.typeParameter) {
                            return inference;
                        }
                    }
                }
                return undefined;
            }
            function getSingleTypeVariableFromIntersectionTypes(types) {
                var typeVariable;
                for (var _i = 0, types_14 = types; _i < types_14.length; _i++) {
                    var type = types_14[_i];
                    var t = type.flags & 2097152 /* Intersection */ && ts.find(type.types, function (t) { return !!getInferenceInfoForType(t); });
                    if (!t || typeVariable && t !== typeVariable) {
                        return undefined;
                    }
                    typeVariable = t;
                }
                return typeVariable;
            }
            function inferToMultipleTypes(source, targets, targetFlags) {
                var typeVariableCount = 0;
                if (targetFlags & 1048576 /* Union */) {
                    var nakedTypeVariable = void 0;
                    var sources = source.flags & 1048576 /* Union */ ? source.types : [source];
                    var matched_1 = new Array(sources.length);
                    var inferenceCircularity = false;
                    // First infer to types that are not naked type variables. For each source type we
                    // track whether inferences were made from that particular type to some target with
                    // equal priority (i.e. of equal quality) to what we would infer for a naked type
                    // parameter.
                    for (var _i = 0, targets_2 = targets; _i < targets_2.length; _i++) {
                        var t = targets_2[_i];
                        if (getInferenceInfoForType(t)) {
                            nakedTypeVariable = t;
                            typeVariableCount++;
                        }
                        else {
                            for (var i = 0; i < sources.length; i++) {
                                var saveInferencePriority = inferencePriority;
                                inferencePriority = 512 /* MaxValue */;
                                inferFromTypes(sources[i], t);
                                if (inferencePriority === priority)
                                    matched_1[i] = true;
                                inferenceCircularity = inferenceCircularity || inferencePriority === -1 /* Circularity */;
                                inferencePriority = Math.min(inferencePriority, saveInferencePriority);
                            }
                        }
                    }
                    if (typeVariableCount === 0) {
                        // If every target is an intersection of types containing a single naked type variable,
                        // make a lower priority inference to that type variable. This handles inferring from
                        // 'A | B' to 'T & (X | Y)' where we want to infer 'A | B' for T.
                        var intersectionTypeVariable = getSingleTypeVariableFromIntersectionTypes(targets);
                        if (intersectionTypeVariable) {
                            inferWithPriority(source, intersectionTypeVariable, 1 /* NakedTypeVariable */);
                        }
                        return;
                    }
                    // If the target has a single naked type variable and no inference circularities were
                    // encountered above (meaning we explored the types fully), create a union of the source
                    // types from which no inferences have been made so far and infer from that union to the
                    // naked type variable.
                    if (typeVariableCount === 1 && !inferenceCircularity) {
                        var unmatched = ts.flatMap(sources, function (s, i) { return matched_1[i] ? undefined : s; });
                        if (unmatched.length) {
                            inferFromTypes(getUnionType(unmatched), nakedTypeVariable);
                            return;
                        }
                    }
                }
                else {
                    // We infer from types that are not naked type variables first so that inferences we
                    // make from nested naked type variables and given slightly higher priority by virtue
                    // of being first in the candidates array.
                    for (var _a = 0, targets_3 = targets; _a < targets_3.length; _a++) {
                        var t = targets_3[_a];
                        if (getInferenceInfoForType(t)) {
                            typeVariableCount++;
                        }
                        else {
                            inferFromTypes(source, t);
                        }
                    }
                }
                // Inferences directly to naked type variables are given lower priority as they are
                // less specific. For example, when inferring from Promise<string> to T | Promise<T>,
                // we want to infer string for T, not Promise<string> | string. For intersection types
                // we only infer to single naked type variables.
                if (targetFlags & 2097152 /* Intersection */ ? typeVariableCount === 1 : typeVariableCount > 0) {
                    for (var _b = 0, targets_4 = targets; _b < targets_4.length; _b++) {
                        var t = targets_4[_b];
                        if (getInferenceInfoForType(t)) {
                            inferWithPriority(source, t, 1 /* NakedTypeVariable */);
                        }
                    }
                }
            }
            function inferToMappedType(source, target, constraintType) {
                if (constraintType.flags & 1048576 /* Union */) {
                    var result = false;
                    for (var _i = 0, _a = constraintType.types; _i < _a.length; _i++) {
                        var type = _a[_i];
                        result = inferToMappedType(source, target, type) || result;
                    }
                    return result;
                }
                if (constraintType.flags & 4194304 /* Index */) {
                    // We're inferring from some source type S to a homomorphic mapped type { [P in keyof T]: X },
                    // where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source
                    // type and then make a secondary inference from that type to T. We make a secondary inference
                    // such that direct inferences to T get priority over inferences to Partial<T>, for example.
                    var inference = getInferenceInfoForType(constraintType.type);
                    if (inference && !inference.isFixed && !isFromInferenceBlockedSource(source)) {
                        var inferredType = inferTypeForHomomorphicMappedType(source, target, constraintType);
                        if (inferredType) {
                            // We assign a lower priority to inferences made from types containing non-inferrable
                            // types because we may only have a partial result (i.e. we may have failed to make
                            // reverse inferences for some properties).
                            inferWithPriority(inferredType, inference.typeParameter, ts.getObjectFlags(source) & 2097152 /* NonInferrableType */ ?
                                4 /* PartialHomomorphicMappedType */ :
                                2 /* HomomorphicMappedType */);
                        }
                    }
                    return true;
                }
                if (constraintType.flags & 262144 /* TypeParameter */) {
                    // We're inferring from some source type S to a mapped type { [P in K]: X }, where K is a type
                    // parameter. First infer from 'keyof S' to K.
                    inferWithPriority(getIndexType(source), constraintType, 8 /* MappedTypeConstraint */);
                    // If K is constrained to a type C, also infer to C. Thus, for a mapped type { [P in K]: X },
                    // where K extends keyof T, we make the same inferences as for a homomorphic mapped type
                    // { [P in keyof T]: X }. This enables us to make meaningful inferences when the target is a
                    // Pick<T, K>.
                    var extendedConstraint = getConstraintOfType(constraintType);
                    if (extendedConstraint && inferToMappedType(source, target, extendedConstraint)) {
                        return true;
                    }
                    // If no inferences can be made to K's constraint, infer from a union of the property types
                    // in the source to the template type X.
                    var propTypes = ts.map(getPropertiesOfType(source), getTypeOfSymbol);
                    var stringIndexType = getIndexTypeOfType(source, 0 /* String */);
                    var numberIndexInfo = getNonEnumNumberIndexInfo(source);
                    var numberIndexType = numberIndexInfo && numberIndexInfo.type;
                    inferFromTypes(getUnionType(ts.append(ts.append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target));
                    return true;
                }
                return false;
            }
            function inferFromObjectTypes(source, target) {
                // If we are already processing another target type with the same associated symbol (such as
                // an instantiation of the same generic type), we do not explore this target as it would yield
                // no further inferences. We exclude the static side of classes from this check since it shares
                // its symbol with the instance side which would lead to false positives.
                var isNonConstructorObject = target.flags & 524288 /* Object */ &&
                    !(ts.getObjectFlags(target) & 16 /* Anonymous */ && target.symbol && target.symbol.flags & 32 /* Class */);
                var symbolOrType = isNonConstructorObject ? isTupleType(target) ? target.target : target.symbol : undefined;
                if (symbolOrType) {
                    if (ts.contains(symbolOrTypeStack, symbolOrType)) {
                        inferencePriority = -1 /* Circularity */;
                        return;
                    }
                    (symbolOrTypeStack || (symbolOrTypeStack = [])).push(symbolOrType);
                    inferFromObjectTypesWorker(source, target);
                    symbolOrTypeStack.pop();
                }
                else {
                    inferFromObjectTypesWorker(source, target);
                }
            }
            function inferFromObjectTypesWorker(source, target) {
                if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && (source.target === target.target || isArrayType(source) && isArrayType(target))) {
                    // If source and target are references to the same generic type, infer from type arguments
                    inferFromTypeArguments(getTypeArguments(source), getTypeArguments(target), getVariances(source.target));
                    return;
                }
                if (isGenericMappedType(source) && isGenericMappedType(target)) {
                    // The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer
                    // from S to T and from X to Y.
                    inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target));
                    inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target));
                }
                if (ts.getObjectFlags(target) & 32 /* Mapped */) {
                    var constraintType = getConstraintTypeFromMappedType(target);
                    if (inferToMappedType(source, target, constraintType)) {
                        return;
                    }
                }
                // Infer from the members of source and target only if the two types are possibly related
                if (!typesDefinitelyUnrelated(source, target)) {
                    if (isArrayType(source) || isTupleType(source)) {
                        if (isTupleType(target)) {
                            var sourceLength = isTupleType(source) ? getLengthOfTupleType(source) : 0;
                            var targetLength = getLengthOfTupleType(target);
                            var sourceRestType = isTupleType(source) ? getRestTypeOfTupleType(source) : getElementTypeOfArrayType(source);
                            var targetRestType = getRestTypeOfTupleType(target);
                            var fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength;
                            for (var i = 0; i < fixedLength; i++) {
                                inferFromTypes(i < sourceLength ? getTypeArguments(source)[i] : sourceRestType, getTypeArguments(target)[i]);
                            }
                            if (targetRestType) {
                                var types = fixedLength < sourceLength ? getTypeArguments(source).slice(fixedLength, sourceLength) : [];
                                if (sourceRestType) {
                                    types.push(sourceRestType);
                                }
                                if (types.length) {
                                    inferFromTypes(getUnionType(types), targetRestType);
                                }
                            }
                            return;
                        }
                        if (isArrayType(target)) {
                            inferFromIndexTypes(source, target);
                            return;
                        }
                    }
                    inferFromProperties(source, target);
                    inferFromSignatures(source, target, 0 /* Call */);
                    inferFromSignatures(source, target, 1 /* Construct */);
                    inferFromIndexTypes(source, target);
                }
            }
            function inferFromProperties(source, target) {
                var properties = getPropertiesOfObjectType(target);
                for (var _i = 0, properties_3 = properties; _i < properties_3.length; _i++) {
                    var targetProp = properties_3[_i];
                    var sourceProp = getPropertyOfType(source, targetProp.escapedName);
                    if (sourceProp) {
                        inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
                    }
                }
            }
            function inferFromSignatures(source, target, kind) {
                var sourceSignatures = getSignaturesOfType(source, kind);
                var targetSignatures = getSignaturesOfType(target, kind);
                var sourceLen = sourceSignatures.length;
                var targetLen = targetSignatures.length;
                var len = sourceLen < targetLen ? sourceLen : targetLen;
                var skipParameters = !!(ts.getObjectFlags(source) & 2097152 /* NonInferrableType */);
                for (var i = 0; i < len; i++) {
                    inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]), skipParameters);
                }
            }
            function inferFromSignature(source, target, skipParameters) {
                if (!skipParameters) {
                    var saveBivariant = bivariant;
                    var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */;
                    // Once we descend into a bivariant signature we remain bivariant for all nested inferences
                    bivariant = bivariant || kind === 161 /* MethodDeclaration */ || kind === 160 /* MethodSignature */ || kind === 162 /* Constructor */;
                    applyToParameterTypes(source, target, inferFromContravariantTypes);
                    bivariant = saveBivariant;
                }
                applyToReturnTypes(source, target, inferFromTypes);
            }
            function inferFromIndexTypes(source, target) {
                var targetStringIndexType = getIndexTypeOfType(target, 0 /* String */);
                if (targetStringIndexType) {
                    var sourceIndexType = getIndexTypeOfType(source, 0 /* String */) ||
                        getImplicitIndexTypeOfType(source, 0 /* String */);
                    if (sourceIndexType) {
                        inferFromTypes(sourceIndexType, targetStringIndexType);
                    }
                }
                var targetNumberIndexType = getIndexTypeOfType(target, 1 /* Number */);
                if (targetNumberIndexType) {
                    var sourceIndexType = getIndexTypeOfType(source, 1 /* Number */) ||
                        getIndexTypeOfType(source, 0 /* String */) ||
                        getImplicitIndexTypeOfType(source, 1 /* Number */);
                    if (sourceIndexType) {
                        inferFromTypes(sourceIndexType, targetNumberIndexType);
                    }
                }
            }
        }
        function isTypeOrBaseIdenticalTo(s, t) {
            return isTypeIdenticalTo(s, t) || !!(t.flags & 4 /* String */ && s.flags & 128 /* StringLiteral */ || t.flags & 8 /* Number */ && s.flags & 256 /* NumberLiteral */);
        }
        function isTypeCloselyMatchedBy(s, t) {
            return !!(s.flags & 524288 /* Object */ && t.flags & 524288 /* Object */ && s.symbol && s.symbol === t.symbol ||
                s.aliasSymbol && s.aliasTypeArguments && s.aliasSymbol === t.aliasSymbol);
        }
        function hasPrimitiveConstraint(type) {
            var constraint = getConstraintOfTypeParameter(type);
            return !!constraint && maybeTypeOfKind(constraint.flags & 16777216 /* Conditional */ ? getDefaultConstraintOfConditionalType(constraint) : constraint, 131068 /* Primitive */ | 4194304 /* Index */);
        }
        function isObjectLiteralType(type) {
            return !!(ts.getObjectFlags(type) & 128 /* ObjectLiteral */);
        }
        function isObjectOrArrayLiteralType(type) {
            return !!(ts.getObjectFlags(type) & (128 /* ObjectLiteral */ | 65536 /* ArrayLiteral */));
        }
        function unionObjectAndArrayLiteralCandidates(candidates) {
            if (candidates.length > 1) {
                var objectLiterals = ts.filter(candidates, isObjectOrArrayLiteralType);
                if (objectLiterals.length) {
                    var literalsType = getUnionType(objectLiterals, 2 /* Subtype */);
                    return ts.concatenate(ts.filter(candidates, function (t) { return !isObjectOrArrayLiteralType(t); }), [literalsType]);
                }
            }
            return candidates;
        }
        function getContravariantInference(inference) {
            return inference.priority & 104 /* PriorityImpliesCombination */ ? getIntersectionType(inference.contraCandidates) : getCommonSubtype(inference.contraCandidates);
        }
        function getCovariantInference(inference, signature) {
            // Extract all object and array literal types and replace them with a single widened and normalized type.
            var candidates = unionObjectAndArrayLiteralCandidates(inference.candidates);
            // We widen inferred literal types if
            // all inferences were made to top-level occurrences of the type parameter, and
            // the type parameter has no constraint or its constraint includes no primitive or literal types, and
            // the type parameter was fixed during inference or does not occur at top-level in the return type.
            var primitiveConstraint = hasPrimitiveConstraint(inference.typeParameter);
            var widenLiteralTypes = !primitiveConstraint && inference.topLevel &&
                (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
            var baseCandidates = primitiveConstraint ? ts.sameMap(candidates, getRegularTypeOfLiteralType) :
                widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) :
                    candidates;
            // If all inferences were made from a position that implies a combined result, infer a union type.
            // Otherwise, infer a common supertype.
            var unwidenedType = inference.priority & 104 /* PriorityImpliesCombination */ ?
                getUnionType(baseCandidates, 2 /* Subtype */) :
                getCommonSupertype(baseCandidates);
            return getWidenedType(unwidenedType);
        }
        function getInferredType(context, index) {
            var inference = context.inferences[index];
            if (!inference.inferredType) {
                var inferredType = void 0;
                var signature = context.signature;
                if (signature) {
                    var inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined;
                    if (inference.contraCandidates) {
                        var inferredContravariantType = getContravariantInference(inference);
                        // If we have both co- and contra-variant inferences, we prefer the contra-variant inference
                        // unless the co-variant inference is a subtype and not 'never'.
                        inferredType = inferredCovariantType && !(inferredCovariantType.flags & 131072 /* Never */) &&
                            isTypeSubtypeOf(inferredCovariantType, inferredContravariantType) ?
                            inferredCovariantType : inferredContravariantType;
                    }
                    else if (inferredCovariantType) {
                        inferredType = inferredCovariantType;
                    }
                    else if (context.flags & 1 /* NoDefault */) {
                        // We use silentNeverType as the wildcard that signals no inferences.
                        inferredType = silentNeverType;
                    }
                    else {
                        // Infer either the default or the empty object type when no inferences were
                        // made. It is important to remember that in this case, inference still
                        // succeeds, meaning there is no error for not having inference candidates. An
                        // inference error only occurs when there are *conflicting* candidates, i.e.
                        // candidates with no common supertype.
                        var defaultType = getDefaultFromTypeParameter(inference.typeParameter);
                        if (defaultType) {
                            // Instantiate the default type. Any forward reference to a type
                            // parameter should be instantiated to the empty object type.
                            inferredType = instantiateType(defaultType, mergeTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper));
                        }
                    }
                }
                else {
                    inferredType = getTypeFromInference(inference);
                }
                inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & 2 /* AnyDefault */));
                var constraint = getConstraintOfTypeParameter(inference.typeParameter);
                if (constraint) {
                    var instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper);
                    if (!inferredType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
                        inference.inferredType = inferredType = instantiatedConstraint;
                    }
                }
            }
            return inference.inferredType;
        }
        function getDefaultTypeArgumentType(isInJavaScriptFile) {
            return isInJavaScriptFile ? anyType : unknownType;
        }
        function getInferredTypes(context) {
            var result = [];
            for (var i = 0; i < context.inferences.length; i++) {
                result.push(getInferredType(context, i));
            }
            return result;
        }
        // EXPRESSION TYPE CHECKING
        function getCannotFindNameDiagnosticForName(node) {
            switch (node.escapedText) {
                case "document":
                case "console":
                    return ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_include_dom;
                case "$":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_types_Slashjquery;
                case "describe":
                case "suite":
                case "it":
                case "test":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_types_Slashjest_or_npm_i_types_Slashmocha;
                case "process":
                case "require":
                case "Buffer":
                case "module":
                    return compilerOptions.types
                        ? ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig
                        : ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_types_Slashnode;
                case "Map":
                case "Set":
                case "Promise":
                case "Symbol":
                case "WeakMap":
                case "WeakSet":
                case "Iterator":
                case "AsyncIterator":
                    return ts.Diagnostics.Cannot_find_name_0_Do_you_need_to_change_your_target_library_Try_changing_the_lib_compiler_option_to_es2015_or_later;
                default:
                    if (node.parent.kind === 282 /* ShorthandPropertyAssignment */) {
                        return ts.Diagnostics.No_value_exists_in_scope_for_the_shorthand_property_0_Either_declare_one_or_provide_an_initializer;
                    }
                    else {
                        return ts.Diagnostics.Cannot_find_name_0;
                    }
            }
        }
        function getResolvedSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                links.resolvedSymbol = !ts.nodeIsMissing(node) &&
                    resolveName(node, node.escapedText, 111551 /* Value */ | 1048576 /* ExportValue */, getCannotFindNameDiagnosticForName(node), node, !ts.isWriteOnlyAccess(node), 
                    /*excludeGlobals*/ false, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol;
            }
            return links.resolvedSymbol;
        }
        function isInTypeQuery(node) {
            // TypeScript 1.0 spec (April 2014): 3.6.3
            // A type query consists of the keyword typeof followed by an expression.
            // The expression is restricted to a single identifier or a sequence of identifiers separated by periods
            return !!ts.findAncestor(node, function (n) { return n.kind === 172 /* TypeQuery */ ? true : n.kind === 75 /* Identifier */ || n.kind === 153 /* QualifiedName */ ? false : "quit"; });
        }
        // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers
        // separated by dots). The key consists of the id of the symbol referenced by the
        // leftmost identifier followed by zero or more property names separated by dots.
        // The result is undefined if the reference isn't a dotted name. We prefix nodes
        // occurring in an apparent type position with '@' because the control flow type
        // of such nodes may be based on the apparent type instead of the declared type.
        function getFlowCacheKey(node, declaredType, initialType, flowContainer) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    var symbol = getResolvedSymbol(node);
                    return symbol !== unknownSymbol ? (flowContainer ? getNodeId(flowContainer) : "-1") + "|" + getTypeId(declaredType) + "|" + getTypeId(initialType) + "|" + (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
                case 104 /* ThisKeyword */:
                    return "0";
                case 218 /* NonNullExpression */:
                case 200 /* ParenthesizedExpression */:
                    return getFlowCacheKey(node.expression, declaredType, initialType, flowContainer);
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    var propName = getAccessedPropertyName(node);
                    if (propName !== undefined) {
                        var key = getFlowCacheKey(node.expression, declaredType, initialType, flowContainer);
                        return key && key + "." + propName;
                    }
            }
            return undefined;
        }
        function isMatchingReference(source, target) {
            switch (target.kind) {
                case 200 /* ParenthesizedExpression */:
                case 218 /* NonNullExpression */:
                    return isMatchingReference(source, target.expression);
            }
            switch (source.kind) {
                case 75 /* Identifier */:
                    return target.kind === 75 /* Identifier */ && getResolvedSymbol(source) === getResolvedSymbol(target) ||
                        (target.kind === 242 /* VariableDeclaration */ || target.kind === 191 /* BindingElement */) &&
                            getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source)) === getSymbolOfNode(target);
                case 104 /* ThisKeyword */:
                    return target.kind === 104 /* ThisKeyword */;
                case 102 /* SuperKeyword */:
                    return target.kind === 102 /* SuperKeyword */;
                case 218 /* NonNullExpression */:
                case 200 /* ParenthesizedExpression */:
                    return isMatchingReference(source.expression, target);
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    return ts.isAccessExpression(target) &&
                        getAccessedPropertyName(source) === getAccessedPropertyName(target) &&
                        isMatchingReference(source.expression, target.expression);
            }
            return false;
        }
        // Given a source x, check if target matches x or is an && operation with an operand that matches x.
        function containsTruthyCheck(source, target) {
            return isMatchingReference(source, target) ||
                (target.kind === 209 /* BinaryExpression */ && target.operatorToken.kind === 55 /* AmpersandAmpersandToken */ &&
                    (containsTruthyCheck(source, target.left) || containsTruthyCheck(source, target.right)));
        }
        function getAccessedPropertyName(access) {
            return access.kind === 194 /* PropertyAccessExpression */ ? access.name.escapedText :
                ts.isStringOrNumericLiteralLike(access.argumentExpression) ? ts.escapeLeadingUnderscores(access.argumentExpression.text) :
                    undefined;
        }
        function containsMatchingReference(source, target) {
            while (ts.isAccessExpression(source)) {
                source = source.expression;
                if (isMatchingReference(source, target)) {
                    return true;
                }
            }
            return false;
        }
        function optionalChainContainsReference(source, target) {
            while (ts.isOptionalChain(source)) {
                source = source.expression;
                if (isMatchingReference(source, target)) {
                    return true;
                }
            }
            return false;
        }
        function isDiscriminantProperty(type, name) {
            if (type && type.flags & 1048576 /* Union */) {
                var prop = getUnionOrIntersectionProperty(type, name);
                if (prop && ts.getCheckFlags(prop) & 2 /* SyntheticProperty */) {
                    if (prop.isDiscriminantProperty === undefined) {
                        prop.isDiscriminantProperty =
                            (prop.checkFlags & 192 /* Discriminant */) === 192 /* Discriminant */ &&
                                !maybeTypeOfKind(getTypeOfSymbol(prop), 63176704 /* Instantiable */);
                    }
                    return !!prop.isDiscriminantProperty;
                }
            }
            return false;
        }
        function findDiscriminantProperties(sourceProperties, target) {
            var result;
            for (var _i = 0, sourceProperties_2 = sourceProperties; _i < sourceProperties_2.length; _i++) {
                var sourceProperty = sourceProperties_2[_i];
                if (isDiscriminantProperty(target, sourceProperty.escapedName)) {
                    if (result) {
                        result.push(sourceProperty);
                        continue;
                    }
                    result = [sourceProperty];
                }
            }
            return result;
        }
        function isOrContainsMatchingReference(source, target) {
            return isMatchingReference(source, target) || containsMatchingReference(source, target);
        }
        function hasMatchingArgument(callExpression, reference) {
            if (callExpression.arguments) {
                for (var _i = 0, _a = callExpression.arguments; _i < _a.length; _i++) {
                    var argument = _a[_i];
                    if (isOrContainsMatchingReference(reference, argument)) {
                        return true;
                    }
                }
            }
            if (callExpression.expression.kind === 194 /* PropertyAccessExpression */ &&
                isOrContainsMatchingReference(reference, callExpression.expression.expression)) {
                return true;
            }
            return false;
        }
        function getFlowNodeId(flow) {
            if (!flow.id || flow.id < 0) {
                flow.id = nextFlowId;
                nextFlowId++;
            }
            return flow.id;
        }
        function typeMaybeAssignableTo(source, target) {
            if (!(source.flags & 1048576 /* Union */)) {
                return isTypeAssignableTo(source, target);
            }
            for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                var t = _a[_i];
                if (isTypeAssignableTo(t, target)) {
                    return true;
                }
            }
            return false;
        }
        // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
        // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
        // we remove type string.
        function getAssignmentReducedType(declaredType, assignedType) {
            if (declaredType !== assignedType) {
                if (assignedType.flags & 131072 /* Never */) {
                    return assignedType;
                }
                var reducedType = filterType(declaredType, function (t) { return typeMaybeAssignableTo(assignedType, t); });
                if (assignedType.flags & 512 /* BooleanLiteral */ && isFreshLiteralType(assignedType)) {
                    reducedType = mapType(reducedType, getFreshTypeOfLiteralType); // Ensure that if the assignment is a fresh type, that we narrow to fresh types
                }
                // Our crude heuristic produces an invalid result in some cases: see GH#26130.
                // For now, when that happens, we give up and don't narrow at all.  (This also
                // means we'll never narrow for erroneous assignments where the assigned type
                // is not assignable to the declared type.)
                if (isTypeAssignableTo(assignedType, reducedType)) {
                    return reducedType;
                }
            }
            return declaredType;
        }
        function getTypeFactsOfTypes(types) {
            var result = 0 /* None */;
            for (var _i = 0, types_15 = types; _i < types_15.length; _i++) {
                var t = types_15[_i];
                result |= getTypeFacts(t);
            }
            return result;
        }
        function isFunctionObjectType(type) {
            // We do a quick check for a "bind" property before performing the more expensive subtype
            // check. This gives us a quicker out in the common case where an object type is not a function.
            var resolved = resolveStructuredTypeMembers(type);
            return !!(resolved.callSignatures.length || resolved.constructSignatures.length ||
                resolved.members.get("bind") && isTypeSubtypeOf(type, globalFunctionType));
        }
        function getTypeFacts(type) {
            var flags = type.flags;
            if (flags & 4 /* String */) {
                return strictNullChecks ? 16317953 /* StringStrictFacts */ : 16776705 /* StringFacts */;
            }
            if (flags & 128 /* StringLiteral */) {
                var isEmpty = type.value === "";
                return strictNullChecks ?
                    isEmpty ? 12123649 /* EmptyStringStrictFacts */ : 7929345 /* NonEmptyStringStrictFacts */ :
                    isEmpty ? 12582401 /* EmptyStringFacts */ : 16776705 /* NonEmptyStringFacts */;
            }
            if (flags & (8 /* Number */ | 32 /* Enum */)) {
                return strictNullChecks ? 16317698 /* NumberStrictFacts */ : 16776450 /* NumberFacts */;
            }
            if (flags & 256 /* NumberLiteral */) {
                var isZero = type.value === 0;
                return strictNullChecks ?
                    isZero ? 12123394 /* ZeroNumberStrictFacts */ : 7929090 /* NonZeroNumberStrictFacts */ :
                    isZero ? 12582146 /* ZeroNumberFacts */ : 16776450 /* NonZeroNumberFacts */;
            }
            if (flags & 64 /* BigInt */) {
                return strictNullChecks ? 16317188 /* BigIntStrictFacts */ : 16775940 /* BigIntFacts */;
            }
            if (flags & 2048 /* BigIntLiteral */) {
                var isZero = isZeroBigInt(type);
                return strictNullChecks ?
                    isZero ? 12122884 /* ZeroBigIntStrictFacts */ : 7928580 /* NonZeroBigIntStrictFacts */ :
                    isZero ? 12581636 /* ZeroBigIntFacts */ : 16775940 /* NonZeroBigIntFacts */;
            }
            if (flags & 16 /* Boolean */) {
                return strictNullChecks ? 16316168 /* BooleanStrictFacts */ : 16774920 /* BooleanFacts */;
            }
            if (flags & 528 /* BooleanLike */) {
                return strictNullChecks ?
                    (type === falseType || type === regularFalseType) ? 12121864 /* FalseStrictFacts */ : 7927560 /* TrueStrictFacts */ :
                    (type === falseType || type === regularFalseType) ? 12580616 /* FalseFacts */ : 16774920 /* TrueFacts */;
            }
            if (flags & 524288 /* Object */) {
                return ts.getObjectFlags(type) & 16 /* Anonymous */ && isEmptyObjectType(type) ?
                    strictNullChecks ? 16318463 /* EmptyObjectStrictFacts */ : 16777215 /* EmptyObjectFacts */ :
                    isFunctionObjectType(type) ?
                        strictNullChecks ? 7880640 /* FunctionStrictFacts */ : 16728000 /* FunctionFacts */ :
                        strictNullChecks ? 7888800 /* ObjectStrictFacts */ : 16736160 /* ObjectFacts */;
            }
            if (flags & (16384 /* Void */ | 32768 /* Undefined */)) {
                return 9830144 /* UndefinedFacts */;
            }
            if (flags & 65536 /* Null */) {
                return 9363232 /* NullFacts */;
            }
            if (flags & 12288 /* ESSymbolLike */) {
                return strictNullChecks ? 7925520 /* SymbolStrictFacts */ : 16772880 /* SymbolFacts */;
            }
            if (flags & 67108864 /* NonPrimitive */) {
                return strictNullChecks ? 7888800 /* ObjectStrictFacts */ : 16736160 /* ObjectFacts */;
            }
            if (flags & 131072 /* Never */) {
                return 0 /* None */;
            }
            if (flags & 63176704 /* Instantiable */) {
                return getTypeFacts(getBaseConstraintOfType(type) || unknownType);
            }
            if (flags & 3145728 /* UnionOrIntersection */) {
                return getTypeFactsOfTypes(type.types);
            }
            return 16777215 /* All */;
        }
        function getTypeWithFacts(type, include) {
            return filterType(type, function (t) { return (getTypeFacts(t) & include) !== 0; });
        }
        function getTypeWithDefault(type, defaultExpression) {
            if (defaultExpression) {
                var defaultType = getTypeOfExpression(defaultExpression);
                return getUnionType([getTypeWithFacts(type, 524288 /* NEUndefined */), defaultType]);
            }
            return type;
        }
        function getTypeOfDestructuredProperty(type, name) {
            var nameType = getLiteralTypeFromPropertyName(name);
            if (!isTypeUsableAsPropertyName(nameType))
                return errorType;
            var text = getPropertyNameFromType(nameType);
            return getConstraintForLocation(getTypeOfPropertyOfType(type, text), name) ||
                isNumericLiteralName(text) && getIndexTypeOfType(type, 1 /* Number */) ||
                getIndexTypeOfType(type, 0 /* String */) ||
                errorType;
        }
        function getTypeOfDestructuredArrayElement(type, index) {
            return everyType(type, isTupleLikeType) && getTupleElementType(type, index) ||
                checkIteratedTypeOrElementType(65 /* Destructuring */, type, undefinedType, /*errorNode*/ undefined) ||
                errorType;
        }
        function getTypeOfDestructuredSpreadExpression(type) {
            return createArrayType(checkIteratedTypeOrElementType(65 /* Destructuring */, type, undefinedType, /*errorNode*/ undefined) || errorType);
        }
        function getAssignedTypeOfBinaryExpression(node) {
            var isDestructuringDefaultAssignment = node.parent.kind === 192 /* ArrayLiteralExpression */ && isDestructuringAssignmentTarget(node.parent) ||
                node.parent.kind === 281 /* PropertyAssignment */ && isDestructuringAssignmentTarget(node.parent.parent);
            return isDestructuringDefaultAssignment ?
                getTypeWithDefault(getAssignedType(node), node.right) :
                getTypeOfExpression(node.right);
        }
        function isDestructuringAssignmentTarget(parent) {
            return parent.parent.kind === 209 /* BinaryExpression */ && parent.parent.left === parent ||
                parent.parent.kind === 232 /* ForOfStatement */ && parent.parent.initializer === parent;
        }
        function getAssignedTypeOfArrayLiteralElement(node, element) {
            return getTypeOfDestructuredArrayElement(getAssignedType(node), node.elements.indexOf(element));
        }
        function getAssignedTypeOfSpreadExpression(node) {
            return getTypeOfDestructuredSpreadExpression(getAssignedType(node.parent));
        }
        function getAssignedTypeOfPropertyAssignment(node) {
            return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name);
        }
        function getAssignedTypeOfShorthandPropertyAssignment(node) {
            return getTypeWithDefault(getAssignedTypeOfPropertyAssignment(node), node.objectAssignmentInitializer);
        }
        function getAssignedType(node) {
            var parent = node.parent;
            switch (parent.kind) {
                case 231 /* ForInStatement */:
                    return stringType;
                case 232 /* ForOfStatement */:
                    return checkRightHandSideOfForOf(parent) || errorType;
                case 209 /* BinaryExpression */:
                    return getAssignedTypeOfBinaryExpression(parent);
                case 203 /* DeleteExpression */:
                    return undefinedType;
                case 192 /* ArrayLiteralExpression */:
                    return getAssignedTypeOfArrayLiteralElement(parent, node);
                case 213 /* SpreadElement */:
                    return getAssignedTypeOfSpreadExpression(parent);
                case 281 /* PropertyAssignment */:
                    return getAssignedTypeOfPropertyAssignment(parent);
                case 282 /* ShorthandPropertyAssignment */:
                    return getAssignedTypeOfShorthandPropertyAssignment(parent);
            }
            return errorType;
        }
        function getInitialTypeOfBindingElement(node) {
            var pattern = node.parent;
            var parentType = getInitialType(pattern.parent);
            var type = pattern.kind === 189 /* ObjectBindingPattern */ ?
                getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) :
                !node.dotDotDotToken ?
                    getTypeOfDestructuredArrayElement(parentType, pattern.elements.indexOf(node)) :
                    getTypeOfDestructuredSpreadExpression(parentType);
            return getTypeWithDefault(type, node.initializer);
        }
        function getTypeOfInitializer(node) {
            // Return the cached type if one is available. If the type of the variable was inferred
            // from its initializer, we'll already have cached the type. Otherwise we compute it now
            // without caching such that transient types are reflected.
            var links = getNodeLinks(node);
            return links.resolvedType || getTypeOfExpression(node);
        }
        function getInitialTypeOfVariableDeclaration(node) {
            if (node.initializer) {
                return getTypeOfInitializer(node.initializer);
            }
            if (node.parent.parent.kind === 231 /* ForInStatement */) {
                return stringType;
            }
            if (node.parent.parent.kind === 232 /* ForOfStatement */) {
                return checkRightHandSideOfForOf(node.parent.parent) || errorType;
            }
            return errorType;
        }
        function getInitialType(node) {
            return node.kind === 242 /* VariableDeclaration */ ?
                getInitialTypeOfVariableDeclaration(node) :
                getInitialTypeOfBindingElement(node);
        }
        function isEmptyArrayAssignment(node) {
            return node.kind === 242 /* VariableDeclaration */ && node.initializer &&
                isEmptyArrayLiteral(node.initializer) ||
                node.kind !== 191 /* BindingElement */ && node.parent.kind === 209 /* BinaryExpression */ &&
                    isEmptyArrayLiteral(node.parent.right);
        }
        function getReferenceCandidate(node) {
            switch (node.kind) {
                case 200 /* ParenthesizedExpression */:
                    return getReferenceCandidate(node.expression);
                case 209 /* BinaryExpression */:
                    switch (node.operatorToken.kind) {
                        case 62 /* EqualsToken */:
                            return getReferenceCandidate(node.left);
                        case 27 /* CommaToken */:
                            return getReferenceCandidate(node.right);
                    }
            }
            return node;
        }
        function getReferenceRoot(node) {
            var parent = node.parent;
            return parent.kind === 200 /* ParenthesizedExpression */ ||
                parent.kind === 209 /* BinaryExpression */ && parent.operatorToken.kind === 62 /* EqualsToken */ && parent.left === node ||
                parent.kind === 209 /* BinaryExpression */ && parent.operatorToken.kind === 27 /* CommaToken */ && parent.right === node ?
                getReferenceRoot(parent) : node;
        }
        function getTypeOfSwitchClause(clause) {
            if (clause.kind === 277 /* CaseClause */) {
                return getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression));
            }
            return neverType;
        }
        function getSwitchClauseTypes(switchStatement) {
            var links = getNodeLinks(switchStatement);
            if (!links.switchTypes) {
                links.switchTypes = [];
                for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) {
                    var clause = _a[_i];
                    links.switchTypes.push(getTypeOfSwitchClause(clause));
                }
            }
            return links.switchTypes;
        }
        function getSwitchClauseTypeOfWitnesses(switchStatement, retainDefault) {
            var witnesses = [];
            for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) {
                var clause = _a[_i];
                if (clause.kind === 277 /* CaseClause */) {
                    if (ts.isStringLiteralLike(clause.expression)) {
                        witnesses.push(clause.expression.text);
                        continue;
                    }
                    return ts.emptyArray;
                }
                if (retainDefault)
                    witnesses.push(/*explicitDefaultStatement*/ undefined);
            }
            return witnesses;
        }
        function eachTypeContainedIn(source, types) {
            return source.flags & 1048576 /* Union */ ? !ts.forEach(source.types, function (t) { return !ts.contains(types, t); }) : ts.contains(types, source);
        }
        function isTypeSubsetOf(source, target) {
            return source === target || target.flags & 1048576 /* Union */ && isTypeSubsetOfUnion(source, target);
        }
        function isTypeSubsetOfUnion(source, target) {
            if (source.flags & 1048576 /* Union */) {
                for (var _i = 0, _a = source.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (!containsType(target.types, t)) {
                        return false;
                    }
                }
                return true;
            }
            if (source.flags & 1024 /* EnumLiteral */ && getBaseTypeOfEnumLiteralType(source) === target) {
                return true;
            }
            return containsType(target.types, source);
        }
        function forEachType(type, f) {
            return type.flags & 1048576 /* Union */ ? ts.forEach(type.types, f) : f(type);
        }
        function everyType(type, f) {
            return type.flags & 1048576 /* Union */ ? ts.every(type.types, f) : f(type);
        }
        function filterType(type, f) {
            if (type.flags & 1048576 /* Union */) {
                var types = type.types;
                var filtered = ts.filter(types, f);
                return filtered === types ? type : getUnionTypeFromSortedList(filtered, type.objectFlags);
            }
            return type.flags & 131072 /* Never */ || f(type) ? type : neverType;
        }
        function countTypes(type) {
            return type.flags & 1048576 /* Union */ ? type.types.length : 1;
        }
        function mapType(type, mapper, noReductions) {
            if (type.flags & 131072 /* Never */) {
                return type;
            }
            if (!(type.flags & 1048576 /* Union */)) {
                return mapper(type);
            }
            var mappedTypes;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var t = _a[_i];
                var mapped = mapper(t);
                if (mapped) {
                    if (!mappedTypes) {
                        mappedTypes = [mapped];
                    }
                    else {
                        mappedTypes.push(mapped);
                    }
                }
            }
            return mappedTypes && getUnionType(mappedTypes, noReductions ? 0 /* None */ : 1 /* Literal */);
        }
        function extractTypesOfKind(type, kind) {
            return filterType(type, function (t) { return (t.flags & kind) !== 0; });
        }
        // Return a new type in which occurrences of the string and number primitive types in
        // typeWithPrimitives have been replaced with occurrences of string literals and numeric
        // literals in typeWithLiterals, respectively.
        function replacePrimitivesWithLiterals(typeWithPrimitives, typeWithLiterals) {
            if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 128 /* StringLiteral */) ||
                isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 256 /* NumberLiteral */) ||
                isTypeSubsetOf(bigintType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 2048 /* BigIntLiteral */)) {
                return mapType(typeWithPrimitives, function (t) {
                    return t.flags & 4 /* String */ ? extractTypesOfKind(typeWithLiterals, 4 /* String */ | 128 /* StringLiteral */) :
                        t.flags & 8 /* Number */ ? extractTypesOfKind(typeWithLiterals, 8 /* Number */ | 256 /* NumberLiteral */) :
                            t.flags & 64 /* BigInt */ ? extractTypesOfKind(typeWithLiterals, 64 /* BigInt */ | 2048 /* BigIntLiteral */) : t;
                });
            }
            return typeWithPrimitives;
        }
        function isIncomplete(flowType) {
            return flowType.flags === 0;
        }
        function getTypeFromFlowType(flowType) {
            return flowType.flags === 0 ? flowType.type : flowType;
        }
        function createFlowType(type, incomplete) {
            return incomplete ? { flags: 0, type: type } : type;
        }
        // An evolving array type tracks the element types that have so far been seen in an
        // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving
        // array types are ultimately converted into manifest array types (using getFinalArrayType)
        // and never escape the getFlowTypeOfReference function.
        function createEvolvingArrayType(elementType) {
            var result = createObjectType(256 /* EvolvingArray */);
            result.elementType = elementType;
            return result;
        }
        function getEvolvingArrayType(elementType) {
            return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType));
        }
        // When adding evolving array element types we do not perform subtype reduction. Instead,
        // we defer subtype reduction until the evolving array type is finalized into a manifest
        // array type.
        function addEvolvingArrayElementType(evolvingArrayType, node) {
            var elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node));
            return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
        }
        function createFinalArrayType(elementType) {
            return elementType.flags & 131072 /* Never */ ?
                autoArrayType :
                createArrayType(elementType.flags & 1048576 /* Union */ ?
                    getUnionType(elementType.types, 2 /* Subtype */) :
                    elementType);
        }
        // We perform subtype reduction upon obtaining the final array type from an evolving array type.
        function getFinalArrayType(evolvingArrayType) {
            return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType));
        }
        function finalizeEvolvingArrayType(type) {
            return ts.getObjectFlags(type) & 256 /* EvolvingArray */ ? getFinalArrayType(type) : type;
        }
        function getElementTypeOfEvolvingArrayType(type) {
            return ts.getObjectFlags(type) & 256 /* EvolvingArray */ ? type.elementType : neverType;
        }
        function isEvolvingArrayTypeList(types) {
            var hasEvolvingArrayType = false;
            for (var _i = 0, types_16 = types; _i < types_16.length; _i++) {
                var t = types_16[_i];
                if (!(t.flags & 131072 /* Never */)) {
                    if (!(ts.getObjectFlags(t) & 256 /* EvolvingArray */)) {
                        return false;
                    }
                    hasEvolvingArrayType = true;
                }
            }
            return hasEvolvingArrayType;
        }
        // At flow control branch or loop junctions, if the type along every antecedent code path
        // is an evolving array type, we construct a combined evolving array type. Otherwise we
        // finalize all evolving array types.
        function getUnionOrEvolvingArrayType(types, subtypeReduction) {
            return isEvolvingArrayTypeList(types) ?
                getEvolvingArrayType(getUnionType(ts.map(types, getElementTypeOfEvolvingArrayType))) :
                getUnionType(ts.sameMap(types, finalizeEvolvingArrayType), subtypeReduction);
        }
        // Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or
        // 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type.
        function isEvolvingArrayOperationTarget(node) {
            var root = getReferenceRoot(node);
            var parent = root.parent;
            var isLengthPushOrUnshift = ts.isPropertyAccessExpression(parent) && (parent.name.escapedText === "length" ||
                parent.parent.kind === 196 /* CallExpression */
                    && ts.isIdentifier(parent.name)
                    && ts.isPushOrUnshiftIdentifier(parent.name));
            var isElementAssignment = parent.kind === 195 /* ElementAccessExpression */ &&
                parent.expression === root &&
                parent.parent.kind === 209 /* BinaryExpression */ &&
                parent.parent.operatorToken.kind === 62 /* EqualsToken */ &&
                parent.parent.left === parent &&
                !ts.isAssignmentTarget(parent.parent) &&
                isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 296 /* NumberLike */);
            return isLengthPushOrUnshift || isElementAssignment;
        }
        function isDeclarationWithExplicitTypeAnnotation(declaration) {
            return (declaration.kind === 242 /* VariableDeclaration */ || declaration.kind === 156 /* Parameter */ ||
                declaration.kind === 159 /* PropertyDeclaration */ || declaration.kind === 158 /* PropertySignature */) &&
                !!ts.getEffectiveTypeAnnotationNode(declaration);
        }
        function getExplicitTypeOfSymbol(symbol, diagnostic) {
            if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 512 /* ValueModule */)) {
                return getTypeOfSymbol(symbol);
            }
            if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) {
                var declaration = symbol.valueDeclaration;
                if (declaration) {
                    if (isDeclarationWithExplicitTypeAnnotation(declaration)) {
                        return getTypeOfSymbol(symbol);
                    }
                    if (ts.isVariableDeclaration(declaration) && declaration.parent.parent.kind === 232 /* ForOfStatement */) {
                        var statement = declaration.parent.parent;
                        var expressionType = getTypeOfDottedName(statement.expression, /*diagnostic*/ undefined);
                        if (expressionType) {
                            var use = statement.awaitModifier ? 15 /* ForAwaitOf */ : 13 /* ForOf */;
                            return checkIteratedTypeOrElementType(use, expressionType, undefinedType, /*errorNode*/ undefined);
                        }
                    }
                    if (diagnostic) {
                        ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(declaration, ts.Diagnostics._0_needs_an_explicit_type_annotation, symbolToString(symbol)));
                    }
                }
            }
        }
        // We require the dotted function name in an assertion expression to be comprised of identifiers
        // that reference function, method, class or value module symbols; or variable, property or
        // parameter symbols with declarations that have explicit type annotations. Such references are
        // resolvable with no possibility of triggering circularities in control flow analysis.
        function getTypeOfDottedName(node, diagnostic) {
            if (!(node.flags & 16777216 /* InWithStatement */)) {
                switch (node.kind) {
                    case 75 /* Identifier */:
                        var symbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(node));
                        return getExplicitTypeOfSymbol(symbol.flags & 2097152 /* Alias */ ? resolveAlias(symbol) : symbol, diagnostic);
                    case 104 /* ThisKeyword */:
                        return getExplicitThisType(node);
                    case 102 /* SuperKeyword */:
                        return checkSuperExpression(node);
                    case 194 /* PropertyAccessExpression */:
                        var type = getTypeOfDottedName(node.expression, diagnostic);
                        var prop = type && getPropertyOfType(type, node.name.escapedText);
                        return prop && getExplicitTypeOfSymbol(prop, diagnostic);
                    case 200 /* ParenthesizedExpression */:
                        return getTypeOfDottedName(node.expression, diagnostic);
                }
            }
        }
        function getEffectsSignature(node) {
            var links = getNodeLinks(node);
            var signature = links.effectsSignature;
            if (signature === undefined) {
                // A call expression parented by an expression statement is a potential assertion. Other call
                // expressions are potential type predicate function calls. In order to avoid triggering
                // circularities in control flow analysis, we use getTypeOfDottedName when resolving the call
                // target expression of an assertion.
                var funcType = void 0;
                if (node.parent.kind === 226 /* ExpressionStatement */) {
                    funcType = getTypeOfDottedName(node.expression, /*diagnostic*/ undefined);
                }
                else if (node.expression.kind !== 102 /* SuperKeyword */) {
                    if (ts.isOptionalChain(node)) {
                        funcType = checkNonNullType(getOptionalExpressionType(checkExpression(node.expression), node.expression), node.expression);
                    }
                    else {
                        funcType = checkNonNullExpression(node.expression);
                    }
                }
                var signatures = getSignaturesOfType(funcType && getApparentType(funcType) || unknownType, 0 /* Call */);
                var candidate = signatures.length === 1 && !signatures[0].typeParameters ? signatures[0] :
                    ts.some(signatures, hasTypePredicateOrNeverReturnType) ? getResolvedSignature(node) :
                        undefined;
                signature = links.effectsSignature = candidate && hasTypePredicateOrNeverReturnType(candidate) ? candidate : unknownSignature;
            }
            return signature === unknownSignature ? undefined : signature;
        }
        function hasTypePredicateOrNeverReturnType(signature) {
            return !!(getTypePredicateOfSignature(signature) ||
                signature.declaration && (getReturnTypeFromAnnotation(signature.declaration) || unknownType).flags & 131072 /* Never */);
        }
        function getTypePredicateArgument(predicate, callExpression) {
            if (predicate.kind === 1 /* Identifier */ || predicate.kind === 3 /* AssertsIdentifier */) {
                return callExpression.arguments[predicate.parameterIndex];
            }
            var invokedExpression = ts.skipParentheses(callExpression.expression);
            return ts.isAccessExpression(invokedExpression) ? ts.skipParentheses(invokedExpression.expression) : undefined;
        }
        function reportFlowControlError(node) {
            var block = ts.findAncestor(node, ts.isFunctionOrModuleBlock);
            var sourceFile = ts.getSourceFileOfNode(node);
            var span = ts.getSpanOfTokenAtPosition(sourceFile, block.statements.pos);
            diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis));
        }
        function isReachableFlowNode(flow) {
            var result = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ false);
            lastFlowNode = flow;
            lastFlowNodeReachable = result;
            return result;
        }
        function isFalseExpression(expr) {
            var node = ts.skipParentheses(expr);
            return node.kind === 91 /* FalseKeyword */ || node.kind === 209 /* BinaryExpression */ && (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */ && (isFalseExpression(node.left) || isFalseExpression(node.right)) ||
                node.operatorToken.kind === 56 /* BarBarToken */ && isFalseExpression(node.left) && isFalseExpression(node.right));
        }
        function isReachableFlowNodeWorker(flow, noCacheCheck) {
            while (true) {
                if (flow === lastFlowNode) {
                    return lastFlowNodeReachable;
                }
                var flags = flow.flags;
                if (flags & 4096 /* Shared */) {
                    if (!noCacheCheck) {
                        var id = getFlowNodeId(flow);
                        var reachable = flowNodeReachable[id];
                        return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ true));
                    }
                    noCacheCheck = false;
                }
                if (flags & (16 /* Assignment */ | 96 /* Condition */ | 256 /* ArrayMutation */)) {
                    flow = flow.antecedent;
                }
                else if (flags & 512 /* Call */) {
                    var signature = getEffectsSignature(flow.node);
                    if (signature) {
                        var predicate = getTypePredicateOfSignature(signature);
                        if (predicate && predicate.kind === 3 /* AssertsIdentifier */) {
                            var predicateArgument = flow.node.arguments[predicate.parameterIndex];
                            if (predicateArgument && isFalseExpression(predicateArgument)) {
                                return false;
                            }
                        }
                        if (getReturnTypeOfSignature(signature).flags & 131072 /* Never */) {
                            return false;
                        }
                    }
                    flow = flow.antecedent;
                }
                else if (flags & 4 /* BranchLabel */) {
                    // A branching point is reachable if any branch is reachable.
                    return ts.some(flow.antecedents, function (f) { return isReachableFlowNodeWorker(f, /*noCacheCheck*/ false); });
                }
                else if (flags & 8 /* LoopLabel */) {
                    // A loop is reachable if the control flow path that leads to the top is reachable.
                    flow = flow.antecedents[0];
                }
                else if (flags & 128 /* SwitchClause */) {
                    // The control flow path representing an unmatched value in a switch statement with
                    // no default clause is unreachable if the switch statement is exhaustive.
                    if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) {
                        return false;
                    }
                    flow = flow.antecedent;
                }
                else if (flags & 1024 /* ReduceLabel */) {
                    // Cache is unreliable once we start adjusting labels
                    lastFlowNode = undefined;
                    var target = flow.target;
                    var saveAntecedents = target.antecedents;
                    target.antecedents = flow.antecedents;
                    var result = isReachableFlowNodeWorker(flow.antecedent, /*noCacheCheck*/ false);
                    target.antecedents = saveAntecedents;
                    return result;
                }
                else {
                    return !(flags & 1 /* Unreachable */);
                }
            }
        }
        function getFlowTypeOfReference(reference, declaredType, initialType, flowContainer, couldBeUninitialized) {
            if (initialType === void 0) { initialType = declaredType; }
            var key;
            var keySet = false;
            var flowDepth = 0;
            if (flowAnalysisDisabled) {
                return errorType;
            }
            if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & 133970943 /* Narrowable */)) {
                return declaredType;
            }
            flowInvocationCount++;
            var sharedFlowStart = sharedFlowCount;
            var evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode));
            sharedFlowCount = sharedFlowStart;
            // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation,
            // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations
            // on empty arrays are possible without implicit any errors and new element types can be inferred without
            // type mismatch errors.
            var resultType = ts.getObjectFlags(evolvedType) & 256 /* EvolvingArray */ && isEvolvingArrayOperationTarget(reference) ? autoArrayType : finalizeEvolvingArrayType(evolvedType);
            if (resultType === unreachableNeverType || reference.parent && reference.parent.kind === 218 /* NonNullExpression */ && getTypeWithFacts(resultType, 2097152 /* NEUndefinedOrNull */).flags & 131072 /* Never */) {
                return declaredType;
            }
            return resultType;
            function getOrSetCacheKey() {
                if (keySet) {
                    return key;
                }
                keySet = true;
                return key = getFlowCacheKey(reference, declaredType, initialType, flowContainer);
            }
            function getTypeAtFlowNode(flow) {
                if (flowDepth === 2000) {
                    // We have made 2000 recursive invocations. To avoid overflowing the call stack we report an error
                    // and disable further control flow analysis in the containing function or module body.
                    flowAnalysisDisabled = true;
                    reportFlowControlError(reference);
                    return errorType;
                }
                flowDepth++;
                while (true) {
                    var flags = flow.flags;
                    if (flags & 4096 /* Shared */) {
                        // We cache results of flow type resolution for shared nodes that were previously visited in
                        // the same getFlowTypeOfReference invocation. A node is considered shared when it is the
                        // antecedent of more than one node.
                        for (var i = sharedFlowStart; i < sharedFlowCount; i++) {
                            if (sharedFlowNodes[i] === flow) {
                                flowDepth--;
                                return sharedFlowTypes[i];
                            }
                        }
                    }
                    var type = void 0;
                    if (flags & 16 /* Assignment */) {
                        type = getTypeAtFlowAssignment(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 512 /* Call */) {
                        type = getTypeAtFlowCall(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 96 /* Condition */) {
                        type = getTypeAtFlowCondition(flow);
                    }
                    else if (flags & 128 /* SwitchClause */) {
                        type = getTypeAtSwitchClause(flow);
                    }
                    else if (flags & 12 /* Label */) {
                        if (flow.antecedents.length === 1) {
                            flow = flow.antecedents[0];
                            continue;
                        }
                        type = flags & 4 /* BranchLabel */ ?
                            getTypeAtFlowBranchLabel(flow) :
                            getTypeAtFlowLoopLabel(flow);
                    }
                    else if (flags & 256 /* ArrayMutation */) {
                        type = getTypeAtFlowArrayMutation(flow);
                        if (!type) {
                            flow = flow.antecedent;
                            continue;
                        }
                    }
                    else if (flags & 1024 /* ReduceLabel */) {
                        var target = flow.target;
                        var saveAntecedents = target.antecedents;
                        target.antecedents = flow.antecedents;
                        type = getTypeAtFlowNode(flow.antecedent);
                        target.antecedents = saveAntecedents;
                    }
                    else if (flags & 2 /* Start */) {
                        // Check if we should continue with the control flow of the containing function.
                        var container = flow.node;
                        if (container && container !== flowContainer &&
                            reference.kind !== 194 /* PropertyAccessExpression */ &&
                            reference.kind !== 195 /* ElementAccessExpression */ &&
                            reference.kind !== 104 /* ThisKeyword */) {
                            flow = container.flowNode;
                            continue;
                        }
                        // At the top of the flow we have the initial type.
                        type = initialType;
                    }
                    else {
                        // Unreachable code errors are reported in the binding phase. Here we
                        // simply return the non-auto declared type to reduce follow-on errors.
                        type = convertAutoToAny(declaredType);
                    }
                    if (flags & 4096 /* Shared */) {
                        // Record visited node and the associated type in the cache.
                        sharedFlowNodes[sharedFlowCount] = flow;
                        sharedFlowTypes[sharedFlowCount] = type;
                        sharedFlowCount++;
                    }
                    flowDepth--;
                    return type;
                }
            }
            function getInitialOrAssignedType(flow) {
                var node = flow.node;
                return getConstraintForLocation(node.kind === 242 /* VariableDeclaration */ || node.kind === 191 /* BindingElement */ ?
                    getInitialType(node) :
                    getAssignedType(node), reference);
            }
            function getTypeAtFlowAssignment(flow) {
                var node = flow.node;
                // Assignments only narrow the computed type if the declared type is a union type. Thus, we
                // only need to evaluate the assigned type if the declared type is a union type.
                if (isMatchingReference(reference, node)) {
                    if (!isReachableFlowNode(flow)) {
                        return unreachableNeverType;
                    }
                    if (ts.getAssignmentTargetKind(node) === 2 /* Compound */) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType));
                    }
                    if (declaredType === autoType || declaredType === autoArrayType) {
                        if (isEmptyArrayAssignment(node)) {
                            return getEvolvingArrayType(neverType);
                        }
                        var assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(flow));
                        return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType;
                    }
                    if (declaredType.flags & 1048576 /* Union */) {
                        return getAssignmentReducedType(declaredType, getInitialOrAssignedType(flow));
                    }
                    return declaredType;
                }
                // We didn't have a direct match. However, if the reference is a dotted name, this
                // may be an assignment to a left hand part of the reference. For example, for a
                // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case,
                // return the declared type.
                if (containsMatchingReference(reference, node)) {
                    if (!isReachableFlowNode(flow)) {
                        return unreachableNeverType;
                    }
                    // A matching dotted name might also be an expando property on a function *expression*,
                    // in which case we continue control flow analysis back to the function's declaration
                    if (ts.isVariableDeclaration(node) && (ts.isInJSFile(node) || ts.isVarConst(node))) {
                        var init = ts.getDeclaredExpandoInitializer(node);
                        if (init && (init.kind === 201 /* FunctionExpression */ || init.kind === 202 /* ArrowFunction */)) {
                            return getTypeAtFlowNode(flow.antecedent);
                        }
                    }
                    return declaredType;
                }
                // for (const _ in ref) acts as a nonnull on ref
                if (ts.isVariableDeclaration(node) && node.parent.parent.kind === 231 /* ForInStatement */ && isMatchingReference(reference, node.parent.parent.expression)) {
                    return getNonNullableTypeIfNeeded(getTypeFromFlowType(getTypeAtFlowNode(flow.antecedent)));
                }
                // Assignment doesn't affect reference
                return undefined;
            }
            function narrowTypeByAssertion(type, expr) {
                var node = ts.skipParentheses(expr);
                if (node.kind === 91 /* FalseKeyword */) {
                    return unreachableNeverType;
                }
                if (node.kind === 209 /* BinaryExpression */) {
                    if (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */) {
                        return narrowTypeByAssertion(narrowTypeByAssertion(type, node.left), node.right);
                    }
                    if (node.operatorToken.kind === 56 /* BarBarToken */) {
                        return getUnionType([narrowTypeByAssertion(type, node.left), narrowTypeByAssertion(type, node.right)]);
                    }
                }
                return narrowType(type, node, /*assumeTrue*/ true);
            }
            function getTypeAtFlowCall(flow) {
                var signature = getEffectsSignature(flow.node);
                if (signature) {
                    var predicate = getTypePredicateOfSignature(signature);
                    if (predicate && (predicate.kind === 2 /* AssertsThis */ || predicate.kind === 3 /* AssertsIdentifier */)) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        var type = finalizeEvolvingArrayType(getTypeFromFlowType(flowType));
                        var narrowedType = predicate.type ? narrowTypeByTypePredicate(type, predicate, flow.node, /*assumeTrue*/ true) :
                            predicate.kind === 3 /* AssertsIdentifier */ && predicate.parameterIndex >= 0 && predicate.parameterIndex < flow.node.arguments.length ? narrowTypeByAssertion(type, flow.node.arguments[predicate.parameterIndex]) :
                                type;
                        return narrowedType === type ? flowType : createFlowType(narrowedType, isIncomplete(flowType));
                    }
                    if (getReturnTypeOfSignature(signature).flags & 131072 /* Never */) {
                        return unreachableNeverType;
                    }
                }
                return undefined;
            }
            function getTypeAtFlowArrayMutation(flow) {
                if (declaredType === autoType || declaredType === autoArrayType) {
                    var node = flow.node;
                    var expr = node.kind === 196 /* CallExpression */ ?
                        node.expression.expression :
                        node.left.expression;
                    if (isMatchingReference(reference, getReferenceCandidate(expr))) {
                        var flowType = getTypeAtFlowNode(flow.antecedent);
                        var type = getTypeFromFlowType(flowType);
                        if (ts.getObjectFlags(type) & 256 /* EvolvingArray */) {
                            var evolvedType_1 = type;
                            if (node.kind === 196 /* CallExpression */) {
                                for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) {
                                    var arg = _a[_i];
                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, arg);
                                }
                            }
                            else {
                                // We must get the context free expression type so as to not recur in an uncached fashion on the LHS (which causes exponential blowup in compile time)
                                var indexType = getContextFreeTypeOfExpression(node.left.argumentExpression);
                                if (isTypeAssignableToKind(indexType, 296 /* NumberLike */)) {
                                    evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right);
                                }
                            }
                            return evolvedType_1 === type ? flowType : createFlowType(evolvedType_1, isIncomplete(flowType));
                        }
                        return flowType;
                    }
                }
                return undefined;
            }
            function getTypeAtFlowCondition(flow) {
                var flowType = getTypeAtFlowNode(flow.antecedent);
                var type = getTypeFromFlowType(flowType);
                if (type.flags & 131072 /* Never */) {
                    return flowType;
                }
                // If we have an antecedent type (meaning we're reachable in some way), we first
                // attempt to narrow the antecedent type. If that produces the never type, and if
                // the antecedent type is incomplete (i.e. a transient type in a loop), then we
                // take the type guard as an indication that control *could* reach here once we
                // have the complete type. We proceed by switching to the silent never type which
                // doesn't report errors when operators are applied to it. Note that this is the
                // *only* place a silent never type is ever generated.
                var assumeTrue = (flow.flags & 32 /* TrueCondition */) !== 0;
                var nonEvolvingType = finalizeEvolvingArrayType(type);
                var narrowedType = narrowType(nonEvolvingType, flow.node, assumeTrue);
                if (narrowedType === nonEvolvingType) {
                    return flowType;
                }
                var incomplete = isIncomplete(flowType);
                var resultType = incomplete && narrowedType.flags & 131072 /* Never */ ? silentNeverType : narrowedType;
                return createFlowType(resultType, incomplete);
            }
            function getTypeAtSwitchClause(flow) {
                var expr = flow.switchStatement.expression;
                var flowType = getTypeAtFlowNode(flow.antecedent);
                var type = getTypeFromFlowType(flowType);
                if (isMatchingReference(reference, expr)) {
                    type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
                }
                else if (expr.kind === 204 /* TypeOfExpression */ && isMatchingReference(reference, expr.expression)) {
                    type = narrowBySwitchOnTypeOf(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd);
                }
                else {
                    if (strictNullChecks) {
                        if (optionalChainContainsReference(expr, reference)) {
                            type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, function (t) { return !(t.flags & (32768 /* Undefined */ | 131072 /* Never */)); });
                        }
                        else if (expr.kind === 204 /* TypeOfExpression */ && optionalChainContainsReference(expr.expression, reference)) {
                            type = narrowTypeBySwitchOptionalChainContainment(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd, function (t) { return !(t.flags & 131072 /* Never */ || t.flags & 128 /* StringLiteral */ && t.value === "undefined"); });
                        }
                    }
                    if (isMatchingReferenceDiscriminant(expr, type)) {
                        type = narrowTypeByDiscriminant(type, expr, function (t) { return narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd); });
                    }
                }
                return createFlowType(type, isIncomplete(flowType));
            }
            function getTypeAtFlowBranchLabel(flow) {
                var antecedentTypes = [];
                var subtypeReduction = false;
                var seenIncomplete = false;
                var bypassFlow;
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    if (!bypassFlow && antecedent.flags & 128 /* SwitchClause */ && antecedent.clauseStart === antecedent.clauseEnd) {
                        // The antecedent is the bypass branch of a potentially exhaustive switch statement.
                        bypassFlow = antecedent;
                        continue;
                    }
                    var flowType = getTypeAtFlowNode(antecedent);
                    var type = getTypeFromFlowType(flowType);
                    // If the type at a particular antecedent path is the declared type and the
                    // reference is known to always be assigned (i.e. when declared and initial types
                    // are the same), there is no reason to process more antecedents since the only
                    // possible outcome is subtypes that will be removed in the final union type anyway.
                    if (type === declaredType && declaredType === initialType) {
                        return type;
                    }
                    ts.pushIfUnique(antecedentTypes, type);
                    // If an antecedent type is not a subset of the declared type, we need to perform
                    // subtype reduction. This happens when a "foreign" type is injected into the control
                    // flow using the instanceof operator or a user defined type predicate.
                    if (!isTypeSubsetOf(type, declaredType)) {
                        subtypeReduction = true;
                    }
                    if (isIncomplete(flowType)) {
                        seenIncomplete = true;
                    }
                }
                if (bypassFlow) {
                    var flowType = getTypeAtFlowNode(bypassFlow);
                    var type = getTypeFromFlowType(flowType);
                    // If the bypass flow contributes a type we haven't seen yet and the switch statement
                    // isn't exhaustive, process the bypass flow type. Since exhaustiveness checks increase
                    // the risk of circularities, we only want to perform them when they make a difference.
                    if (!ts.contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) {
                        if (type === declaredType && declaredType === initialType) {
                            return type;
                        }
                        antecedentTypes.push(type);
                        if (!isTypeSubsetOf(type, declaredType)) {
                            subtypeReduction = true;
                        }
                        if (isIncomplete(flowType)) {
                            seenIncomplete = true;
                        }
                    }
                }
                return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? 2 /* Subtype */ : 1 /* Literal */), seenIncomplete);
            }
            function getTypeAtFlowLoopLabel(flow) {
                // If we have previously computed the control flow type for the reference at
                // this flow loop junction, return the cached type.
                var id = getFlowNodeId(flow);
                var cache = flowLoopCaches[id] || (flowLoopCaches[id] = ts.createMap());
                var key = getOrSetCacheKey();
                if (!key) {
                    // No cache key is generated when binding patterns are in unnarrowable situations
                    return declaredType;
                }
                var cached = cache.get(key);
                if (cached) {
                    return cached;
                }
                // If this flow loop junction and reference are already being processed, return
                // the union of the types computed for each branch so far, marked as incomplete.
                // It is possible to see an empty array in cases where loops are nested and the
                // back edge of the outer loop reaches an inner loop that is already being analyzed.
                // In such cases we restart the analysis of the inner loop, which will then see
                // a non-empty in-process array for the outer loop and eventually terminate because
                // the first antecedent of a loop junction is always the non-looping control flow
                // path that leads to the top.
                for (var i = flowLoopStart; i < flowLoopCount; i++) {
                    if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) {
                        return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], 1 /* Literal */), /*incomplete*/ true);
                    }
                }
                // Add the flow loop junction and reference to the in-process stack and analyze
                // each antecedent code path.
                var antecedentTypes = [];
                var subtypeReduction = false;
                var firstAntecedentType;
                for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) {
                    var antecedent = _a[_i];
                    var flowType = void 0;
                    if (!firstAntecedentType) {
                        // The first antecedent of a loop junction is always the non-looping control
                        // flow path that leads to the top.
                        flowType = firstAntecedentType = getTypeAtFlowNode(antecedent);
                    }
                    else {
                        // All but the first antecedent are the looping control flow paths that lead
                        // back to the loop junction. We track these on the flow loop stack.
                        flowLoopNodes[flowLoopCount] = flow;
                        flowLoopKeys[flowLoopCount] = key;
                        flowLoopTypes[flowLoopCount] = antecedentTypes;
                        flowLoopCount++;
                        var saveFlowTypeCache = flowTypeCache;
                        flowTypeCache = undefined;
                        flowType = getTypeAtFlowNode(antecedent);
                        flowTypeCache = saveFlowTypeCache;
                        flowLoopCount--;
                        // If we see a value appear in the cache it is a sign that control flow analysis
                        // was restarted and completed by checkExpressionCached. We can simply pick up
                        // the resulting type and bail out.
                        var cached_1 = cache.get(key);
                        if (cached_1) {
                            return cached_1;
                        }
                    }
                    var type = getTypeFromFlowType(flowType);
                    ts.pushIfUnique(antecedentTypes, type);
                    // If an antecedent type is not a subset of the declared type, we need to perform
                    // subtype reduction. This happens when a "foreign" type is injected into the control
                    // flow using the instanceof operator or a user defined type predicate.
                    if (!isTypeSubsetOf(type, declaredType)) {
                        subtypeReduction = true;
                    }
                    // If the type at a particular antecedent path is the declared type there is no
                    // reason to process more antecedents since the only possible outcome is subtypes
                    // that will be removed in the final union type anyway.
                    if (type === declaredType) {
                        break;
                    }
                }
                // The result is incomplete if the first antecedent (the non-looping control flow path)
                // is incomplete.
                var result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? 2 /* Subtype */ : 1 /* Literal */);
                if (isIncomplete(firstAntecedentType)) {
                    return createFlowType(result, /*incomplete*/ true);
                }
                cache.set(key, result);
                return result;
            }
            function isMatchingReferenceDiscriminant(expr, computedType) {
                if (!(computedType.flags & 1048576 /* Union */) || !ts.isAccessExpression(expr)) {
                    return false;
                }
                var name = getAccessedPropertyName(expr);
                if (name === undefined) {
                    return false;
                }
                return isMatchingReference(reference, expr.expression) && isDiscriminantProperty(computedType, name);
            }
            function narrowTypeByDiscriminant(type, access, narrowType) {
                var propName = getAccessedPropertyName(access);
                if (propName === undefined) {
                    return type;
                }
                var propType = getTypeOfPropertyOfType(type, propName);
                if (!propType) {
                    return type;
                }
                var narrowedPropType = narrowType(propType);
                return filterType(type, function (t) {
                    var discriminantType = getTypeOfPropertyOrIndexSignature(t, propName);
                    return !(discriminantType.flags & 131072 /* Never */) && isTypeComparableTo(discriminantType, narrowedPropType);
                });
            }
            function narrowTypeByTruthiness(type, expr, assumeTrue) {
                if (isMatchingReference(reference, expr)) {
                    return getTypeWithFacts(type, assumeTrue ? 4194304 /* Truthy */ : 8388608 /* Falsy */);
                }
                if (strictNullChecks && assumeTrue && optionalChainContainsReference(expr, reference)) {
                    type = getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */);
                }
                if (isMatchingReferenceDiscriminant(expr, declaredType)) {
                    return narrowTypeByDiscriminant(type, expr, function (t) { return getTypeWithFacts(t, assumeTrue ? 4194304 /* Truthy */ : 8388608 /* Falsy */); });
                }
                return type;
            }
            function isTypePresencePossible(type, propName, assumeTrue) {
                if (getIndexInfoOfType(type, 0 /* String */)) {
                    return true;
                }
                var prop = getPropertyOfType(type, propName);
                if (prop) {
                    return prop.flags & 16777216 /* Optional */ ? true : assumeTrue;
                }
                return !assumeTrue;
            }
            function narrowByInKeyword(type, literal, assumeTrue) {
                if (type.flags & (1048576 /* Union */ | 524288 /* Object */) || isThisTypeParameter(type)) {
                    var propName_1 = ts.escapeLeadingUnderscores(literal.text);
                    return filterType(type, function (t) { return isTypePresencePossible(t, propName_1, assumeTrue); });
                }
                return type;
            }
            function narrowTypeByBinaryExpression(type, expr, assumeTrue) {
                switch (expr.operatorToken.kind) {
                    case 62 /* EqualsToken */:
                        return narrowTypeByTruthiness(narrowType(type, expr.right, assumeTrue), expr.left, assumeTrue);
                    case 34 /* EqualsEqualsToken */:
                    case 35 /* ExclamationEqualsToken */:
                    case 36 /* EqualsEqualsEqualsToken */:
                    case 37 /* ExclamationEqualsEqualsToken */:
                        var operator_1 = expr.operatorToken.kind;
                        var left_1 = getReferenceCandidate(expr.left);
                        var right_1 = getReferenceCandidate(expr.right);
                        if (left_1.kind === 204 /* TypeOfExpression */ && ts.isStringLiteralLike(right_1)) {
                            return narrowTypeByTypeof(type, left_1, operator_1, right_1, assumeTrue);
                        }
                        if (right_1.kind === 204 /* TypeOfExpression */ && ts.isStringLiteralLike(left_1)) {
                            return narrowTypeByTypeof(type, right_1, operator_1, left_1, assumeTrue);
                        }
                        if (isMatchingReference(reference, left_1)) {
                            return narrowTypeByEquality(type, operator_1, right_1, assumeTrue);
                        }
                        if (isMatchingReference(reference, right_1)) {
                            return narrowTypeByEquality(type, operator_1, left_1, assumeTrue);
                        }
                        if (strictNullChecks) {
                            if (optionalChainContainsReference(left_1, reference)) {
                                type = narrowTypeByOptionalChainContainment(type, operator_1, right_1, assumeTrue);
                            }
                            else if (optionalChainContainsReference(right_1, reference)) {
                                type = narrowTypeByOptionalChainContainment(type, operator_1, left_1, assumeTrue);
                            }
                        }
                        if (isMatchingReferenceDiscriminant(left_1, declaredType)) {
                            return narrowTypeByDiscriminant(type, left_1, function (t) { return narrowTypeByEquality(t, operator_1, right_1, assumeTrue); });
                        }
                        if (isMatchingReferenceDiscriminant(right_1, declaredType)) {
                            return narrowTypeByDiscriminant(type, right_1, function (t) { return narrowTypeByEquality(t, operator_1, left_1, assumeTrue); });
                        }
                        if (isMatchingConstructorReference(left_1)) {
                            return narrowTypeByConstructor(type, operator_1, right_1, assumeTrue);
                        }
                        if (isMatchingConstructorReference(right_1)) {
                            return narrowTypeByConstructor(type, operator_1, left_1, assumeTrue);
                        }
                        break;
                    case 98 /* InstanceOfKeyword */:
                        return narrowTypeByInstanceof(type, expr, assumeTrue);
                    case 97 /* InKeyword */:
                        var target = getReferenceCandidate(expr.right);
                        if (ts.isStringLiteralLike(expr.left) && isMatchingReference(reference, target)) {
                            return narrowByInKeyword(type, expr.left, assumeTrue);
                        }
                        break;
                    case 27 /* CommaToken */:
                        return narrowType(type, expr.right, assumeTrue);
                }
                return type;
            }
            function narrowTypeByOptionalChainContainment(type, operator, value, assumeTrue) {
                // We are in a branch of obj?.foo === value (or any one of the other equality operators). We narrow obj as follows:
                // When operator is === and type of value excludes undefined, null and undefined is removed from type of obj in true branch.
                // When operator is !== and type of value excludes undefined, null and undefined is removed from type of obj in false branch.
                // When operator is == and type of value excludes null and undefined, null and undefined is removed from type of obj in true branch.
                // When operator is != and type of value excludes null and undefined, null and undefined is removed from type of obj in false branch.
                // When operator is === and type of value is undefined, null and undefined is removed from type of obj in false branch.
                // When operator is !== and type of value is undefined, null and undefined is removed from type of obj in true branch.
                // When operator is == and type of value is null or undefined, null and undefined is removed from type of obj in false branch.
                // When operator is != and type of value is null or undefined, null and undefined is removed from type of obj in true branch.
                var equalsOperator = operator === 34 /* EqualsEqualsToken */ || operator === 36 /* EqualsEqualsEqualsToken */;
                var nullableFlags = operator === 34 /* EqualsEqualsToken */ || operator === 35 /* ExclamationEqualsToken */ ? 98304 /* Nullable */ : 32768 /* Undefined */;
                var valueType = getTypeOfExpression(value);
                // Note that we include any and unknown in the exclusion test because their domain includes null and undefined.
                var removeNullable = equalsOperator !== assumeTrue && everyType(valueType, function (t) { return !!(t.flags & nullableFlags); }) ||
                    equalsOperator === assumeTrue && everyType(valueType, function (t) { return !(t.flags & (3 /* AnyOrUnknown */ | nullableFlags)); });
                return removeNullable ? getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */) : type;
            }
            function narrowTypeByEquality(type, operator, value, assumeTrue) {
                if (type.flags & 1 /* Any */) {
                    return type;
                }
                if (operator === 35 /* ExclamationEqualsToken */ || operator === 37 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                var valueType = getTypeOfExpression(value);
                if ((type.flags & 2 /* Unknown */) && assumeTrue && (operator === 36 /* EqualsEqualsEqualsToken */ || operator === 37 /* ExclamationEqualsEqualsToken */)) {
                    if (valueType.flags & (131068 /* Primitive */ | 67108864 /* NonPrimitive */)) {
                        return valueType;
                    }
                    if (valueType.flags & 524288 /* Object */) {
                        return nonPrimitiveType;
                    }
                    return type;
                }
                if (valueType.flags & 98304 /* Nullable */) {
                    if (!strictNullChecks) {
                        return type;
                    }
                    var doubleEquals = operator === 34 /* EqualsEqualsToken */ || operator === 35 /* ExclamationEqualsToken */;
                    var facts = doubleEquals ?
                        assumeTrue ? 262144 /* EQUndefinedOrNull */ : 2097152 /* NEUndefinedOrNull */ :
                        valueType.flags & 65536 /* Null */ ?
                            assumeTrue ? 131072 /* EQNull */ : 1048576 /* NENull */ :
                            assumeTrue ? 65536 /* EQUndefined */ : 524288 /* NEUndefined */;
                    return getTypeWithFacts(type, facts);
                }
                if (type.flags & 67637251 /* NotUnionOrUnit */) {
                    return type;
                }
                if (assumeTrue) {
                    var filterFn = operator === 34 /* EqualsEqualsToken */ ?
                        (function (t) { return areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType); }) :
                        function (t) { return areTypesComparable(t, valueType); };
                    var narrowedType = filterType(type, filterFn);
                    return narrowedType.flags & 131072 /* Never */ ? type : replacePrimitivesWithLiterals(narrowedType, valueType);
                }
                if (isUnitType(valueType)) {
                    var regularType_1 = getRegularTypeOfLiteralType(valueType);
                    return filterType(type, function (t) { return isUnitType(t) ? !areTypesComparable(t, valueType) : getRegularTypeOfLiteralType(t) !== regularType_1; });
                }
                return type;
            }
            function narrowTypeByTypeof(type, typeOfExpr, operator, literal, assumeTrue) {
                // We have '==', '!=', '===', or !==' operator with 'typeof xxx' and string literal operands
                if (operator === 35 /* ExclamationEqualsToken */ || operator === 37 /* ExclamationEqualsEqualsToken */) {
                    assumeTrue = !assumeTrue;
                }
                var target = getReferenceCandidate(typeOfExpr.expression);
                if (!isMatchingReference(reference, target)) {
                    if (strictNullChecks && optionalChainContainsReference(target, reference) && assumeTrue === (literal.text !== "undefined")) {
                        return getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */);
                    }
                    return type;
                }
                if (type.flags & 1 /* Any */ && literal.text === "function") {
                    return type;
                }
                if (assumeTrue && type.flags & 2 /* Unknown */ && literal.text === "object") {
                    // The pattern x && typeof x === 'object', where x is of type unknown, narrows x to type object. We don't
                    // need to check for the reverse typeof x === 'object' && x since that already narrows correctly.
                    if (typeOfExpr.parent.parent.kind === 209 /* BinaryExpression */) {
                        var expr = typeOfExpr.parent.parent;
                        if (expr.operatorToken.kind === 55 /* AmpersandAmpersandToken */ && expr.right === typeOfExpr.parent && containsTruthyCheck(reference, expr.left)) {
                            return nonPrimitiveType;
                        }
                    }
                    return getUnionType([nonPrimitiveType, nullType]);
                }
                var facts = assumeTrue ?
                    typeofEQFacts.get(literal.text) || 128 /* TypeofEQHostObject */ :
                    typeofNEFacts.get(literal.text) || 32768 /* TypeofNEHostObject */;
                return getTypeWithFacts(assumeTrue ? mapType(type, narrowTypeForTypeof) : type, facts);
                function narrowTypeForTypeof(type) {
                    // We narrow a non-union type to an exact primitive type if the non-union type
                    // is a supertype of that primitive type. For example, type 'any' can be narrowed
                    // to one of the primitive types.
                    var targetType = literal.text === "function" ? globalFunctionType : typeofTypesByName.get(literal.text);
                    if (targetType) {
                        if (isTypeSubtypeOf(type, targetType)) {
                            return type;
                        }
                        if (isTypeSubtypeOf(targetType, type)) {
                            return targetType;
                        }
                        if (type.flags & 63176704 /* Instantiable */) {
                            var constraint = getBaseConstraintOfType(type) || anyType;
                            if (isTypeSubtypeOf(targetType, constraint)) {
                                return getIntersectionType([type, targetType]);
                            }
                        }
                    }
                    return type;
                }
            }
            function narrowTypeBySwitchOptionalChainContainment(type, switchStatement, clauseStart, clauseEnd, clauseCheck) {
                var everyClauseChecks = clauseStart !== clauseEnd && ts.every(getSwitchClauseTypes(switchStatement).slice(clauseStart, clauseEnd), clauseCheck);
                return everyClauseChecks ? getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */) : type;
            }
            function narrowTypeBySwitchOnDiscriminant(type, switchStatement, clauseStart, clauseEnd) {
                // We only narrow if all case expressions specify
                // values with unit types, except for the case where
                // `type` is unknown. In this instance we map object
                // types to the nonPrimitive type and narrow with that.
                var switchTypes = getSwitchClauseTypes(switchStatement);
                if (!switchTypes.length) {
                    return type;
                }
                var clauseTypes = switchTypes.slice(clauseStart, clauseEnd);
                var hasDefaultClause = clauseStart === clauseEnd || ts.contains(clauseTypes, neverType);
                if ((type.flags & 2 /* Unknown */) && !hasDefaultClause) {
                    var groundClauseTypes = void 0;
                    for (var i = 0; i < clauseTypes.length; i += 1) {
                        var t = clauseTypes[i];
                        if (t.flags & (131068 /* Primitive */ | 67108864 /* NonPrimitive */)) {
                            if (groundClauseTypes !== undefined) {
                                groundClauseTypes.push(t);
                            }
                        }
                        else if (t.flags & 524288 /* Object */) {
                            if (groundClauseTypes === undefined) {
                                groundClauseTypes = clauseTypes.slice(0, i);
                            }
                            groundClauseTypes.push(nonPrimitiveType);
                        }
                        else {
                            return type;
                        }
                    }
                    return getUnionType(groundClauseTypes === undefined ? clauseTypes : groundClauseTypes);
                }
                var discriminantType = getUnionType(clauseTypes);
                var caseType = discriminantType.flags & 131072 /* Never */ ? neverType :
                    replacePrimitivesWithLiterals(filterType(type, function (t) { return areTypesComparable(discriminantType, t); }), discriminantType);
                if (!hasDefaultClause) {
                    return caseType;
                }
                var defaultType = filterType(type, function (t) { return !(isUnitType(t) && ts.contains(switchTypes, getRegularTypeOfLiteralType(t))); });
                return caseType.flags & 131072 /* Never */ ? defaultType : getUnionType([caseType, defaultType]);
            }
            function getImpliedTypeFromTypeofCase(type, text) {
                switch (text) {
                    case "function":
                        return type.flags & 1 /* Any */ ? type : globalFunctionType;
                    case "object":
                        return type.flags & 2 /* Unknown */ ? getUnionType([nonPrimitiveType, nullType]) : type;
                    default:
                        return typeofTypesByName.get(text) || type;
                }
            }
            function narrowTypeForTypeofSwitch(candidate) {
                return function (type) {
                    if (isTypeSubtypeOf(candidate, type)) {
                        return candidate;
                    }
                    if (type.flags & 63176704 /* Instantiable */) {
                        var constraint = getBaseConstraintOfType(type) || anyType;
                        if (isTypeSubtypeOf(candidate, constraint)) {
                            return getIntersectionType([type, candidate]);
                        }
                    }
                    return type;
                };
            }
            function narrowBySwitchOnTypeOf(type, switchStatement, clauseStart, clauseEnd) {
                var switchWitnesses = getSwitchClauseTypeOfWitnesses(switchStatement, /*retainDefault*/ true);
                if (!switchWitnesses.length) {
                    return type;
                }
                //  Equal start and end denotes implicit fallthrough; undefined marks explicit default clause
                var defaultCaseLocation = ts.findIndex(switchWitnesses, function (elem) { return elem === undefined; });
                var hasDefaultClause = clauseStart === clauseEnd || (defaultCaseLocation >= clauseStart && defaultCaseLocation < clauseEnd);
                var clauseWitnesses;
                var switchFacts;
                if (defaultCaseLocation > -1) {
                    // We no longer need the undefined denoting an
                    // explicit default case. Remove the undefined and
                    // fix-up clauseStart and clauseEnd.  This means
                    // that we don't have to worry about undefined
                    // in the witness array.
                    var witnesses = switchWitnesses.filter(function (witness) { return witness !== undefined; });
                    // The adjusted clause start and end after removing the `default` statement.
                    var fixedClauseStart = defaultCaseLocation < clauseStart ? clauseStart - 1 : clauseStart;
                    var fixedClauseEnd = defaultCaseLocation < clauseEnd ? clauseEnd - 1 : clauseEnd;
                    clauseWitnesses = witnesses.slice(fixedClauseStart, fixedClauseEnd);
                    switchFacts = getFactsFromTypeofSwitch(fixedClauseStart, fixedClauseEnd, witnesses, hasDefaultClause);
                }
                else {
                    clauseWitnesses = switchWitnesses.slice(clauseStart, clauseEnd);
                    switchFacts = getFactsFromTypeofSwitch(clauseStart, clauseEnd, switchWitnesses, hasDefaultClause);
                }
                if (hasDefaultClause) {
                    return filterType(type, function (t) { return (getTypeFacts(t) & switchFacts) === switchFacts; });
                }
                /*
                  The implied type is the raw type suggested by a
                  value being caught in this clause.

                  When the clause contains a default case we ignore
                  the implied type and try to narrow using any facts
                  we can learn: see `switchFacts`.

                  Example:
                  switch (typeof x) {
                      case 'number':
                      case 'string': break;
                      default: break;
                      case 'number':
                      case 'boolean': break
                  }

                  In the first clause (case `number` and `string`) the
                  implied type is number | string.

                  In the default clause we de not compute an implied type.

                  In the third clause (case `number` and `boolean`)
                  the naive implied type is number | boolean, however
                  we use the type facts to narrow the implied type to
                  boolean. We know that number cannot be selected
                  because it is caught in the first clause.
                */
                var impliedType = getTypeWithFacts(getUnionType(clauseWitnesses.map(function (text) { return getImpliedTypeFromTypeofCase(type, text); })), switchFacts);
                if (impliedType.flags & 1048576 /* Union */) {
                    impliedType = getAssignmentReducedType(impliedType, getBaseConstraintOrType(type));
                }
                return getTypeWithFacts(mapType(type, narrowTypeForTypeofSwitch(impliedType)), switchFacts);
            }
            function isMatchingConstructorReference(expr) {
                return (ts.isPropertyAccessExpression(expr) && ts.idText(expr.name) === "constructor" ||
                    ts.isElementAccessExpression(expr) && ts.isStringLiteralLike(expr.argumentExpression) && expr.argumentExpression.text === "constructor") &&
                    isMatchingReference(reference, expr.expression);
            }
            function narrowTypeByConstructor(type, operator, identifier, assumeTrue) {
                // Do not narrow when checking inequality.
                if (assumeTrue ? (operator !== 34 /* EqualsEqualsToken */ && operator !== 36 /* EqualsEqualsEqualsToken */) : (operator !== 35 /* ExclamationEqualsToken */ && operator !== 37 /* ExclamationEqualsEqualsToken */)) {
                    return type;
                }
                // Get the type of the constructor identifier expression, if it is not a function then do not narrow.
                var identifierType = getTypeOfExpression(identifier);
                if (!isFunctionType(identifierType) && !isConstructorType(identifierType)) {
                    return type;
                }
                // Get the prototype property of the type identifier so we can find out its type.
                var prototypeProperty = getPropertyOfType(identifierType, "prototype");
                if (!prototypeProperty) {
                    return type;
                }
                // Get the type of the prototype, if it is undefined, or the global `Object` or `Function` types then do not narrow.
                var prototypeType = getTypeOfSymbol(prototypeProperty);
                var candidate = !isTypeAny(prototypeType) ? prototypeType : undefined;
                if (!candidate || candidate === globalObjectType || candidate === globalFunctionType) {
                    return type;
                }
                // If the type that is being narrowed is `any` then just return the `candidate` type since every type is a subtype of `any`.
                if (isTypeAny(type)) {
                    return candidate;
                }
                // Filter out types that are not considered to be "constructed by" the `candidate` type.
                return filterType(type, function (t) { return isConstructedBy(t, candidate); });
                function isConstructedBy(source, target) {
                    // If either the source or target type are a class type then we need to check that they are the same exact type.
                    // This is because you may have a class `A` that defines some set of properties, and another class `B`
                    // that defines the same set of properties as class `A`, in that case they are structurally the same
                    // type, but when you do something like `instanceOfA.constructor === B` it will return false.
                    if (source.flags & 524288 /* Object */ && ts.getObjectFlags(source) & 1 /* Class */ ||
                        target.flags & 524288 /* Object */ && ts.getObjectFlags(target) & 1 /* Class */) {
                        return source.symbol === target.symbol;
                    }
                    // For all other types just check that the `source` type is a subtype of the `target` type.
                    return isTypeSubtypeOf(source, target);
                }
            }
            function narrowTypeByInstanceof(type, expr, assumeTrue) {
                var left = getReferenceCandidate(expr.left);
                if (!isMatchingReference(reference, left)) {
                    if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) {
                        return getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */);
                    }
                    return type;
                }
                // Check that right operand is a function type with a prototype property
                var rightType = getTypeOfExpression(expr.right);
                if (!isTypeDerivedFrom(rightType, globalFunctionType)) {
                    return type;
                }
                var targetType;
                var prototypeProperty = getPropertyOfType(rightType, "prototype");
                if (prototypeProperty) {
                    // Target type is type of the prototype property
                    var prototypePropertyType = getTypeOfSymbol(prototypeProperty);
                    if (!isTypeAny(prototypePropertyType)) {
                        targetType = prototypePropertyType;
                    }
                }
                // Don't narrow from 'any' if the target type is exactly 'Object' or 'Function'
                if (isTypeAny(type) && (targetType === globalObjectType || targetType === globalFunctionType)) {
                    return type;
                }
                if (!targetType) {
                    var constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */);
                    targetType = constructSignatures.length ?
                        getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })) :
                        emptyObjectType;
                }
                return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom);
            }
            function getNarrowedType(type, candidate, assumeTrue, isRelated) {
                if (!assumeTrue) {
                    return filterType(type, function (t) { return !isRelated(t, candidate); });
                }
                // If the current type is a union type, remove all constituents that couldn't be instances of
                // the candidate type. If one or more constituents remain, return a union of those.
                if (type.flags & 1048576 /* Union */) {
                    var assignableType = filterType(type, function (t) { return isRelated(t, candidate); });
                    if (!(assignableType.flags & 131072 /* Never */)) {
                        return assignableType;
                    }
                }
                // If the candidate type is a subtype of the target type, narrow to the candidate type.
                // Otherwise, if the target type is assignable to the candidate type, keep the target type.
                // Otherwise, if the candidate type is assignable to the target type, narrow to the candidate
                // type. Otherwise, the types are completely unrelated, so narrow to an intersection of the
                // two types.
                return isTypeSubtypeOf(candidate, type) ? candidate :
                    isTypeAssignableTo(type, candidate) ? type :
                        isTypeAssignableTo(candidate, type) ? candidate :
                            getIntersectionType([type, candidate]);
            }
            function narrowTypeByCallExpression(type, callExpression, assumeTrue) {
                if (hasMatchingArgument(callExpression, reference)) {
                    var signature = assumeTrue || !ts.isCallChain(callExpression) ? getEffectsSignature(callExpression) : undefined;
                    var predicate = signature && getTypePredicateOfSignature(signature);
                    if (predicate && (predicate.kind === 0 /* This */ || predicate.kind === 1 /* Identifier */)) {
                        return narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue);
                    }
                }
                return type;
            }
            function narrowTypeByTypePredicate(type, predicate, callExpression, assumeTrue) {
                // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function'
                if (predicate.type && !(isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType))) {
                    var predicateArgument = getTypePredicateArgument(predicate, callExpression);
                    if (predicateArgument) {
                        if (isMatchingReference(reference, predicateArgument)) {
                            return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf);
                        }
                        if (strictNullChecks && assumeTrue && optionalChainContainsReference(predicateArgument, reference) &&
                            !(getTypeFacts(predicate.type) & 65536 /* EQUndefined */)) {
                            type = getTypeWithFacts(type, 2097152 /* NEUndefinedOrNull */);
                        }
                        if (isMatchingReferenceDiscriminant(predicateArgument, declaredType)) {
                            return narrowTypeByDiscriminant(type, predicateArgument, function (t) { return getNarrowedType(t, predicate.type, assumeTrue, isTypeSubtypeOf); });
                        }
                    }
                }
                return type;
            }
            // Narrow the given type based on the given expression having the assumed boolean value. The returned type
            // will be a subtype or the same type as the argument.
            function narrowType(type, expr, assumeTrue) {
                // for `a?.b`, we emulate a synthetic `a !== null && a !== undefined` condition for `a`
                if (ts.isExpressionOfOptionalChainRoot(expr) ||
                    ts.isBinaryExpression(expr.parent) && expr.parent.operatorToken.kind === 60 /* QuestionQuestionToken */ && expr.parent.left === expr) {
                    return narrowTypeByOptionality(type, expr, assumeTrue);
                }
                switch (expr.kind) {
                    case 75 /* Identifier */:
                    case 104 /* ThisKeyword */:
                    case 102 /* SuperKeyword */:
                    case 194 /* PropertyAccessExpression */:
                    case 195 /* ElementAccessExpression */:
                        return narrowTypeByTruthiness(type, expr, assumeTrue);
                    case 196 /* CallExpression */:
                        return narrowTypeByCallExpression(type, expr, assumeTrue);
                    case 200 /* ParenthesizedExpression */:
                        return narrowType(type, expr.expression, assumeTrue);
                    case 209 /* BinaryExpression */:
                        return narrowTypeByBinaryExpression(type, expr, assumeTrue);
                    case 207 /* PrefixUnaryExpression */:
                        if (expr.operator === 53 /* ExclamationToken */) {
                            return narrowType(type, expr.operand, !assumeTrue);
                        }
                        break;
                }
                return type;
            }
            function narrowTypeByOptionality(type, expr, assumePresent) {
                if (isMatchingReference(reference, expr)) {
                    return getTypeWithFacts(type, assumePresent ? 2097152 /* NEUndefinedOrNull */ : 262144 /* EQUndefinedOrNull */);
                }
                if (isMatchingReferenceDiscriminant(expr, declaredType)) {
                    return narrowTypeByDiscriminant(type, expr, function (t) { return getTypeWithFacts(t, assumePresent ? 2097152 /* NEUndefinedOrNull */ : 262144 /* EQUndefinedOrNull */); });
                }
                return type;
            }
        }
        function getTypeOfSymbolAtLocation(symbol, location) {
            symbol = symbol.exportSymbol || symbol;
            // If we have an identifier or a property access at the given location, if the location is
            // an dotted name expression, and if the location is not an assignment target, obtain the type
            // of the expression (which will reflect control flow analysis). If the expression indeed
            // resolved to the given symbol, return the narrowed type.
            if (location.kind === 75 /* Identifier */) {
                if (ts.isRightSideOfQualifiedNameOrPropertyAccess(location)) {
                    location = location.parent;
                }
                if (ts.isExpressionNode(location) && !ts.isAssignmentTarget(location)) {
                    var type = getTypeOfExpression(location);
                    if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
                        return type;
                    }
                }
            }
            // The location isn't a reference to the given symbol, meaning we're being asked
            // a hypothetical question of what type the symbol would have if there was a reference
            // to it at the given location. Since we have no control flow information for the
            // hypothetical reference (control flow information is created and attached by the
            // binder), we simply return the declared type of the symbol.
            return getTypeOfSymbol(symbol);
        }
        function getControlFlowContainer(node) {
            return ts.findAncestor(node.parent, function (node) {
                return ts.isFunctionLike(node) && !ts.getImmediatelyInvokedFunctionExpression(node) ||
                    node.kind === 250 /* ModuleBlock */ ||
                    node.kind === 290 /* SourceFile */ ||
                    node.kind === 159 /* PropertyDeclaration */;
            });
        }
        // Check if a parameter is assigned anywhere within its declaring function.
        function isParameterAssigned(symbol) {
            var func = ts.getRootDeclaration(symbol.valueDeclaration).parent;
            var links = getNodeLinks(func);
            if (!(links.flags & 8388608 /* AssignmentsMarked */)) {
                links.flags |= 8388608 /* AssignmentsMarked */;
                if (!hasParentWithAssignmentsMarked(func)) {
                    markParameterAssignments(func);
                }
            }
            return symbol.isAssigned || false;
        }
        function hasParentWithAssignmentsMarked(node) {
            return !!ts.findAncestor(node.parent, function (node) { return ts.isFunctionLike(node) && !!(getNodeLinks(node).flags & 8388608 /* AssignmentsMarked */); });
        }
        function markParameterAssignments(node) {
            if (node.kind === 75 /* Identifier */) {
                if (ts.isAssignmentTarget(node)) {
                    var symbol = getResolvedSymbol(node);
                    if (symbol.valueDeclaration && ts.getRootDeclaration(symbol.valueDeclaration).kind === 156 /* Parameter */) {
                        symbol.isAssigned = true;
                    }
                }
            }
            else {
                ts.forEachChild(node, markParameterAssignments);
            }
        }
        function isConstVariable(symbol) {
            return symbol.flags & 3 /* Variable */ && (getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */) !== 0 && getTypeOfSymbol(symbol) !== autoArrayType;
        }
        /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */
        function removeOptionalityFromDeclaredType(declaredType, declaration) {
            if (pushTypeResolution(declaration.symbol, 2 /* DeclaredType */)) {
                var annotationIncludesUndefined = strictNullChecks &&
                    declaration.kind === 156 /* Parameter */ &&
                    declaration.initializer &&
                    getFalsyFlags(declaredType) & 32768 /* Undefined */ &&
                    !(getFalsyFlags(checkExpression(declaration.initializer)) & 32768 /* Undefined */);
                popTypeResolution();
                return annotationIncludesUndefined ? getTypeWithFacts(declaredType, 524288 /* NEUndefined */) : declaredType;
            }
            else {
                reportCircularityError(declaration.symbol);
                return declaredType;
            }
        }
        function isConstraintPosition(node) {
            var parent = node.parent;
            return parent.kind === 194 /* PropertyAccessExpression */ ||
                parent.kind === 196 /* CallExpression */ && parent.expression === node ||
                parent.kind === 195 /* ElementAccessExpression */ && parent.expression === node ||
                parent.kind === 191 /* BindingElement */ && parent.name === node && !!parent.initializer;
        }
        function typeHasNullableConstraint(type) {
            return type.flags & 58982400 /* InstantiableNonPrimitive */ && maybeTypeOfKind(getBaseConstraintOfType(type) || unknownType, 98304 /* Nullable */);
        }
        function getConstraintForLocation(type, node) {
            // When a node is the left hand expression of a property access, element access, or call expression,
            // and the type of the node includes type variables with constraints that are nullable, we fetch the
            // apparent type of the node *before* performing control flow analysis such that narrowings apply to
            // the constraint type.
            if (type && isConstraintPosition(node) && forEachType(type, typeHasNullableConstraint)) {
                return mapType(getWidenedType(type), getBaseConstraintOrType);
            }
            return type;
        }
        function isExportOrExportExpression(location) {
            return !!ts.findAncestor(location, function (e) { return e.parent && ts.isExportAssignment(e.parent) && e.parent.expression === e && ts.isEntityNameExpression(e); });
        }
        function markAliasReferenced(symbol, location) {
            if (isNonLocalAlias(symbol, /*excludes*/ 111551 /* Value */) && !isInTypeQuery(location) && !getTypeOnlyAliasDeclaration(symbol)) {
                if (compilerOptions.preserveConstEnums && isExportOrExportExpression(location) || !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
                    markAliasSymbolAsReferenced(symbol);
                }
                else {
                    markConstEnumAliasAsReferenced(symbol);
                }
            }
        }
        function checkIdentifier(node) {
            var symbol = getResolvedSymbol(node);
            if (symbol === unknownSymbol) {
                return errorType;
            }
            // As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects.
            // Although in down-level emit of arrow function, we emit it using function expression which means that
            // arguments objects will be bound to the inner object; emitting arrow function natively in ES6, arguments objects
            // will be bound to non-arrow function that contain this arrow function. This results in inconsistent behavior.
            // To avoid that we will give an error to users if they use arguments objects in arrow function so that they
            // can explicitly bound arguments objects
            if (symbol === argumentsSymbol) {
                var container = ts.getContainingFunction(node);
                if (languageVersion < 2 /* ES2015 */) {
                    if (container.kind === 202 /* ArrowFunction */) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
                    }
                    else if (ts.hasModifier(container, 256 /* Async */)) {
                        error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method);
                    }
                }
                getNodeLinks(container).flags |= 8192 /* CaptureArguments */;
                return getTypeOfSymbol(symbol);
            }
            // We should only mark aliases as referenced if there isn't a local value declaration
            // for the symbol. Also, don't mark any property access expression LHS - checkPropertyAccessExpression will handle that
            if (!(node.parent && ts.isPropertyAccessExpression(node.parent) && node.parent.expression === node)) {
                markAliasReferenced(symbol, node);
            }
            var localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
            var declaration = localOrExportSymbol.valueDeclaration;
            if (localOrExportSymbol.flags & 32 /* Class */) {
                // Due to the emit for class decorators, any reference to the class from inside of the class body
                // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                // behavior of class names in ES6.
                if (declaration.kind === 245 /* ClassDeclaration */
                    && ts.nodeIsDecorated(declaration)) {
                    var container = ts.getContainingClass(node);
                    while (container !== undefined) {
                        if (container === declaration && container.name !== node) {
                            getNodeLinks(declaration).flags |= 16777216 /* ClassWithConstructorReference */;
                            getNodeLinks(node).flags |= 33554432 /* ConstructorReferenceInClass */;
                            break;
                        }
                        container = ts.getContainingClass(container);
                    }
                }
                else if (declaration.kind === 214 /* ClassExpression */) {
                    // When we emit a class expression with static members that contain a reference
                    // to the constructor in the initializer, we will need to substitute that
                    // binding with an alias as the class name is not in scope.
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    while (container.kind !== 290 /* SourceFile */) {
                        if (container.parent === declaration) {
                            if (container.kind === 159 /* PropertyDeclaration */ && ts.hasModifier(container, 32 /* Static */)) {
                                getNodeLinks(declaration).flags |= 16777216 /* ClassWithConstructorReference */;
                                getNodeLinks(node).flags |= 33554432 /* ConstructorReferenceInClass */;
                            }
                            break;
                        }
                        container = ts.getThisContainer(container, /*includeArrowFunctions*/ false);
                    }
                }
            }
            checkNestedBlockScopedBinding(node, symbol);
            var type = getConstraintForLocation(getTypeOfSymbol(localOrExportSymbol), node);
            var assignmentKind = ts.getAssignmentTargetKind(node);
            if (assignmentKind) {
                if (!(localOrExportSymbol.flags & 3 /* Variable */) &&
                    !(ts.isInJSFile(node) && localOrExportSymbol.flags & 512 /* ValueModule */)) {
                    error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable, symbolToString(symbol));
                    return errorType;
                }
                if (isReadonlySymbol(localOrExportSymbol)) {
                    if (localOrExportSymbol.flags & 3 /* Variable */) {
                        error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant, symbolToString(symbol));
                    }
                    else {
                        error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, symbolToString(symbol));
                    }
                    return errorType;
                }
            }
            var isAlias = localOrExportSymbol.flags & 2097152 /* Alias */;
            // We only narrow variables and parameters occurring in a non-assignment position. For all other
            // entities we simply return the declared type.
            if (localOrExportSymbol.flags & 3 /* Variable */) {
                if (assignmentKind === 1 /* Definite */) {
                    return type;
                }
            }
            else if (isAlias) {
                declaration = ts.find(symbol.declarations, isSomeImportDeclaration);
            }
            else {
                return type;
            }
            if (!declaration) {
                return type;
            }
            // The declaration container is the innermost function that encloses the declaration of the variable
            // or parameter. The flow container is the innermost function starting with which we analyze the control
            // flow graph to determine the control flow based type.
            var isParameter = ts.getRootDeclaration(declaration).kind === 156 /* Parameter */;
            var declarationContainer = getControlFlowContainer(declaration);
            var flowContainer = getControlFlowContainer(node);
            var isOuterVariable = flowContainer !== declarationContainer;
            var isSpreadDestructuringAssignmentTarget = node.parent && node.parent.parent && ts.isSpreadAssignment(node.parent) && isDestructuringAssignmentTarget(node.parent.parent);
            var isModuleExports = symbol.flags & 134217728 /* ModuleExports */;
            // When the control flow originates in a function expression or arrow function and we are referencing
            // a const variable or parameter from an outer function, we extend the origin of the control flow
            // analysis to include the immediately enclosing function.
            while (flowContainer !== declarationContainer && (flowContainer.kind === 201 /* FunctionExpression */ ||
                flowContainer.kind === 202 /* ArrowFunction */ || ts.isObjectLiteralOrClassExpressionMethod(flowContainer)) &&
                (isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) {
                flowContainer = getControlFlowContainer(flowContainer);
            }
            // We only look for uninitialized variables in strict null checking mode, and only when we can analyze
            // the entire control flow graph from the variable's declaration (i.e. when the flow container and
            // declaration container are the same).
            var assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || ts.isBindingElement(declaration) ||
                type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (3 /* AnyOrUnknown */ | 16384 /* Void */)) !== 0 ||
                    isInTypeQuery(node) || node.parent.kind === 263 /* ExportSpecifier */) ||
                node.parent.kind === 218 /* NonNullExpression */ ||
                declaration.kind === 242 /* VariableDeclaration */ && declaration.exclamationToken ||
                declaration.flags & 8388608 /* Ambient */;
            var initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, declaration) : type) :
                type === autoType || type === autoArrayType ? undefinedType :
                    getOptionalType(type);
            var flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized);
            // A variable is considered uninitialized when it is possible to analyze the entire control flow graph
            // from declaration to use, and when the variable's declared type doesn't include undefined but the
            // control flow based type does include undefined.
            if (!isEvolvingArrayOperationTarget(node) && (type === autoType || type === autoArrayType)) {
                if (flowType === autoType || flowType === autoArrayType) {
                    if (noImplicitAny) {
                        error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType));
                        error(node, ts.Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType));
                    }
                    return convertAutoToAny(flowType);
                }
            }
            else if (!assumeInitialized && !(getFalsyFlags(type) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) {
                error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol));
                // Return the declared type to reduce follow-on errors
                return type;
            }
            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
        }
        function isInsideFunction(node, threshold) {
            return !!ts.findAncestor(node, function (n) { return n === threshold ? "quit" : ts.isFunctionLike(n); });
        }
        function getPartOfForStatementContainingNode(node, container) {
            return ts.findAncestor(node, function (n) { return n === container ? "quit" : n === container.initializer || n === container.condition || n === container.incrementor || n === container.statement; });
        }
        function checkNestedBlockScopedBinding(node, symbol) {
            if (languageVersion >= 2 /* ES2015 */ ||
                (symbol.flags & (2 /* BlockScopedVariable */ | 32 /* Class */)) === 0 ||
                ts.isSourceFile(symbol.valueDeclaration) ||
                symbol.valueDeclaration.parent.kind === 280 /* CatchClause */) {
                return;
            }
            // 1. walk from the use site up to the declaration and check
            // if there is anything function like between declaration and use-site (is binding/class is captured in function).
            // 2. walk from the declaration up to the boundary of lexical environment and check
            // if there is an iteration statement in between declaration and boundary (is binding/class declared inside iteration statement)
            var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
            var usedInFunction = isInsideFunction(node.parent, container);
            var current = container;
            var containedInIterationStatement = false;
            while (current && !ts.nodeStartsNewLexicalEnvironment(current)) {
                if (ts.isIterationStatement(current, /*lookInLabeledStatements*/ false)) {
                    containedInIterationStatement = true;
                    break;
                }
                current = current.parent;
            }
            if (containedInIterationStatement) {
                if (usedInFunction) {
                    // mark iteration statement as containing block-scoped binding captured in some function
                    var capturesBlockScopeBindingInLoopBody = true;
                    if (ts.isForStatement(container)) {
                        var varDeclList = ts.getAncestor(symbol.valueDeclaration, 243 /* VariableDeclarationList */);
                        if (varDeclList && varDeclList.parent === container) {
                            var part = getPartOfForStatementContainingNode(node.parent, container);
                            if (part) {
                                var links = getNodeLinks(part);
                                links.flags |= 131072 /* ContainsCapturedBlockScopeBinding */;
                                var capturedBindings = links.capturedBlockScopeBindings || (links.capturedBlockScopeBindings = []);
                                ts.pushIfUnique(capturedBindings, symbol);
                                if (part === container.initializer) {
                                    capturesBlockScopeBindingInLoopBody = false; // Initializer is outside of loop body
                                }
                            }
                        }
                    }
                    if (capturesBlockScopeBindingInLoopBody) {
                        getNodeLinks(current).flags |= 65536 /* LoopWithCapturedBlockScopedBinding */;
                    }
                }
                // mark variables that are declared in loop initializer and reassigned inside the body of ForStatement.
                // if body of ForStatement will be converted to function then we'll need a extra machinery to propagate reassigned values back.
                if (ts.isForStatement(container)) {
                    var varDeclList = ts.getAncestor(symbol.valueDeclaration, 243 /* VariableDeclarationList */);
                    if (varDeclList && varDeclList.parent === container && isAssignedInBodyOfForStatement(node, container)) {
                        getNodeLinks(symbol.valueDeclaration).flags |= 4194304 /* NeedsLoopOutParameter */;
                    }
                }
                // set 'declared inside loop' bit on the block-scoped binding
                getNodeLinks(symbol.valueDeclaration).flags |= 524288 /* BlockScopedBindingInLoop */;
            }
            if (usedInFunction) {
                getNodeLinks(symbol.valueDeclaration).flags |= 262144 /* CapturedBlockScopedBinding */;
            }
        }
        function isBindingCapturedByNode(node, decl) {
            var links = getNodeLinks(node);
            return !!links && ts.contains(links.capturedBlockScopeBindings, getSymbolOfNode(decl));
        }
        function isAssignedInBodyOfForStatement(node, container) {
            // skip parenthesized nodes
            var current = node;
            while (current.parent.kind === 200 /* ParenthesizedExpression */) {
                current = current.parent;
            }
            // check if node is used as LHS in some assignment expression
            var isAssigned = false;
            if (ts.isAssignmentTarget(current)) {
                isAssigned = true;
            }
            else if ((current.parent.kind === 207 /* PrefixUnaryExpression */ || current.parent.kind === 208 /* PostfixUnaryExpression */)) {
                var expr = current.parent;
                isAssigned = expr.operator === 45 /* PlusPlusToken */ || expr.operator === 46 /* MinusMinusToken */;
            }
            if (!isAssigned) {
                return false;
            }
            // at this point we know that node is the target of assignment
            // now check that modification happens inside the statement part of the ForStatement
            return !!ts.findAncestor(current, function (n) { return n === container ? "quit" : n === container.statement; });
        }
        function captureLexicalThis(node, container) {
            getNodeLinks(node).flags |= 2 /* LexicalThis */;
            if (container.kind === 159 /* PropertyDeclaration */ || container.kind === 162 /* Constructor */) {
                var classNode = container.parent;
                getNodeLinks(classNode).flags |= 4 /* CaptureThis */;
            }
            else {
                getNodeLinks(container).flags |= 4 /* CaptureThis */;
            }
        }
        function findFirstSuperCall(n) {
            if (ts.isSuperCall(n)) {
                return n;
            }
            else if (ts.isFunctionLike(n)) {
                return undefined;
            }
            return ts.forEachChild(n, findFirstSuperCall);
        }
        /**
         * Return a cached result if super-statement is already found.
         * Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor
         *
         * @param constructor constructor-function to look for super statement
         */
        function getSuperCallInConstructor(constructor) {
            var links = getNodeLinks(constructor);
            // Only trying to find super-call if we haven't yet tried to find one.  Once we try, we will record the result
            if (links.hasSuperCall === undefined) {
                links.superCall = findFirstSuperCall(constructor.body);
                links.hasSuperCall = links.superCall ? true : false;
            }
            return links.superCall;
        }
        /**
         * Check if the given class-declaration extends null then return true.
         * Otherwise, return false
         * @param classDecl a class declaration to check if it extends null
         */
        function classDeclarationExtendsNull(classDecl) {
            var classSymbol = getSymbolOfNode(classDecl);
            var classInstanceType = getDeclaredTypeOfSymbol(classSymbol);
            var baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType);
            return baseConstructorType === nullWideningType;
        }
        function checkThisBeforeSuper(node, container, diagnosticMessage) {
            var containingClassDecl = container.parent;
            var baseTypeNode = ts.getClassExtendsHeritageElement(containingClassDecl);
            // If a containing class does not have extends clause or the class extends null
            // skip checking whether super statement is called before "this" accessing.
            if (baseTypeNode && !classDeclarationExtendsNull(containingClassDecl)) {
                var superCall = getSuperCallInConstructor(container);
                // We should give an error in the following cases:
                //      - No super-call
                //      - "this" is accessing before super-call.
                //          i.e super(this)
                //              this.x; super();
                // We want to make sure that super-call is done before accessing "this" so that
                // "this" is not accessed as a parameter of the super-call.
                if (!superCall || superCall.end > node.pos) {
                    // In ES6, super inside constructor of class-declaration has to precede "this" accessing
                    error(node, diagnosticMessage);
                }
            }
        }
        function checkThisExpression(node) {
            // Stop at the first arrow function so that we can
            // tell whether 'this' needs to be captured.
            var container = ts.getThisContainer(node, /* includeArrowFunctions */ true);
            var capturedByArrowFunction = false;
            if (container.kind === 162 /* Constructor */) {
                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class);
            }
            // Now skip arrow functions to get the "real" owner of 'this'.
            if (container.kind === 202 /* ArrowFunction */) {
                container = ts.getThisContainer(container, /* includeArrowFunctions */ false);
                capturedByArrowFunction = true;
            }
            switch (container.kind) {
                case 249 /* ModuleDeclaration */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_module_or_namespace_body);
                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    break;
                case 248 /* EnumDeclaration */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_current_location);
                    // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    break;
                case 162 /* Constructor */:
                    if (isInConstructorArgumentInitializer(node, container)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments);
                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    }
                    break;
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                    if (ts.hasModifier(container, 32 /* Static */) && !(compilerOptions.target === 99 /* ESNext */ && compilerOptions.useDefineForClassFields)) {
                        error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
                        // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
                    }
                    break;
                case 154 /* ComputedPropertyName */:
                    error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_computed_property_name);
                    break;
            }
            // When targeting es6, mark that we'll need to capture `this` in its lexically bound scope.
            if (capturedByArrowFunction && languageVersion < 2 /* ES2015 */) {
                captureLexicalThis(node, container);
            }
            var type = tryGetThisTypeAt(node, /*includeGlobalThis*/ true, container);
            if (noImplicitThis) {
                var globalThisType_1 = getTypeOfSymbol(globalThisSymbol);
                if (type === globalThisType_1 && capturedByArrowFunction) {
                    error(node, ts.Diagnostics.The_containing_arrow_function_captures_the_global_value_of_this);
                }
                else if (!type) {
                    // With noImplicitThis, functions may not reference 'this' if it has type 'any'
                    var diag = error(node, ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation);
                    if (!ts.isSourceFile(container)) {
                        var outsideThis = tryGetThisTypeAt(container);
                        if (outsideThis && outsideThis !== globalThisType_1) {
                            ts.addRelatedInfo(diag, ts.createDiagnosticForNode(container, ts.Diagnostics.An_outer_value_of_this_is_shadowed_by_this_container));
                        }
                    }
                }
            }
            return type || anyType;
        }
        function tryGetThisTypeAt(node, includeGlobalThis, container) {
            if (includeGlobalThis === void 0) { includeGlobalThis = true; }
            if (container === void 0) { container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); }
            var isInJS = ts.isInJSFile(node);
            if (ts.isFunctionLike(container) &&
                (!isInParameterInitializerBeforeContainingFunction(node) || ts.getThisParameter(container))) {
                // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated.
                // If this is a function in a JS file, it might be a class method.
                var className = getClassNameFromPrototypeMethod(container);
                if (isInJS && className) {
                    var classSymbol = checkExpression(className).symbol;
                    if (classSymbol && classSymbol.members && (classSymbol.flags & 16 /* Function */)) {
                        var classType = getDeclaredTypeOfSymbol(classSymbol).thisType;
                        if (classType) {
                            return getFlowTypeOfReference(node, classType);
                        }
                    }
                }
                // Check if it's a constructor definition, can be either a variable decl or function decl
                // i.e.
                //   * /** @constructor */ function [name]() { ... }
                //   * /** @constructor */ var x = function() { ... }
                else if (isInJS &&
                    (container.kind === 201 /* FunctionExpression */ || container.kind === 244 /* FunctionDeclaration */) &&
                    ts.getJSDocClassTag(container)) {
                    var classType = getDeclaredTypeOfSymbol(getMergedSymbol(container.symbol)).thisType;
                    return getFlowTypeOfReference(node, classType);
                }
                var thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container);
                if (thisType) {
                    return getFlowTypeOfReference(node, thisType);
                }
            }
            if (ts.isClassLike(container.parent)) {
                var symbol = getSymbolOfNode(container.parent);
                var type = ts.hasModifier(container, 32 /* Static */) ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType;
                return getFlowTypeOfReference(node, type);
            }
            if (isInJS) {
                var type = getTypeForThisExpressionFromJSDoc(container);
                if (type && type !== errorType) {
                    return getFlowTypeOfReference(node, type);
                }
            }
            if (ts.isSourceFile(container)) {
                // look up in the source file's locals or exports
                if (container.commonJsModuleIndicator) {
                    var fileSymbol = getSymbolOfNode(container);
                    return fileSymbol && getTypeOfSymbol(fileSymbol);
                }
                else if (includeGlobalThis) {
                    return getTypeOfSymbol(globalThisSymbol);
                }
            }
        }
        function getExplicitThisType(node) {
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
            if (ts.isFunctionLike(container)) {
                var signature = getSignatureFromDeclaration(container);
                if (signature.thisParameter) {
                    return getExplicitTypeOfSymbol(signature.thisParameter);
                }
            }
            if (ts.isClassLike(container.parent)) {
                var symbol = getSymbolOfNode(container.parent);
                return ts.hasModifier(container, 32 /* Static */) ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType;
            }
        }
        function getClassNameFromPrototypeMethod(container) {
            // Check if it's the RHS of a x.prototype.y = function [name]() { .... }
            if (container.kind === 201 /* FunctionExpression */ &&
                ts.isBinaryExpression(container.parent) &&
                ts.getAssignmentDeclarationKind(container.parent) === 3 /* PrototypeProperty */) {
                // Get the 'x' of 'x.prototype.y = container'
                return container.parent // x.prototype.y = container
                    .left // x.prototype.y
                    .expression // x.prototype
                    .expression; // x
            }
            // x.prototype = { method() { } }
            else if (container.kind === 161 /* MethodDeclaration */ &&
                container.parent.kind === 193 /* ObjectLiteralExpression */ &&
                ts.isBinaryExpression(container.parent.parent) &&
                ts.getAssignmentDeclarationKind(container.parent.parent) === 6 /* Prototype */) {
                return container.parent.parent.left.expression;
            }
            // x.prototype = { method: function() { } }
            else if (container.kind === 201 /* FunctionExpression */ &&
                container.parent.kind === 281 /* PropertyAssignment */ &&
                container.parent.parent.kind === 193 /* ObjectLiteralExpression */ &&
                ts.isBinaryExpression(container.parent.parent.parent) &&
                ts.getAssignmentDeclarationKind(container.parent.parent.parent) === 6 /* Prototype */) {
                return container.parent.parent.parent.left.expression;
            }
            // Object.defineProperty(x, "method", { value: function() { } });
            // Object.defineProperty(x, "method", { set: (x: () => void) => void });
            // Object.defineProperty(x, "method", { get: () => function() { }) });
            else if (container.kind === 201 /* FunctionExpression */ &&
                ts.isPropertyAssignment(container.parent) &&
                ts.isIdentifier(container.parent.name) &&
                (container.parent.name.escapedText === "value" || container.parent.name.escapedText === "get" || container.parent.name.escapedText === "set") &&
                ts.isObjectLiteralExpression(container.parent.parent) &&
                ts.isCallExpression(container.parent.parent.parent) &&
                container.parent.parent.parent.arguments[2] === container.parent.parent &&
                ts.getAssignmentDeclarationKind(container.parent.parent.parent) === 9 /* ObjectDefinePrototypeProperty */) {
                return container.parent.parent.parent.arguments[0].expression;
            }
            // Object.defineProperty(x, "method", { value() { } });
            // Object.defineProperty(x, "method", { set(x: () => void) {} });
            // Object.defineProperty(x, "method", { get() { return () => {} } });
            else if (ts.isMethodDeclaration(container) &&
                ts.isIdentifier(container.name) &&
                (container.name.escapedText === "value" || container.name.escapedText === "get" || container.name.escapedText === "set") &&
                ts.isObjectLiteralExpression(container.parent) &&
                ts.isCallExpression(container.parent.parent) &&
                container.parent.parent.arguments[2] === container.parent &&
                ts.getAssignmentDeclarationKind(container.parent.parent) === 9 /* ObjectDefinePrototypeProperty */) {
                return container.parent.parent.arguments[0].expression;
            }
        }
        function getTypeForThisExpressionFromJSDoc(node) {
            var jsdocType = ts.getJSDocType(node);
            if (jsdocType && jsdocType.kind === 300 /* JSDocFunctionType */) {
                var jsDocFunctionType = jsdocType;
                if (jsDocFunctionType.parameters.length > 0 &&
                    jsDocFunctionType.parameters[0].name &&
                    jsDocFunctionType.parameters[0].name.escapedText === "this" /* This */) {
                    return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type);
                }
            }
            var thisTag = ts.getJSDocThisTag(node);
            if (thisTag && thisTag.typeExpression) {
                return getTypeFromTypeNode(thisTag.typeExpression);
            }
        }
        function isInConstructorArgumentInitializer(node, constructorDecl) {
            return !!ts.findAncestor(node, function (n) { return ts.isFunctionLikeDeclaration(n) ? "quit" : n.kind === 156 /* Parameter */ && n.parent === constructorDecl; });
        }
        function checkSuperExpression(node) {
            var isCallExpression = node.parent.kind === 196 /* CallExpression */ && node.parent.expression === node;
            var container = ts.getSuperContainer(node, /*stopOnFunctions*/ true);
            var needToCaptureLexicalThis = false;
            // adjust the container reference in case if super is used inside arrow functions with arbitrarily deep nesting
            if (!isCallExpression) {
                while (container && container.kind === 202 /* ArrowFunction */) {
                    container = ts.getSuperContainer(container, /*stopOnFunctions*/ true);
                    needToCaptureLexicalThis = languageVersion < 2 /* ES2015 */;
                }
            }
            var canUseSuperExpression = isLegalUsageOfSuperExpression(container);
            var nodeCheckFlag = 0;
            if (!canUseSuperExpression) {
                // issue more specific error if super is used in computed property name
                // class A { foo() { return "1" }}
                // class B {
                //     [super.foo()]() {}
                // }
                var current = ts.findAncestor(node, function (n) { return n === container ? "quit" : n.kind === 154 /* ComputedPropertyName */; });
                if (current && current.kind === 154 /* ComputedPropertyName */) {
                    error(node, ts.Diagnostics.super_cannot_be_referenced_in_a_computed_property_name);
                }
                else if (isCallExpression) {
                    error(node, ts.Diagnostics.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors);
                }
                else if (!container || !container.parent || !(ts.isClassLike(container.parent) || container.parent.kind === 193 /* ObjectLiteralExpression */)) {
                    error(node, ts.Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions);
                }
                else {
                    error(node, ts.Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class);
                }
                return errorType;
            }
            if (!isCallExpression && container.kind === 162 /* Constructor */) {
                checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class);
            }
            if (ts.hasModifier(container, 32 /* Static */) || isCallExpression) {
                nodeCheckFlag = 512 /* SuperStatic */;
            }
            else {
                nodeCheckFlag = 256 /* SuperInstance */;
            }
            getNodeLinks(node).flags |= nodeCheckFlag;
            // Due to how we emit async functions, we need to specialize the emit for an async method that contains a `super` reference.
            // This is due to the fact that we emit the body of an async function inside of a generator function. As generator
            // functions cannot reference `super`, we emit a helper inside of the method body, but outside of the generator. This helper
            // uses an arrow function, which is permitted to reference `super`.
            //
            // There are two primary ways we can access `super` from within an async method. The first is getting the value of a property
            // or indexed access on super, either as part of a right-hand-side expression or call expression. The second is when setting the value
            // of a property or indexed access, either as part of an assignment expression or destructuring assignment.
            //
            // The simplest case is reading a value, in which case we will emit something like the following:
            //
            //  // ts
            //  ...
            //  async asyncMethod() {
            //    let x = await super.asyncMethod();
            //    return x;
            //  }
            //  ...
            //
            //  // js
            //  ...
            //  asyncMethod() {
            //      const _super = Object.create(null, {
            //        asyncMethod: { get: () => super.asyncMethod },
            //      });
            //      return __awaiter(this, arguments, Promise, function *() {
            //          let x = yield _super.asyncMethod.call(this);
            //          return x;
            //      });
            //  }
            //  ...
            //
            // The more complex case is when we wish to assign a value, especially as part of a destructuring assignment. As both cases
            // are legal in ES6, but also likely less frequent, we only emit setters if there is an assignment:
            //
            //  // ts
            //  ...
            //  async asyncMethod(ar: Promise<any[]>) {
            //      [super.a, super.b] = await ar;
            //  }
            //  ...
            //
            //  // js
            //  ...
            //  asyncMethod(ar) {
            //      const _super = Object.create(null, {
            //        a: { get: () => super.a, set: (v) => super.a = v },
            //        b: { get: () => super.b, set: (v) => super.b = v }
            //      };
            //      return __awaiter(this, arguments, Promise, function *() {
            //          [_super.a, _super.b] = yield ar;
            //      });
            //  }
            //  ...
            //
            // Creating an object that has getter and setters instead of just an accessor function is required for destructuring assignments
            // as a call expression cannot be used as the target of a destructuring assignment while a property access can.
            //
            // For element access expressions (`super[x]`), we emit a generic helper that forwards the element access in both situations.
            if (container.kind === 161 /* MethodDeclaration */ && ts.hasModifier(container, 256 /* Async */)) {
                if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) {
                    getNodeLinks(container).flags |= 4096 /* AsyncMethodWithSuperBinding */;
                }
                else {
                    getNodeLinks(container).flags |= 2048 /* AsyncMethodWithSuper */;
                }
            }
            if (needToCaptureLexicalThis) {
                // call expressions are allowed only in constructors so they should always capture correct 'this'
                // super property access expressions can also appear in arrow functions -
                // in this case they should also use correct lexical this
                captureLexicalThis(node.parent, container);
            }
            if (container.parent.kind === 193 /* ObjectLiteralExpression */) {
                if (languageVersion < 2 /* ES2015 */) {
                    error(node, ts.Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher);
                    return errorType;
                }
                else {
                    // for object literal assume that type of 'super' is 'any'
                    return anyType;
                }
            }
            // at this point the only legal case for parent is ClassLikeDeclaration
            var classLikeDeclaration = container.parent;
            if (!ts.getClassExtendsHeritageElement(classLikeDeclaration)) {
                error(node, ts.Diagnostics.super_can_only_be_referenced_in_a_derived_class);
                return errorType;
            }
            var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration));
            var baseClassType = classType && getBaseTypes(classType)[0];
            if (!baseClassType) {
                return errorType;
            }
            if (container.kind === 162 /* Constructor */ && isInConstructorArgumentInitializer(node, container)) {
                // issue custom error message for super property access in constructor arguments (to be aligned with old compiler)
                error(node, ts.Diagnostics.super_cannot_be_referenced_in_constructor_arguments);
                return errorType;
            }
            return nodeCheckFlag === 512 /* SuperStatic */
                ? getBaseConstructorTypeOfClass(classType)
                : getTypeWithThisArgument(baseClassType, classType.thisType);
            function isLegalUsageOfSuperExpression(container) {
                if (!container) {
                    return false;
                }
                if (isCallExpression) {
                    // TS 1.0 SPEC (April 2014): 4.8.1
                    // Super calls are only permitted in constructors of derived classes
                    return container.kind === 162 /* Constructor */;
                }
                else {
                    // TS 1.0 SPEC (April 2014)
                    // 'super' property access is allowed
                    // - In a constructor, instance member function, instance member accessor, or instance member variable initializer where this references a derived class instance
                    // - In a static member function or static member accessor
                    // topmost container must be something that is directly nested in the class declaration\object literal expression
                    if (ts.isClassLike(container.parent) || container.parent.kind === 193 /* ObjectLiteralExpression */) {
                        if (ts.hasModifier(container, 32 /* Static */)) {
                            return container.kind === 161 /* MethodDeclaration */ ||
                                container.kind === 160 /* MethodSignature */ ||
                                container.kind === 163 /* GetAccessor */ ||
                                container.kind === 164 /* SetAccessor */;
                        }
                        else {
                            return container.kind === 161 /* MethodDeclaration */ ||
                                container.kind === 160 /* MethodSignature */ ||
                                container.kind === 163 /* GetAccessor */ ||
                                container.kind === 164 /* SetAccessor */ ||
                                container.kind === 159 /* PropertyDeclaration */ ||
                                container.kind === 158 /* PropertySignature */ ||
                                container.kind === 162 /* Constructor */;
                        }
                    }
                }
                return false;
            }
        }
        function getContainingObjectLiteral(func) {
            return (func.kind === 161 /* MethodDeclaration */ ||
                func.kind === 163 /* GetAccessor */ ||
                func.kind === 164 /* SetAccessor */) && func.parent.kind === 193 /* ObjectLiteralExpression */ ? func.parent :
                func.kind === 201 /* FunctionExpression */ && func.parent.kind === 281 /* PropertyAssignment */ ? func.parent.parent :
                    undefined;
        }
        function getThisTypeArgument(type) {
            return ts.getObjectFlags(type) & 4 /* Reference */ && type.target === globalThisType ? getTypeArguments(type)[0] : undefined;
        }
        function getThisTypeFromContextualType(type) {
            return mapType(type, function (t) {
                return t.flags & 2097152 /* Intersection */ ? ts.forEach(t.types, getThisTypeArgument) : getThisTypeArgument(t);
            });
        }
        function getContextualThisParameterType(func) {
            if (func.kind === 202 /* ArrowFunction */) {
                return undefined;
            }
            if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
                var contextualSignature = getContextualSignature(func);
                if (contextualSignature) {
                    var thisParameter = contextualSignature.thisParameter;
                    if (thisParameter) {
                        return getTypeOfSymbol(thisParameter);
                    }
                }
            }
            var inJs = ts.isInJSFile(func);
            if (noImplicitThis || inJs) {
                var containingLiteral = getContainingObjectLiteral(func);
                if (containingLiteral) {
                    // We have an object literal method. Check if the containing object literal has a contextual type
                    // that includes a ThisType<T>. If so, T is the contextual type for 'this'. We continue looking in
                    // any directly enclosing object literals.
                    var contextualType = getApparentTypeOfContextualType(containingLiteral);
                    var literal = containingLiteral;
                    var type = contextualType;
                    while (type) {
                        var thisType = getThisTypeFromContextualType(type);
                        if (thisType) {
                            return instantiateType(thisType, getMapperFromContext(getInferenceContext(containingLiteral)));
                        }
                        if (literal.parent.kind !== 281 /* PropertyAssignment */) {
                            break;
                        }
                        literal = literal.parent.parent;
                        type = getApparentTypeOfContextualType(literal);
                    }
                    // There was no contextual ThisType<T> for the containing object literal, so the contextual type
                    // for 'this' is the non-null form of the contextual type for the containing object literal or
                    // the type of the object literal itself.
                    return getWidenedType(contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral));
                }
                // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the
                // contextual type for 'this' is 'obj'.
                var parent = ts.walkUpParenthesizedExpressions(func.parent);
                if (parent.kind === 209 /* BinaryExpression */ && parent.operatorToken.kind === 62 /* EqualsToken */) {
                    var target = parent.left;
                    if (ts.isAccessExpression(target)) {
                        var expression = target.expression;
                        // Don't contextually type `this` as `exports` in `exports.Point = function(x, y) { this.x = x; this.y = y; }`
                        if (inJs && ts.isIdentifier(expression)) {
                            var sourceFile = ts.getSourceFileOfNode(parent);
                            if (sourceFile.commonJsModuleIndicator && getResolvedSymbol(expression) === sourceFile.symbol) {
                                return undefined;
                            }
                        }
                        return getWidenedType(checkExpressionCached(expression));
                    }
                }
            }
            return undefined;
        }
        // Return contextual type of parameter or undefined if no contextual type is available
        function getContextuallyTypedParameterType(parameter) {
            var func = parameter.parent;
            if (!isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
                return undefined;
            }
            var iife = ts.getImmediatelyInvokedFunctionExpression(func);
            if (iife && iife.arguments) {
                var args = getEffectiveCallArguments(iife);
                var indexOfParameter = func.parameters.indexOf(parameter);
                if (parameter.dotDotDotToken) {
                    return getSpreadArgumentType(args, indexOfParameter, args.length, anyType, /*context*/ undefined);
                }
                var links = getNodeLinks(iife);
                var cached = links.resolvedSignature;
                links.resolvedSignature = anySignature;
                var type = indexOfParameter < args.length ?
                    getWidenedLiteralType(checkExpression(args[indexOfParameter])) :
                    parameter.initializer ? undefined : undefinedWideningType;
                links.resolvedSignature = cached;
                return type;
            }
            var contextualSignature = getContextualSignature(func);
            if (contextualSignature) {
                var index = func.parameters.indexOf(parameter) - (ts.getThisParameter(func) ? 1 : 0);
                return parameter.dotDotDotToken && ts.lastOrUndefined(func.parameters) === parameter ?
                    getRestTypeAtPosition(contextualSignature, index) :
                    tryGetTypeAtPosition(contextualSignature, index);
            }
        }
        function getContextualTypeForVariableLikeDeclaration(declaration) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
            if (typeNode) {
                return getTypeFromTypeNode(typeNode);
            }
            switch (declaration.kind) {
                case 156 /* Parameter */:
                    return getContextuallyTypedParameterType(declaration);
                case 191 /* BindingElement */:
                    return getContextualTypeForBindingElement(declaration);
                // By default, do nothing and return undefined - only parameters and binding elements have context implied by a parent
            }
        }
        function getContextualTypeForBindingElement(declaration) {
            var parent = declaration.parent.parent;
            var name = declaration.propertyName || declaration.name;
            var parentType = getContextualTypeForVariableLikeDeclaration(parent) ||
                parent.kind !== 191 /* BindingElement */ && parent.initializer && checkDeclarationInitializer(parent);
            if (parentType && !ts.isBindingPattern(name) && !ts.isComputedNonLiteralName(name)) {
                var nameType = getLiteralTypeFromPropertyName(name);
                if (isTypeUsableAsPropertyName(nameType)) {
                    var text = getPropertyNameFromType(nameType);
                    return getTypeOfPropertyOfType(parentType, text);
                }
            }
        }
        // In a variable, parameter or property declaration with a type annotation,
        //   the contextual type of an initializer expression is the type of the variable, parameter or property.
        // Otherwise, in a parameter declaration of a contextually typed function expression,
        //   the contextual type of an initializer expression is the contextual type of the parameter.
        // Otherwise, in a variable or parameter declaration with a binding pattern name,
        //   the contextual type of an initializer expression is the type implied by the binding pattern.
        // Otherwise, in a binding pattern inside a variable or parameter declaration,
        //   the contextual type of an initializer expression is the type annotation of the containing declaration, if present.
        function getContextualTypeForInitializerExpression(node) {
            var declaration = node.parent;
            if (ts.hasInitializer(declaration) && node === declaration.initializer) {
                var result = getContextualTypeForVariableLikeDeclaration(declaration);
                if (result) {
                    return result;
                }
                if (ts.isBindingPattern(declaration.name)) { // This is less a contextual type and more an implied shape - in some cases, this may be undesirable
                    return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false);
                }
            }
            return undefined;
        }
        function getContextualTypeForReturnExpression(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var functionFlags = ts.getFunctionFlags(func);
                if (functionFlags & 1 /* Generator */) { // AsyncGenerator function or Generator function
                    return undefined;
                }
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    if (functionFlags & 2 /* Async */) { // Async function
                        var contextualAwaitedType = mapType(contextualReturnType, getAwaitedTypeOfPromise);
                        return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
                    }
                    return contextualReturnType; // Regular function
                }
            }
            return undefined;
        }
        function getContextualTypeForAwaitOperand(node) {
            var contextualType = getContextualType(node);
            if (contextualType) {
                var contextualAwaitedType = getAwaitedType(contextualType);
                return contextualAwaitedType && getUnionType([contextualAwaitedType, createPromiseLikeType(contextualAwaitedType)]);
            }
            return undefined;
        }
        function getContextualTypeForYieldOperand(node) {
            var func = ts.getContainingFunction(node);
            if (func) {
                var functionFlags = ts.getFunctionFlags(func);
                var contextualReturnType = getContextualReturnType(func);
                if (contextualReturnType) {
                    return node.asteriskToken
                        ? contextualReturnType
                        : getIterationTypeOfGeneratorFunctionReturnType(0 /* Yield */, contextualReturnType, (functionFlags & 2 /* Async */) !== 0);
                }
            }
            return undefined;
        }
        function isInParameterInitializerBeforeContainingFunction(node) {
            var inBindingInitializer = false;
            while (node.parent && !ts.isFunctionLike(node.parent)) {
                if (ts.isParameter(node.parent) && (inBindingInitializer || node.parent.initializer === node)) {
                    return true;
                }
                if (ts.isBindingElement(node.parent) && node.parent.initializer === node) {
                    inBindingInitializer = true;
                }
                node = node.parent;
            }
            return false;
        }
        function getContextualIterationType(kind, functionDecl) {
            var isAsync = !!(ts.getFunctionFlags(functionDecl) & 2 /* Async */);
            var contextualReturnType = getContextualReturnType(functionDecl);
            if (contextualReturnType) {
                return getIterationTypeOfGeneratorFunctionReturnType(kind, contextualReturnType, isAsync)
                    || undefined;
            }
            return undefined;
        }
        function getContextualReturnType(functionDecl) {
            // If the containing function has a return type annotation, is a constructor, or is a get accessor whose
            // corresponding set accessor has a type annotation, return statements in the function are contextually typed
            var returnType = getReturnTypeFromAnnotation(functionDecl);
            if (returnType) {
                return returnType;
            }
            // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature
            // and that call signature is non-generic, return statements are contextually typed by the return type of the signature
            var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl);
            if (signature && !isResolvingReturnTypeOfSignature(signature)) {
                return getReturnTypeOfSignature(signature);
            }
            return undefined;
        }
        // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter.
        function getContextualTypeForArgument(callTarget, arg) {
            var args = getEffectiveCallArguments(callTarget);
            var argIndex = args.indexOf(arg); // -1 for e.g. the expression of a CallExpression, or the tag of a TaggedTemplateExpression
            return argIndex === -1 ? undefined : getContextualTypeForArgumentAtIndex(callTarget, argIndex);
        }
        function getContextualTypeForArgumentAtIndex(callTarget, argIndex) {
            // If we're already in the process of resolving the given signature, don't resolve again as
            // that could cause infinite recursion. Instead, return anySignature.
            var signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget);
            if (ts.isJsxOpeningLikeElement(callTarget) && argIndex === 0) {
                return getEffectiveFirstArgumentForJsxSignature(signature, callTarget);
            }
            return getTypeAtPosition(signature, argIndex);
        }
        function getContextualTypeForSubstitutionExpression(template, substitutionExpression) {
            if (template.parent.kind === 198 /* TaggedTemplateExpression */) {
                return getContextualTypeForArgument(template.parent, substitutionExpression);
            }
            return undefined;
        }
        function getContextualTypeForBinaryOperand(node, contextFlags) {
            var binaryExpression = node.parent;
            var left = binaryExpression.left, operatorToken = binaryExpression.operatorToken, right = binaryExpression.right;
            switch (operatorToken.kind) {
                case 62 /* EqualsToken */:
                    if (node !== right) {
                        return undefined;
                    }
                    var contextSensitive = getIsContextSensitiveAssignmentOrContextType(binaryExpression);
                    if (!contextSensitive) {
                        return undefined;
                    }
                    return contextSensitive === true ? getTypeOfExpression(left) : contextSensitive;
                case 56 /* BarBarToken */:
                case 60 /* QuestionQuestionToken */:
                    // When an || expression has a contextual type, the operands are contextually typed by that type, except
                    // when that type originates in a binding pattern, the right operand is contextually typed by the type of
                    // the left operand. When an || expression has no contextual type, the right operand is contextually typed
                    // by the type of the left operand, except for the special case of Javascript declarations of the form
                    // `namespace.prop = namespace.prop || {}`.
                    var type = getContextualType(binaryExpression, contextFlags);
                    return node === right && (type && type.pattern || !type && !ts.isDefaultedExpandoInitializer(binaryExpression)) ?
                        getTypeOfExpression(left) : type;
                case 55 /* AmpersandAmpersandToken */:
                case 27 /* CommaToken */:
                    return node === right ? getContextualType(binaryExpression, contextFlags) : undefined;
                default:
                    return undefined;
            }
        }
        // In an assignment expression, the right operand is contextually typed by the type of the left operand.
        // Don't do this for assignment declarations unless there is a type tag on the assignment, to avoid circularity from checking the right operand.
        function getIsContextSensitiveAssignmentOrContextType(binaryExpression) {
            var kind = ts.getAssignmentDeclarationKind(binaryExpression);
            switch (kind) {
                case 0 /* None */:
                    return true;
                case 5 /* Property */:
                case 1 /* ExportsProperty */:
                case 6 /* Prototype */:
                case 3 /* PrototypeProperty */:
                    // If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration.
                    // See `bindStaticPropertyAssignment` in `binder.ts`.
                    if (!binaryExpression.left.symbol) {
                        return true;
                    }
                    else {
                        var decl = binaryExpression.left.symbol.valueDeclaration;
                        if (!decl) {
                            return false;
                        }
                        var lhs = ts.cast(binaryExpression.left, ts.isAccessExpression);
                        var overallAnnotation = ts.getEffectiveTypeAnnotationNode(decl);
                        if (overallAnnotation) {
                            return getTypeFromTypeNode(overallAnnotation);
                        }
                        else if (ts.isIdentifier(lhs.expression)) {
                            var id = lhs.expression;
                            var parentSymbol = resolveName(id, id.escapedText, 111551 /* Value */, undefined, id.escapedText, /*isUse*/ true);
                            if (parentSymbol) {
                                var annotated = ts.getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration);
                                if (annotated) {
                                    var nameStr_1 = ts.getElementOrPropertyAccessName(lhs);
                                    if (nameStr_1 !== undefined) {
                                        var type = getTypeOfPropertyOfContextualType(getTypeFromTypeNode(annotated), nameStr_1);
                                        return type || false;
                                    }
                                }
                                return false;
                            }
                        }
                        return !ts.isInJSFile(decl);
                    }
                case 2 /* ModuleExports */:
                case 4 /* ThisProperty */:
                    if (!binaryExpression.symbol)
                        return true;
                    if (binaryExpression.symbol.valueDeclaration) {
                        var annotated = ts.getEffectiveTypeAnnotationNode(binaryExpression.symbol.valueDeclaration);
                        if (annotated) {
                            var type = getTypeFromTypeNode(annotated);
                            if (type) {
                                return type;
                            }
                        }
                    }
                    if (kind === 2 /* ModuleExports */)
                        return false;
                    var thisAccess = ts.cast(binaryExpression.left, ts.isAccessExpression);
                    if (!ts.isObjectLiteralMethod(ts.getThisContainer(thisAccess.expression, /*includeArrowFunctions*/ false))) {
                        return false;
                    }
                    var thisType = checkThisExpression(thisAccess.expression);
                    var nameStr = ts.getElementOrPropertyAccessName(thisAccess);
                    return nameStr !== undefined && thisType && getTypeOfPropertyOfContextualType(thisType, nameStr) || false;
                case 7 /* ObjectDefinePropertyValue */:
                case 8 /* ObjectDefinePropertyExports */:
                case 9 /* ObjectDefinePrototypeProperty */:
                    return ts.Debug.fail("Does not apply");
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function isCircularMappedProperty(symbol) {
            return !!(ts.getCheckFlags(symbol) & 262144 /* Mapped */ && !symbol.type && findResolutionCycleStartIndex(symbol, 0 /* Type */) >= 0);
        }
        function getTypeOfPropertyOfContextualType(type, name) {
            return mapType(type, function (t) {
                if (isGenericMappedType(t)) {
                    var constraint = getConstraintTypeFromMappedType(t);
                    var constraintOfConstraint = getBaseConstraintOfType(constraint) || constraint;
                    var propertyNameType = getLiteralType(ts.unescapeLeadingUnderscores(name));
                    if (isTypeAssignableTo(propertyNameType, constraintOfConstraint)) {
                        return substituteIndexedMappedType(t, propertyNameType);
                    }
                }
                else if (t.flags & 3670016 /* StructuredType */) {
                    var prop = getPropertyOfType(t, name);
                    if (prop) {
                        return isCircularMappedProperty(prop) ? undefined : getTypeOfSymbol(prop);
                    }
                    if (isTupleType(t)) {
                        var restType = getRestTypeOfTupleType(t);
                        if (restType && isNumericLiteralName(name) && +name >= 0) {
                            return restType;
                        }
                    }
                    return isNumericLiteralName(name) && getIndexTypeOfContextualType(t, 1 /* Number */) ||
                        getIndexTypeOfContextualType(t, 0 /* String */);
                }
                return undefined;
            }, /*noReductions*/ true);
        }
        function getIndexTypeOfContextualType(type, kind) {
            return mapType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); }, /*noReductions*/ true);
        }
        // In an object literal contextually typed by a type T, the contextual type of a property assignment is the type of
        // the matching property in T, if one exists. Otherwise, it is the type of the numeric index signature in T, if one
        // exists. Otherwise, it is the type of the string index signature in T, if one exists.
        function getContextualTypeForObjectLiteralMethod(node, contextFlags) {
            ts.Debug.assert(ts.isObjectLiteralMethod(node));
            if (node.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            return getContextualTypeForObjectLiteralElement(node, contextFlags);
        }
        function getContextualTypeForObjectLiteralElement(element, contextFlags) {
            var objectLiteral = element.parent;
            var type = getApparentTypeOfContextualType(objectLiteral, contextFlags);
            if (type) {
                if (!hasNonBindableDynamicName(element)) {
                    // For a (non-symbol) computed property, there is no reason to look up the name
                    // in the type. It will just be "__computed", which does not appear in any
                    // SymbolTable.
                    var symbolName_3 = getSymbolOfNode(element).escapedName;
                    var propertyType = getTypeOfPropertyOfContextualType(type, symbolName_3);
                    if (propertyType) {
                        return propertyType;
                    }
                }
                return isNumericName(element.name) && getIndexTypeOfContextualType(type, 1 /* Number */) ||
                    getIndexTypeOfContextualType(type, 0 /* String */);
            }
            return undefined;
        }
        // In an array literal contextually typed by a type T, the contextual type of an element expression at index N is
        // the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature,
        // it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated
        // type of T.
        function getContextualTypeForElementExpression(arrayContextualType, index) {
            return arrayContextualType && (getTypeOfPropertyOfContextualType(arrayContextualType, "" + index)
                || getIteratedTypeOrElementType(1 /* Element */, arrayContextualType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false));
        }
        // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type.
        function getContextualTypeForConditionalOperand(node, contextFlags) {
            var conditional = node.parent;
            return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional, contextFlags) : undefined;
        }
        function getContextualTypeForChildJsxExpression(node, child) {
            var attributesType = getApparentTypeOfContextualType(node.openingElement.tagName);
            // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
            var jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(node));
            if (!(attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "")) {
                return undefined;
            }
            var realChildren = getSemanticJsxChildren(node.children);
            var childIndex = realChildren.indexOf(child);
            var childFieldType = getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName);
            return childFieldType && (realChildren.length === 1 ? childFieldType : mapType(childFieldType, function (t) {
                if (isArrayLikeType(t)) {
                    return getIndexedAccessType(t, getLiteralType(childIndex));
                }
                else {
                    return t;
                }
            }, /*noReductions*/ true));
        }
        function getContextualTypeForJsxExpression(node) {
            var exprParent = node.parent;
            return ts.isJsxAttributeLike(exprParent)
                ? getContextualType(node)
                : ts.isJsxElement(exprParent)
                    ? getContextualTypeForChildJsxExpression(exprParent, node)
                    : undefined;
        }
        function getContextualTypeForJsxAttribute(attribute) {
            // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
            // which is a type of the parameter of the signature we are trying out.
            // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
            if (ts.isJsxAttribute(attribute)) {
                var attributesType = getApparentTypeOfContextualType(attribute.parent);
                if (!attributesType || isTypeAny(attributesType)) {
                    return undefined;
                }
                return getTypeOfPropertyOfContextualType(attributesType, attribute.name.escapedText);
            }
            else {
                return getContextualType(attribute.parent);
            }
        }
        // Return true if the given expression is possibly a discriminant value. We limit the kinds of
        // expressions we check to those that don't depend on their contextual type in order not to cause
        // recursive (and possibly infinite) invocations of getContextualType.
        function isPossiblyDiscriminantValue(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 100 /* NullKeyword */:
                case 75 /* Identifier */:
                case 146 /* UndefinedKeyword */:
                    return true;
                case 194 /* PropertyAccessExpression */:
                case 200 /* ParenthesizedExpression */:
                    return isPossiblyDiscriminantValue(node.expression);
                case 276 /* JsxExpression */:
                    return !node.expression || isPossiblyDiscriminantValue(node.expression);
            }
            return false;
        }
        function discriminateContextualTypeByObjectMembers(node, contextualType) {
            return discriminateTypeByDiscriminableItems(contextualType, ts.map(ts.filter(node.properties, function (p) { return !!p.symbol && p.kind === 281 /* PropertyAssignment */ && isPossiblyDiscriminantValue(p.initializer) && isDiscriminantProperty(contextualType, p.symbol.escapedName); }), function (prop) { return [function () { return checkExpression(prop.initializer); }, prop.symbol.escapedName]; }), isTypeAssignableTo, contextualType);
        }
        function discriminateContextualTypeByJSXAttributes(node, contextualType) {
            return discriminateTypeByDiscriminableItems(contextualType, ts.map(ts.filter(node.properties, function (p) { return !!p.symbol && p.kind === 273 /* JsxAttribute */ && isDiscriminantProperty(contextualType, p.symbol.escapedName) && (!p.initializer || isPossiblyDiscriminantValue(p.initializer)); }), function (prop) { return [!prop.initializer ? (function () { return trueType; }) : (function () { return checkExpression(prop.initializer); }), prop.symbol.escapedName]; }), isTypeAssignableTo, contextualType);
        }
        // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
        // be "pushed" onto a node using the contextualType property.
        function getApparentTypeOfContextualType(node, contextFlags) {
            var contextualType = ts.isObjectLiteralMethod(node) ?
                getContextualTypeForObjectLiteralMethod(node, contextFlags) :
                getContextualType(node, contextFlags);
            var instantiatedType = instantiateContextualType(contextualType, node, contextFlags);
            if (instantiatedType && !(contextFlags && contextFlags & 2 /* NoConstraints */ && instantiatedType.flags & 8650752 /* TypeVariable */)) {
                var apparentType = mapType(instantiatedType, getApparentType, /*noReductions*/ true);
                if (apparentType.flags & 1048576 /* Union */) {
                    if (ts.isObjectLiteralExpression(node)) {
                        return discriminateContextualTypeByObjectMembers(node, apparentType);
                    }
                    else if (ts.isJsxAttributes(node)) {
                        return discriminateContextualTypeByJSXAttributes(node, apparentType);
                    }
                }
                return apparentType;
            }
        }
        // If the given contextual type contains instantiable types and if a mapper representing
        // return type inferences is available, instantiate those types using that mapper.
        function instantiateContextualType(contextualType, node, contextFlags) {
            if (contextualType && maybeTypeOfKind(contextualType, 63176704 /* Instantiable */)) {
                var inferenceContext = getInferenceContext(node);
                // If no inferences have been made, nothing is gained from instantiating as type parameters
                // would just be replaced with their defaults similar to the apparent type.
                if (inferenceContext && ts.some(inferenceContext.inferences, hasInferenceCandidates)) {
                    // For contextual signatures we incorporate all inferences made so far, e.g. from return
                    // types as well as arguments to the left in a function call.
                    if (contextFlags && contextFlags & 1 /* Signature */) {
                        return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper);
                    }
                    // For other purposes (e.g. determining whether to produce literal types) we only
                    // incorporate inferences made from the return type in a function call.
                    if (inferenceContext.returnMapper) {
                        return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper);
                    }
                }
            }
            return contextualType;
        }
        // This function is similar to instantiateType, except that (a) it only instantiates types that
        // are classified as instantiable (i.e. it doesn't instantiate object types), and (b) it performs
        // no reductions on instantiated union types.
        function instantiateInstantiableTypes(type, mapper) {
            if (type.flags & 63176704 /* Instantiable */) {
                return instantiateType(type, mapper);
            }
            if (type.flags & 1048576 /* Union */) {
                return getUnionType(ts.map(type.types, function (t) { return instantiateInstantiableTypes(t, mapper); }), 0 /* None */);
            }
            if (type.flags & 2097152 /* Intersection */) {
                return getIntersectionType(ts.map(type.types, function (t) { return instantiateInstantiableTypes(t, mapper); }));
            }
            return type;
        }
        /**
         * Whoa! Do you really want to use this function?
         *
         * Unless you're trying to get the *non-apparent* type for a
         * value-literal type or you're authoring relevant portions of this algorithm,
         * you probably meant to use 'getApparentTypeOfContextualType'.
         * Otherwise this may not be very useful.
         *
         * In cases where you *are* working on this function, you should understand
         * when it is appropriate to use 'getContextualType' and 'getApparentTypeOfContextualType'.
         *
         *   - Use 'getContextualType' when you are simply going to propagate the result to the expression.
         *   - Use 'getApparentTypeOfContextualType' when you're going to need the members of the type.
         *
         * @param node the expression whose contextual type will be returned.
         * @returns the contextual type of an expression.
         */
        function getContextualType(node, contextFlags) {
            if (node.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            if (node.contextualType) {
                return node.contextualType;
            }
            var parent = node.parent;
            switch (parent.kind) {
                case 242 /* VariableDeclaration */:
                case 156 /* Parameter */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 191 /* BindingElement */:
                    return getContextualTypeForInitializerExpression(node);
                case 202 /* ArrowFunction */:
                case 235 /* ReturnStatement */:
                    return getContextualTypeForReturnExpression(node);
                case 212 /* YieldExpression */:
                    return getContextualTypeForYieldOperand(parent);
                case 206 /* AwaitExpression */:
                    return getContextualTypeForAwaitOperand(parent);
                case 196 /* CallExpression */:
                    if (parent.expression.kind === 96 /* ImportKeyword */) {
                        return stringType;
                    }
                /* falls through */
                case 197 /* NewExpression */:
                    return getContextualTypeForArgument(parent, node);
                case 199 /* TypeAssertionExpression */:
                case 217 /* AsExpression */:
                    return ts.isConstTypeReference(parent.type) ? undefined : getTypeFromTypeNode(parent.type);
                case 209 /* BinaryExpression */:
                    return getContextualTypeForBinaryOperand(node, contextFlags);
                case 281 /* PropertyAssignment */:
                case 282 /* ShorthandPropertyAssignment */:
                    return getContextualTypeForObjectLiteralElement(parent, contextFlags);
                case 283 /* SpreadAssignment */:
                    return getApparentTypeOfContextualType(parent.parent, contextFlags);
                case 192 /* ArrayLiteralExpression */: {
                    var arrayLiteral = parent;
                    var type = getApparentTypeOfContextualType(arrayLiteral, contextFlags);
                    return getContextualTypeForElementExpression(type, ts.indexOfNode(arrayLiteral.elements, node));
                }
                case 210 /* ConditionalExpression */:
                    return getContextualTypeForConditionalOperand(node, contextFlags);
                case 221 /* TemplateSpan */:
                    ts.Debug.assert(parent.parent.kind === 211 /* TemplateExpression */);
                    return getContextualTypeForSubstitutionExpression(parent.parent, node);
                case 200 /* ParenthesizedExpression */: {
                    // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
                    var tag = ts.isInJSFile(parent) ? ts.getJSDocTypeTag(parent) : undefined;
                    return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent, contextFlags);
                }
                case 276 /* JsxExpression */:
                    return getContextualTypeForJsxExpression(parent);
                case 273 /* JsxAttribute */:
                case 275 /* JsxSpreadAttribute */:
                    return getContextualTypeForJsxAttribute(parent);
                case 268 /* JsxOpeningElement */:
                case 267 /* JsxSelfClosingElement */:
                    return getContextualJsxElementAttributesType(parent, contextFlags);
            }
            return undefined;
        }
        function getInferenceContext(node) {
            var ancestor = ts.findAncestor(node, function (n) { return !!n.inferenceContext; });
            return ancestor && ancestor.inferenceContext;
        }
        function getContextualJsxElementAttributesType(node, contextFlags) {
            if (ts.isJsxOpeningElement(node) && node.parent.contextualType && contextFlags !== 4 /* Completions */) {
                // Contextually applied type is moved from attributes up to the outer jsx attributes so when walking up from the children they get hit
                // _However_ to hit them from the _attributes_ we must look for them here; otherwise we'll used the declared type
                // (as below) instead!
                return node.parent.contextualType;
            }
            return getContextualTypeForArgumentAtIndex(node, 0);
        }
        function getEffectiveFirstArgumentForJsxSignature(signature, node) {
            return getJsxReferenceKind(node) !== 0 /* Component */
                ? getJsxPropsTypeFromCallSignature(signature, node)
                : getJsxPropsTypeFromClassType(signature, node);
        }
        function getJsxPropsTypeFromCallSignature(sig, context) {
            var propsType = getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType);
            propsType = getJsxManagedAttributesFromLocatedAttributes(context, getJsxNamespaceAt(context), propsType);
            var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
            if (intrinsicAttribs !== errorType) {
                propsType = intersectTypes(intrinsicAttribs, propsType);
            }
            return propsType;
        }
        function getJsxPropsTypeForSignatureFromMember(sig, forcedLookupLocation) {
            if (sig.unionSignatures) {
                // JSX Elements using the legacy `props`-field based lookup (eg, react class components) need to treat the `props` member as an input
                // instead of an output position when resolving the signature. We need to go back to the input signatures of the composite signature,
                // get the type of `props` on each return type individually, and then _intersect them_, rather than union them (as would normally occur
                // for a union signature). It's an unfortunate quirk of looking in the output of the signature for the type we want to use for the input.
                // The default behavior of `getTypeOfFirstParameterOfSignatureWithFallback` when no `props` member name is defined is much more sane.
                var results = [];
                for (var _i = 0, _a = sig.unionSignatures; _i < _a.length; _i++) {
                    var signature = _a[_i];
                    var instance = getReturnTypeOfSignature(signature);
                    if (isTypeAny(instance)) {
                        return instance;
                    }
                    var propType = getTypeOfPropertyOfType(instance, forcedLookupLocation);
                    if (!propType) {
                        return;
                    }
                    results.push(propType);
                }
                return getIntersectionType(results);
            }
            var instanceType = getReturnTypeOfSignature(sig);
            return isTypeAny(instanceType) ? instanceType : getTypeOfPropertyOfType(instanceType, forcedLookupLocation);
        }
        function getStaticTypeOfReferencedJsxConstructor(context) {
            if (isJsxIntrinsicIdentifier(context.tagName)) {
                var result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(context);
                var fakeSignature = createSignatureForJSXIntrinsic(context, result);
                return getOrCreateTypeFromSignature(fakeSignature);
            }
            var tagType = checkExpressionCached(context.tagName);
            if (tagType.flags & 128 /* StringLiteral */) {
                var result = getIntrinsicAttributesTypeFromStringLiteralType(tagType, context);
                if (!result) {
                    return errorType;
                }
                var fakeSignature = createSignatureForJSXIntrinsic(context, result);
                return getOrCreateTypeFromSignature(fakeSignature);
            }
            return tagType;
        }
        function getJsxManagedAttributesFromLocatedAttributes(context, ns, attributesType) {
            var managedSym = getJsxLibraryManagedAttributes(ns);
            if (managedSym) {
                var declaredManagedType = getDeclaredTypeOfSymbol(managedSym);
                var ctorType = getStaticTypeOfReferencedJsxConstructor(context);
                if (ts.length(declaredManagedType.typeParameters) >= 2) {
                    var args = fillMissingTypeArguments([ctorType, attributesType], declaredManagedType.typeParameters, 2, ts.isInJSFile(context));
                    return createTypeReference(declaredManagedType, args);
                }
                else if (ts.length(declaredManagedType.aliasTypeArguments) >= 2) {
                    var args = fillMissingTypeArguments([ctorType, attributesType], declaredManagedType.aliasTypeArguments, 2, ts.isInJSFile(context));
                    return getTypeAliasInstantiation(declaredManagedType.aliasSymbol, args);
                }
            }
            return attributesType;
        }
        function getJsxPropsTypeFromClassType(sig, context) {
            var ns = getJsxNamespaceAt(context);
            var forcedLookupLocation = getJsxElementPropertiesName(ns);
            var attributesType = forcedLookupLocation === undefined
                // If there is no type ElementAttributesProperty, return the type of the first parameter of the signature, which should be the props type
                ? getTypeOfFirstParameterOfSignatureWithFallback(sig, unknownType)
                : forcedLookupLocation === ""
                    // If there is no e.g. 'props' member in ElementAttributesProperty, use the element class type instead
                    ? getReturnTypeOfSignature(sig)
                    // Otherwise get the type of the property on the signature return type
                    : getJsxPropsTypeForSignatureFromMember(sig, forcedLookupLocation);
            if (!attributesType) {
                // There is no property named 'props' on this instance type
                if (!!forcedLookupLocation && !!ts.length(context.attributes.properties)) {
                    error(context, ts.Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, ts.unescapeLeadingUnderscores(forcedLookupLocation));
                }
                return unknownType;
            }
            attributesType = getJsxManagedAttributesFromLocatedAttributes(context, ns, attributesType);
            if (isTypeAny(attributesType)) {
                // Props is of type 'any' or unknown
                return attributesType;
            }
            else {
                // Normal case -- add in IntrinsicClassElements<T> and IntrinsicElements
                var apparentAttributesType = attributesType;
                var intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes, context);
                if (intrinsicClassAttribs !== errorType) {
                    var typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol);
                    var hostClassType = getReturnTypeOfSignature(sig);
                    apparentAttributesType = intersectTypes(typeParams
                        ? createTypeReference(intrinsicClassAttribs, fillMissingTypeArguments([hostClassType], typeParams, getMinTypeArgumentCount(typeParams), ts.isInJSFile(context)))
                        : intrinsicClassAttribs, apparentAttributesType);
                }
                var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
                if (intrinsicAttribs !== errorType) {
                    apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType);
                }
                return apparentAttributesType;
            }
        }
        // If the given type is an object or union type with a single signature, and if that signature has at
        // least as many parameters as the given function, return the signature. Otherwise return undefined.
        function getContextualCallSignature(type, node) {
            var signatures = getSignaturesOfType(type, 0 /* Call */);
            if (signatures.length === 1) {
                var signature = signatures[0];
                if (!isAritySmaller(signature, node)) {
                    return signature;
                }
            }
        }
        /** If the contextual signature has fewer parameters than the function expression, do not use it */
        function isAritySmaller(signature, target) {
            var targetParameterCount = 0;
            for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
                var param = target.parameters[targetParameterCount];
                if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) {
                    break;
                }
            }
            if (target.parameters.length && ts.parameterIsThisKeyword(target.parameters[0])) {
                targetParameterCount--;
            }
            return !hasEffectiveRestParameter(signature) && getParameterCount(signature) < targetParameterCount;
        }
        function isFunctionExpressionOrArrowFunction(node) {
            return node.kind === 201 /* FunctionExpression */ || node.kind === 202 /* ArrowFunction */;
        }
        function getContextualSignatureForFunctionLikeDeclaration(node) {
            // Only function expressions, arrow functions, and object literal methods are contextually typed.
            return isFunctionExpressionOrArrowFunction(node) || ts.isObjectLiteralMethod(node)
                ? getContextualSignature(node)
                : undefined;
        }
        // Return the contextual signature for a given expression node. A contextual type provides a
        // contextual signature if it has a single call signature and if that call signature is non-generic.
        // If the contextual type is a union type, get the signature from each type possible and if they are
        // all identical ignoring their return type, the result is same signature but with return type as
        // union type of return types from these signatures
        function getContextualSignature(node) {
            ts.Debug.assert(node.kind !== 161 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var typeTagSignature = getSignatureOfTypeTag(node);
            if (typeTagSignature) {
                return typeTagSignature;
            }
            var type = getApparentTypeOfContextualType(node, 1 /* Signature */);
            if (!type) {
                return undefined;
            }
            if (!(type.flags & 1048576 /* Union */)) {
                return getContextualCallSignature(type, node);
            }
            var signatureList;
            var types = type.types;
            for (var _i = 0, types_17 = types; _i < types_17.length; _i++) {
                var current = types_17[_i];
                var signature = getContextualCallSignature(current, node);
                if (signature) {
                    if (!signatureList) {
                        // This signature will contribute to contextual union signature
                        signatureList = [signature];
                    }
                    else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) {
                        // Signatures aren't identical, do not use
                        return undefined;
                    }
                    else {
                        // Use this signature for contextual union signature
                        signatureList.push(signature);
                    }
                }
            }
            // Result is union of signatures collected (return type is union of return types of this signature set)
            if (signatureList) {
                return signatureList.length === 1 ? signatureList[0] : createUnionSignature(signatureList[0], signatureList);
            }
        }
        function checkSpreadExpression(node, checkMode) {
            if (languageVersion < 2 /* ES2015 */) {
                checkExternalEmitHelpers(node, compilerOptions.downlevelIteration ? 1536 /* SpreadIncludes */ : 2048 /* SpreadArrays */);
            }
            var arrayOrIterableType = checkExpression(node.expression, checkMode);
            return checkIteratedTypeOrElementType(33 /* Spread */, arrayOrIterableType, undefinedType, node.expression);
        }
        function hasDefaultValue(node) {
            return (node.kind === 191 /* BindingElement */ && !!node.initializer) ||
                (node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 62 /* EqualsToken */);
        }
        function checkArrayLiteral(node, checkMode, forceTuple) {
            var elements = node.elements;
            var elementCount = elements.length;
            var elementTypes = [];
            var hasEndingSpreadElement = false;
            var hasNonEndingSpreadElement = false;
            var contextualType = getApparentTypeOfContextualType(node);
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            var inConstContext = isConstContext(node);
            for (var i = 0; i < elementCount; i++) {
                var e = elements[i];
                var spread = e.kind === 213 /* SpreadElement */ && e.expression;
                var spreadType = spread && checkExpression(spread, checkMode, forceTuple);
                if (spreadType && isTupleType(spreadType)) {
                    elementTypes.push.apply(elementTypes, getTypeArguments(spreadType));
                    if (spreadType.target.hasRestElement) {
                        if (i === elementCount - 1)
                            hasEndingSpreadElement = true;
                        else
                            hasNonEndingSpreadElement = true;
                    }
                }
                else {
                    if (inDestructuringPattern && spreadType) {
                        // Given the following situation:
                        //    var c: {};
                        //    [...c] = ["", 0];
                        //
                        // c is represented in the tree as a spread element in an array literal.
                        // But c really functions as a rest element, and its purpose is to provide
                        // a contextual type for the right hand side of the assignment. Therefore,
                        // instead of calling checkExpression on "...c", which will give an error
                        // if c is not iterable/array-like, we need to act as if we are trying to
                        // get the contextual element type from it. So we do something similar to
                        // getContextualTypeForElementExpression, which will crucially not error
                        // if there is no index type / iterated type.
                        var restElementType = getIndexTypeOfType(spreadType, 1 /* Number */) ||
                            getIteratedTypeOrElementType(65 /* Destructuring */, spreadType, undefinedType, /*errorNode*/ undefined, /*checkAssignability*/ false);
                        if (restElementType) {
                            elementTypes.push(restElementType);
                        }
                    }
                    else {
                        var elementContextualType = getContextualTypeForElementExpression(contextualType, elementTypes.length);
                        var type = checkExpressionForMutableLocation(e, checkMode, elementContextualType, forceTuple);
                        elementTypes.push(type);
                    }
                    if (spread) { // tuples are done above, so these are only arrays
                        if (i === elementCount - 1)
                            hasEndingSpreadElement = true;
                        else
                            hasNonEndingSpreadElement = true;
                    }
                }
            }
            if (!hasNonEndingSpreadElement) {
                var minLength = elementTypes.length - (hasEndingSpreadElement ? 1 : 0);
                // If array literal is actually a destructuring pattern, mark it as an implied type. We do this such
                // that we get the same behavior for "var [x, y] = []" and "[x, y] = []".
                var tupleResult = void 0;
                if (inDestructuringPattern && minLength > 0) {
                    var type = cloneTypeReference(createTupleType(elementTypes, minLength, hasEndingSpreadElement));
                    type.pattern = node;
                    return type;
                }
                else if (tupleResult = getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasEndingSpreadElement, elementTypes.length, inConstContext)) {
                    return createArrayLiteralType(tupleResult);
                }
                else if (forceTuple) {
                    return createArrayLiteralType(createTupleType(elementTypes, minLength, hasEndingSpreadElement));
                }
            }
            return createArrayLiteralType(createArrayType(elementTypes.length ?
                getUnionType(elementTypes, 2 /* Subtype */) :
                strictNullChecks ? implicitNeverType : undefinedWideningType, inConstContext));
        }
        function createArrayLiteralType(type) {
            if (!(ts.getObjectFlags(type) & 4 /* Reference */)) {
                return type;
            }
            var literalType = type.literalType;
            if (!literalType) {
                literalType = type.literalType = cloneTypeReference(type);
                literalType.objectFlags |= 65536 /* ArrayLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
            }
            return literalType;
        }
        function getArrayLiteralTupleTypeIfApplicable(elementTypes, contextualType, hasRestElement, elementCount, readonly) {
            if (elementCount === void 0) { elementCount = elementTypes.length; }
            if (readonly === void 0) { readonly = false; }
            // Infer a tuple type when the contextual type is or contains a tuple-like type
            if (readonly || (contextualType && forEachType(contextualType, isTupleLikeType))) {
                return createTupleType(elementTypes, elementCount - (hasRestElement ? 1 : 0), hasRestElement, readonly);
            }
        }
        function isNumericName(name) {
            switch (name.kind) {
                case 154 /* ComputedPropertyName */:
                    return isNumericComputedName(name);
                case 75 /* Identifier */:
                    return isNumericLiteralName(name.escapedText);
                case 8 /* NumericLiteral */:
                case 10 /* StringLiteral */:
                    return isNumericLiteralName(name.text);
                default:
                    return false;
            }
        }
        function isNumericComputedName(name) {
            // It seems odd to consider an expression of type Any to result in a numeric name,
            // but this behavior is consistent with checkIndexedAccess
            return isTypeAssignableToKind(checkComputedPropertyName(name), 296 /* NumberLike */);
        }
        function isInfinityOrNaNString(name) {
            return name === "Infinity" || name === "-Infinity" || name === "NaN";
        }
        function isNumericLiteralName(name) {
            // The intent of numeric names is that
            //     - they are names with text in a numeric form, and that
            //     - setting properties/indexing with them is always equivalent to doing so with the numeric literal 'numLit',
            //         acquired by applying the abstract 'ToNumber' operation on the name's text.
            //
            // The subtlety is in the latter portion, as we cannot reliably say that anything that looks like a numeric literal is a numeric name.
            // In fact, it is the case that the text of the name must be equal to 'ToString(numLit)' for this to hold.
            //
            // Consider the property name '"0xF00D"'. When one indexes with '0xF00D', they are actually indexing with the value of 'ToString(0xF00D)'
            // according to the ECMAScript specification, so it is actually as if the user indexed with the string '"61453"'.
            // Thus, the text of all numeric literals equivalent to '61543' such as '0xF00D', '0xf00D', '0170015', etc. are not valid numeric names
            // because their 'ToString' representation is not equal to their original text.
            // This is motivated by ECMA-262 sections 9.3.1, 9.8.1, 11.1.5, and 11.2.1.
            //
            // Here, we test whether 'ToString(ToNumber(name))' is exactly equal to 'name'.
            // The '+' prefix operator is equivalent here to applying the abstract ToNumber operation.
            // Applying the 'toString()' method on a number gives us the abstract ToString operation on a number.
            //
            // Note that this accepts the values 'Infinity', '-Infinity', and 'NaN', and that this is intentional.
            // This is desired behavior, because when indexing with them as numeric entities, you are indexing
            // with the strings '"Infinity"', '"-Infinity"', and '"NaN"' respectively.
            return (+name).toString() === name;
        }
        function checkComputedPropertyName(node) {
            var links = getNodeLinks(node.expression);
            if (!links.resolvedType) {
                links.resolvedType = checkExpression(node.expression);
                // This will allow types number, string, symbol or any. It will also allow enums, the unknown
                // type, and any union of these types (like string | number).
                if (links.resolvedType.flags & 98304 /* Nullable */ ||
                    !isTypeAssignableToKind(links.resolvedType, 132 /* StringLike */ | 296 /* NumberLike */ | 12288 /* ESSymbolLike */) &&
                        !isTypeAssignableTo(links.resolvedType, stringNumberSymbolType)) {
                    error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any);
                }
                else {
                    checkThatExpressionIsProperSymbolReference(node.expression, links.resolvedType, /*reportError*/ true);
                }
            }
            return links.resolvedType;
        }
        function getObjectLiteralIndexInfo(node, offset, properties, kind) {
            var propTypes = [];
            for (var i = 0; i < properties.length; i++) {
                if (kind === 0 /* String */ || isNumericName(node.properties[i + offset].name)) {
                    propTypes.push(getTypeOfSymbol(properties[i]));
                }
            }
            var unionType = propTypes.length ? getUnionType(propTypes, 2 /* Subtype */) : undefinedType;
            return createIndexInfo(unionType, isConstContext(node));
        }
        function getImmediateAliasedSymbol(symbol) {
            ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here.");
            var links = getSymbolLinks(symbol);
            if (!links.immediateTarget) {
                var node = getDeclarationOfAliasSymbol(symbol);
                if (!node)
                    return ts.Debug.fail();
                links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true);
            }
            return links.immediateTarget;
        }
        function checkObjectLiteral(node, checkMode) {
            var inDestructuringPattern = ts.isAssignmentTarget(node);
            // Grammar checking
            checkGrammarObjectLiteralExpression(node, inDestructuringPattern);
            var allPropertiesTable = strictNullChecks ? ts.createSymbolTable() : undefined;
            var propertiesTable = ts.createSymbolTable();
            var propertiesArray = [];
            var spread = emptyObjectType;
            var contextualType = getApparentTypeOfContextualType(node);
            var contextualTypeHasPattern = contextualType && contextualType.pattern &&
                (contextualType.pattern.kind === 189 /* ObjectBindingPattern */ || contextualType.pattern.kind === 193 /* ObjectLiteralExpression */);
            var inConstContext = isConstContext(node);
            var checkFlags = inConstContext ? 8 /* Readonly */ : 0;
            var isInJavascript = ts.isInJSFile(node) && !ts.isInJsonFile(node);
            var enumTag = ts.getJSDocEnumTag(node);
            var isJSObjectLiteral = !contextualType && isInJavascript && !enumTag;
            var objectFlags = freshObjectLiteralFlag;
            var patternWithComputedProperties = false;
            var hasComputedStringProperty = false;
            var hasComputedNumberProperty = false;
            // Spreads may cause an early bail; ensure computed names are always checked (this is cached)
            // As otherwise they may not be checked until exports for the type at this position are retrieved,
            // which may never occur.
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var elem = _a[_i];
                if (elem.name && ts.isComputedPropertyName(elem.name) && !ts.isWellKnownSymbolSyntactically(elem.name)) {
                    checkComputedPropertyName(elem.name);
                }
            }
            var offset = 0;
            for (var i = 0; i < node.properties.length; i++) {
                var memberDecl = node.properties[i];
                var member = getSymbolOfNode(memberDecl);
                var computedNameType = memberDecl.name && memberDecl.name.kind === 154 /* ComputedPropertyName */ && !ts.isWellKnownSymbolSyntactically(memberDecl.name.expression) ?
                    checkComputedPropertyName(memberDecl.name) : undefined;
                if (memberDecl.kind === 281 /* PropertyAssignment */ ||
                    memberDecl.kind === 282 /* ShorthandPropertyAssignment */ ||
                    ts.isObjectLiteralMethod(memberDecl)) {
                    var type = memberDecl.kind === 281 /* PropertyAssignment */ ? checkPropertyAssignment(memberDecl, checkMode) :
                        memberDecl.kind === 282 /* ShorthandPropertyAssignment */ ? checkExpressionForMutableLocation(memberDecl.name, checkMode) :
                            checkObjectLiteralMethod(memberDecl, checkMode);
                    if (isInJavascript) {
                        var jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl);
                        if (jsDocType) {
                            checkTypeAssignableTo(type, jsDocType, memberDecl);
                            type = jsDocType;
                        }
                        else if (enumTag && enumTag.typeExpression) {
                            checkTypeAssignableTo(type, getTypeFromTypeNode(enumTag.typeExpression), memberDecl);
                        }
                    }
                    objectFlags |= ts.getObjectFlags(type) & 3670016 /* PropagatingFlags */;
                    var nameType = computedNameType && isTypeUsableAsPropertyName(computedNameType) ? computedNameType : undefined;
                    var prop = nameType ?
                        createSymbol(4 /* Property */ | member.flags, getPropertyNameFromType(nameType), checkFlags | 4096 /* Late */) :
                        createSymbol(4 /* Property */ | member.flags, member.escapedName, checkFlags);
                    if (nameType) {
                        prop.nameType = nameType;
                    }
                    if (inDestructuringPattern) {
                        // If object literal is an assignment pattern and if the assignment pattern specifies a default value
                        // for the property, make the property optional.
                        var isOptional = (memberDecl.kind === 281 /* PropertyAssignment */ && hasDefaultValue(memberDecl.initializer)) ||
                            (memberDecl.kind === 282 /* ShorthandPropertyAssignment */ && memberDecl.objectAssignmentInitializer);
                        if (isOptional) {
                            prop.flags |= 16777216 /* Optional */;
                        }
                    }
                    else if (contextualTypeHasPattern && !(ts.getObjectFlags(contextualType) & 512 /* ObjectLiteralPatternWithComputedProperties */)) {
                        // If object literal is contextually typed by the implied type of a binding pattern, and if the
                        // binding pattern specifies a default value for the property, make the property optional.
                        var impliedProp = getPropertyOfType(contextualType, member.escapedName);
                        if (impliedProp) {
                            prop.flags |= impliedProp.flags & 16777216 /* Optional */;
                        }
                        else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, 0 /* String */)) {
                            error(memberDecl.name, ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType));
                        }
                    }
                    prop.declarations = member.declarations;
                    prop.parent = member.parent;
                    if (member.valueDeclaration) {
                        prop.valueDeclaration = member.valueDeclaration;
                    }
                    prop.type = type;
                    prop.target = member;
                    member = prop;
                    allPropertiesTable === null || allPropertiesTable === void 0 ? void 0 : allPropertiesTable.set(prop.escapedName, prop);
                }
                else if (memberDecl.kind === 283 /* SpreadAssignment */) {
                    if (languageVersion < 2 /* ES2015 */) {
                        checkExternalEmitHelpers(memberDecl, 2 /* Assign */);
                    }
                    if (propertiesArray.length > 0) {
                        spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
                        propertiesArray = [];
                        propertiesTable = ts.createSymbolTable();
                        hasComputedStringProperty = false;
                        hasComputedNumberProperty = false;
                    }
                    var type = getReducedType(checkExpression(memberDecl.expression));
                    if (!isValidSpreadType(type)) {
                        error(memberDecl, ts.Diagnostics.Spread_types_may_only_be_created_from_object_types);
                        return errorType;
                    }
                    if (allPropertiesTable) {
                        checkSpreadPropOverrides(type, allPropertiesTable, memberDecl);
                    }
                    spread = getSpreadType(spread, type, node.symbol, objectFlags, inConstContext);
                    offset = i + 1;
                    continue;
                }
                else {
                    // TypeScript 1.0 spec (April 2014)
                    // A get accessor declaration is processed in the same manner as
                    // an ordinary function declaration(section 6.1) with no parameters.
                    // A set accessor declaration is processed in the same manner
                    // as an ordinary function declaration with a single parameter and a Void return type.
                    ts.Debug.assert(memberDecl.kind === 163 /* GetAccessor */ || memberDecl.kind === 164 /* SetAccessor */);
                    checkNodeDeferred(memberDecl);
                }
                if (computedNameType && !(computedNameType.flags & 8576 /* StringOrNumberLiteralOrUnique */)) {
                    if (isTypeAssignableTo(computedNameType, stringNumberSymbolType)) {
                        if (isTypeAssignableTo(computedNameType, numberType)) {
                            hasComputedNumberProperty = true;
                        }
                        else {
                            hasComputedStringProperty = true;
                        }
                        if (inDestructuringPattern) {
                            patternWithComputedProperties = true;
                        }
                    }
                }
                else {
                    propertiesTable.set(member.escapedName, member);
                }
                propertiesArray.push(member);
            }
            // If object literal is contextually typed by the implied type of a binding pattern, augment the result
            // type with those properties for which the binding pattern specifies a default value.
            // If the object literal is spread into another object literal, skip this step and let the top-level object
            // literal handle it instead.
            if (contextualTypeHasPattern && node.parent.kind !== 283 /* SpreadAssignment */) {
                for (var _b = 0, _c = getPropertiesOfType(contextualType); _b < _c.length; _b++) {
                    var prop = _c[_b];
                    if (!propertiesTable.get(prop.escapedName) && !getPropertyOfType(spread, prop.escapedName)) {
                        if (!(prop.flags & 16777216 /* Optional */)) {
                            error(prop.valueDeclaration || prop.bindingElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
                        }
                        propertiesTable.set(prop.escapedName, prop);
                        propertiesArray.push(prop);
                    }
                }
            }
            if (spread !== emptyObjectType) {
                if (propertiesArray.length > 0) {
                    spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, objectFlags, inConstContext);
                    propertiesArray = [];
                    propertiesTable = ts.createSymbolTable();
                    hasComputedStringProperty = false;
                    hasComputedNumberProperty = false;
                }
                // remap the raw emptyObjectType fed in at the top into a fresh empty object literal type, unique to this use site
                return mapType(spread, function (t) { return t === emptyObjectType ? createObjectLiteralType() : t; });
            }
            return createObjectLiteralType();
            function createObjectLiteralType() {
                var stringIndexInfo = hasComputedStringProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, 0 /* String */) : undefined;
                var numberIndexInfo = hasComputedNumberProperty ? getObjectLiteralIndexInfo(node, offset, propertiesArray, 1 /* Number */) : undefined;
                var result = createAnonymousType(node.symbol, propertiesTable, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo);
                result.objectFlags |= objectFlags | 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
                if (isJSObjectLiteral) {
                    result.objectFlags |= 16384 /* JSLiteral */;
                }
                if (patternWithComputedProperties) {
                    result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */;
                }
                if (inDestructuringPattern) {
                    result.pattern = node;
                }
                return result;
            }
        }
        function isValidSpreadType(type) {
            if (type.flags & 63176704 /* Instantiable */) {
                var constraint = getBaseConstraintOfType(type);
                if (constraint !== undefined) {
                    return isValidSpreadType(constraint);
                }
            }
            return !!(type.flags & (1 /* Any */ | 67108864 /* NonPrimitive */ | 524288 /* Object */ | 58982400 /* InstantiableNonPrimitive */) ||
                getFalsyFlags(type) & 117632 /* DefinitelyFalsy */ && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
                type.flags & 3145728 /* UnionOrIntersection */ && ts.every(type.types, isValidSpreadType));
        }
        function checkJsxSelfClosingElementDeferred(node) {
            checkJsxOpeningLikeElementOrOpeningFragment(node);
            resolveUntypedCall(node); // ensure type arguments and parameters are typechecked, even if there is an arity error
        }
        function checkJsxSelfClosingElement(node, _checkMode) {
            checkNodeDeferred(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        function checkJsxElementDeferred(node) {
            // Check attributes
            checkJsxOpeningLikeElementOrOpeningFragment(node.openingElement);
            // Perform resolution on the closing tag so that rename/go to definition/etc work
            if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
                getIntrinsicTagSymbol(node.closingElement);
            }
            else {
                checkExpression(node.closingElement.tagName);
            }
            checkJsxChildren(node);
        }
        function checkJsxElement(node, _checkMode) {
            checkNodeDeferred(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        function checkJsxFragment(node) {
            checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment);
            if (compilerOptions.jsx === 2 /* React */ && (compilerOptions.jsxFactory || ts.getSourceFileOfNode(node).pragmas.has("jsx"))) {
                error(node, compilerOptions.jsxFactory
                    ? ts.Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory
                    : ts.Diagnostics.JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma);
            }
            checkJsxChildren(node);
            return getJsxElementTypeAt(node) || anyType;
        }
        /**
         * Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
         */
        function isUnhyphenatedJsxName(name) {
            // - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers
            return !ts.stringContains(name, "-");
        }
        /**
         * Returns true iff React would emit this tag name as a string rather than an identifier or qualified name
         */
        function isJsxIntrinsicIdentifier(tagName) {
            return tagName.kind === 75 /* Identifier */ && ts.isIntrinsicJsxName(tagName.escapedText);
        }
        function checkJsxAttribute(node, checkMode) {
            return node.initializer
                ? checkExpressionForMutableLocation(node.initializer, checkMode)
                : trueType; // <Elem attr /> is sugar for <Elem attr={true} />
        }
        /**
         * Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element.
         *
         * @param openingLikeElement a JSX opening-like element
         * @param filter a function to remove attributes that will not participate in checking whether attributes are assignable
         * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property.
         * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral,
         * which also calls getSpreadType.
         */
        function createJsxAttributesTypeFromAttributesProperty(openingLikeElement, checkMode) {
            var attributes = openingLikeElement.attributes;
            var allAttributesTable = strictNullChecks ? ts.createSymbolTable() : undefined;
            var attributesTable = ts.createSymbolTable();
            var spread = emptyJsxObjectType;
            var hasSpreadAnyType = false;
            var typeToIntersect;
            var explicitlySpecifyChildrenAttribute = false;
            var objectFlags = 4096 /* JsxAttributes */;
            var jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement));
            for (var _i = 0, _a = attributes.properties; _i < _a.length; _i++) {
                var attributeDecl = _a[_i];
                var member = attributeDecl.symbol;
                if (ts.isJsxAttribute(attributeDecl)) {
                    var exprType = checkJsxAttribute(attributeDecl, checkMode);
                    objectFlags |= ts.getObjectFlags(exprType) & 3670016 /* PropagatingFlags */;
                    var attributeSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */ | member.flags, member.escapedName);
                    attributeSymbol.declarations = member.declarations;
                    attributeSymbol.parent = member.parent;
                    if (member.valueDeclaration) {
                        attributeSymbol.valueDeclaration = member.valueDeclaration;
                    }
                    attributeSymbol.type = exprType;
                    attributeSymbol.target = member;
                    attributesTable.set(attributeSymbol.escapedName, attributeSymbol);
                    allAttributesTable === null || allAttributesTable === void 0 ? void 0 : allAttributesTable.set(attributeSymbol.escapedName, attributeSymbol);
                    if (attributeDecl.name.escapedText === jsxChildrenPropertyName) {
                        explicitlySpecifyChildrenAttribute = true;
                    }
                }
                else {
                    ts.Debug.assert(attributeDecl.kind === 275 /* JsxSpreadAttribute */);
                    if (attributesTable.size > 0) {
                        spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
                        attributesTable = ts.createSymbolTable();
                    }
                    var exprType = getReducedType(checkExpressionCached(attributeDecl.expression, checkMode));
                    if (isTypeAny(exprType)) {
                        hasSpreadAnyType = true;
                    }
                    if (isValidSpreadType(exprType)) {
                        spread = getSpreadType(spread, exprType, attributes.symbol, objectFlags, /*readonly*/ false);
                        if (allAttributesTable) {
                            checkSpreadPropOverrides(exprType, allAttributesTable, attributeDecl);
                        }
                    }
                    else {
                        typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
                    }
                }
            }
            if (!hasSpreadAnyType) {
                if (attributesTable.size > 0) {
                    spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, objectFlags, /*readonly*/ false);
                }
            }
            // Handle children attribute
            var parent = openingLikeElement.parent.kind === 266 /* JsxElement */ ? openingLikeElement.parent : undefined;
            // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement
            if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) {
                var childrenTypes = checkJsxChildren(parent, checkMode);
                if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") {
                    // Error if there is a attribute named "children" explicitly specified and children element.
                    // This is because children element will overwrite the value from attributes.
                    // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread.
                    if (explicitlySpecifyChildrenAttribute) {
                        error(attributes, ts.Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName));
                    }
                    var contextualType = getApparentTypeOfContextualType(openingLikeElement.attributes);
                    var childrenContextualType = contextualType && getTypeOfPropertyOfContextualType(contextualType, jsxChildrenPropertyName);
                    // If there are children in the body of JSX element, create dummy attribute "children" with the union of children types so that it will pass the attribute checking process
                    var childrenPropSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */, jsxChildrenPropertyName);
                    childrenPropSymbol.type = childrenTypes.length === 1 ?
                        childrenTypes[0] :
                        (getArrayLiteralTupleTypeIfApplicable(childrenTypes, childrenContextualType, /*hasRestElement*/ false) || createArrayType(getUnionType(childrenTypes)));
                    // Fake up a property declaration for the children
                    childrenPropSymbol.valueDeclaration = ts.createPropertySignature(/*modifiers*/ undefined, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName), /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined);
                    childrenPropSymbol.valueDeclaration.parent = attributes;
                    childrenPropSymbol.valueDeclaration.symbol = childrenPropSymbol;
                    var childPropMap = ts.createSymbolTable();
                    childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
                    spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined), attributes.symbol, objectFlags, /*readonly*/ false);
                }
            }
            if (hasSpreadAnyType) {
                return anyType;
            }
            if (typeToIntersect && spread !== emptyJsxObjectType) {
                return getIntersectionType([typeToIntersect, spread]);
            }
            return typeToIntersect || (spread === emptyJsxObjectType ? createJsxAttributesType() : spread);
            /**
             * Create anonymous type from given attributes symbol table.
             * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable
             * @param attributesTable a symbol table of attributes property
             */
            function createJsxAttributesType() {
                objectFlags |= freshObjectLiteralFlag;
                var result = createAnonymousType(attributes.symbol, attributesTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
                result.objectFlags |= objectFlags | 128 /* ObjectLiteral */ | 1048576 /* ContainsObjectOrArrayLiteral */;
                return result;
            }
        }
        function checkJsxChildren(node, checkMode) {
            var childrenTypes = [];
            for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
                var child = _a[_i];
                // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that
                // because then type of children property will have constituent of string type.
                if (child.kind === 11 /* JsxText */) {
                    if (!child.containsOnlyTriviaWhiteSpaces) {
                        childrenTypes.push(stringType);
                    }
                }
                else {
                    childrenTypes.push(checkExpressionForMutableLocation(child, checkMode));
                }
            }
            return childrenTypes;
        }
        function checkSpreadPropOverrides(type, props, spread) {
            for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) {
                var right = _a[_i];
                var left = props.get(right.escapedName);
                var rightType = getTypeOfSymbol(right);
                if (left && !maybeTypeOfKind(rightType, 98304 /* Nullable */) && !(maybeTypeOfKind(rightType, 3 /* AnyOrUnknown */) && right.flags & 16777216 /* Optional */)) {
                    var diagnostic = error(left.valueDeclaration, ts.Diagnostics._0_is_specified_more_than_once_so_this_usage_will_be_overwritten, ts.unescapeLeadingUnderscores(left.escapedName));
                    ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(spread, ts.Diagnostics.This_spread_always_overwrites_this_property));
                }
            }
        }
        /**
         * Check attributes property of opening-like element. This function is called during chooseOverload to get call signature of a JSX opening-like element.
         * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used)
         * @param node a JSXAttributes to be resolved of its type
         */
        function checkJsxAttributes(node, checkMode) {
            return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode);
        }
        function getJsxType(name, location) {
            var namespace = getJsxNamespaceAt(location);
            var exports = namespace && getExportsOfSymbol(namespace);
            var typeSymbol = exports && getSymbol(exports, name, 788968 /* Type */);
            return typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType;
        }
        /**
         * Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic
         * property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic
         * string index signature (in which case nodeLinks.jsxFlags will be IntrinsicIndexedElement).
         * May also return unknownSymbol if both of these lookups fail.
         */
        function getIntrinsicTagSymbol(node) {
            var links = getNodeLinks(node);
            if (!links.resolvedSymbol) {
                var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, node);
                if (intrinsicElementsType !== errorType) {
                    // Property case
                    if (!ts.isIdentifier(node.tagName))
                        return ts.Debug.fail();
                    var intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText);
                    if (intrinsicProp) {
                        links.jsxFlags |= 1 /* IntrinsicNamedElement */;
                        return links.resolvedSymbol = intrinsicProp;
                    }
                    // Intrinsic string indexer case
                    var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                    if (indexSignatureType) {
                        links.jsxFlags |= 2 /* IntrinsicIndexedElement */;
                        return links.resolvedSymbol = intrinsicElementsType.symbol;
                    }
                    // Wasn't found
                    error(node, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(node.tagName), "JSX." + JsxNames.IntrinsicElements);
                    return links.resolvedSymbol = unknownSymbol;
                }
                else {
                    if (noImplicitAny) {
                        error(node, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, ts.unescapeLeadingUnderscores(JsxNames.IntrinsicElements));
                    }
                    return links.resolvedSymbol = unknownSymbol;
                }
            }
            return links.resolvedSymbol;
        }
        function getJsxNamespaceAt(location) {
            var links = location && getNodeLinks(location);
            if (links && links.jsxNamespace) {
                return links.jsxNamespace;
            }
            if (!links || links.jsxNamespace !== false) {
                var namespaceName = getJsxNamespace(location);
                var resolvedNamespace = resolveName(location, namespaceName, 1920 /* Namespace */, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false);
                if (resolvedNamespace) {
                    var candidate = resolveSymbol(getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, 1920 /* Namespace */));
                    if (candidate) {
                        if (links) {
                            links.jsxNamespace = candidate;
                        }
                        return candidate;
                    }
                    if (links) {
                        links.jsxNamespace = false;
                    }
                }
            }
            // JSX global fallback
            return getGlobalSymbol(JsxNames.JSX, 1920 /* Namespace */, /*diagnosticMessage*/ undefined); // TODO: GH#18217
        }
        /**
         * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer.
         * Get a single property from that container if existed. Report an error if there are more than one property.
         *
         * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer
         *          if other string is given or the container doesn't exist, return undefined.
         */
        function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer, jsxNamespace) {
            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol]
            var jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, 788968 /* Type */);
            // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type]
            var jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym);
            // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute
            var propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType);
            if (propertiesOfJsxElementAttribPropInterface) {
                // Element Attributes has zero properties, so the element attributes type will be the class instance type
                if (propertiesOfJsxElementAttribPropInterface.length === 0) {
                    return "";
                }
                // Element Attributes has one property, so the element attributes type will be the type of the corresponding
                // property of the class instance type
                else if (propertiesOfJsxElementAttribPropInterface.length === 1) {
                    return propertiesOfJsxElementAttribPropInterface[0].escapedName;
                }
                else if (propertiesOfJsxElementAttribPropInterface.length > 1) {
                    // More than one property on ElementAttributesProperty is an error
                    error(jsxElementAttribPropInterfaceSym.declarations[0], ts.Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, ts.unescapeLeadingUnderscores(nameOfAttribPropContainer));
                }
            }
            return undefined;
        }
        function getJsxLibraryManagedAttributes(jsxNamespace) {
            // JSX.LibraryManagedAttributes [symbol]
            return jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.LibraryManagedAttributes, 788968 /* Type */);
        }
        /// e.g. "props" for React.d.ts,
        /// or 'undefined' if ElementAttributesProperty doesn't exist (which means all
        ///     non-intrinsic elements' attributes type is 'any'),
        /// or '' if it has 0 properties (which means every
        ///     non-intrinsic elements' attributes type is the element instance type)
        function getJsxElementPropertiesName(jsxNamespace) {
            return getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer, jsxNamespace);
        }
        function getJsxElementChildrenPropertyName(jsxNamespace) {
            return getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer, jsxNamespace);
        }
        function getUninstantiatedJsxSignaturesOfType(elementType, caller) {
            if (elementType.flags & 4 /* String */) {
                return [anySignature];
            }
            else if (elementType.flags & 128 /* StringLiteral */) {
                var intrinsicType = getIntrinsicAttributesTypeFromStringLiteralType(elementType, caller);
                if (!intrinsicType) {
                    error(caller, ts.Diagnostics.Property_0_does_not_exist_on_type_1, elementType.value, "JSX." + JsxNames.IntrinsicElements);
                    return ts.emptyArray;
                }
                else {
                    var fakeSignature = createSignatureForJSXIntrinsic(caller, intrinsicType);
                    return [fakeSignature];
                }
            }
            var apparentElemType = getApparentType(elementType);
            // Resolve the signatures, preferring constructor
            var signatures = getSignaturesOfType(apparentElemType, 1 /* Construct */);
            if (signatures.length === 0) {
                // No construct signatures, try call signatures
                signatures = getSignaturesOfType(apparentElemType, 0 /* Call */);
            }
            if (signatures.length === 0 && apparentElemType.flags & 1048576 /* Union */) {
                // If each member has some combination of new/call signatures; make a union signature list for those
                signatures = getUnionSignatures(ts.map(apparentElemType.types, function (t) { return getUninstantiatedJsxSignaturesOfType(t, caller); }));
            }
            return signatures;
        }
        function getIntrinsicAttributesTypeFromStringLiteralType(type, location) {
            // If the elemType is a stringLiteral type, we can then provide a check to make sure that the string literal type is one of the Jsx intrinsic element type
            // For example:
            //      var CustomTag: "h1" = "h1";
            //      <CustomTag> Hello World </CustomTag>
            var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, location);
            if (intrinsicElementsType !== errorType) {
                var stringLiteralTypeName = type.value;
                var intrinsicProp = getPropertyOfType(intrinsicElementsType, ts.escapeLeadingUnderscores(stringLiteralTypeName));
                if (intrinsicProp) {
                    return getTypeOfSymbol(intrinsicProp);
                }
                var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */);
                if (indexSignatureType) {
                    return indexSignatureType;
                }
                return undefined;
            }
            // If we need to report an error, we already done so here. So just return any to prevent any more error downstream
            return anyType;
        }
        function checkJsxReturnAssignableToAppropriateBound(refKind, elemInstanceType, openingLikeElement) {
            if (refKind === 1 /* Function */) {
                var sfcReturnConstraint = getJsxStatelessElementTypeAt(openingLikeElement);
                if (sfcReturnConstraint) {
                    checkTypeRelatedTo(elemInstanceType, sfcReturnConstraint, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_return_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain);
                }
            }
            else if (refKind === 0 /* Component */) {
                var classConstraint = getJsxElementClassTypeAt(openingLikeElement);
                if (classConstraint) {
                    // Issue an error if this return type isn't assignable to JSX.ElementClass, failing that
                    checkTypeRelatedTo(elemInstanceType, classConstraint, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_instance_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain);
                }
            }
            else { // Mixed
                var sfcReturnConstraint = getJsxStatelessElementTypeAt(openingLikeElement);
                var classConstraint = getJsxElementClassTypeAt(openingLikeElement);
                if (!sfcReturnConstraint || !classConstraint) {
                    return;
                }
                var combined = getUnionType([sfcReturnConstraint, classConstraint]);
                checkTypeRelatedTo(elemInstanceType, combined, assignableRelation, openingLikeElement.tagName, ts.Diagnostics.Its_element_type_0_is_not_a_valid_JSX_element, generateInitialErrorChain);
            }
            function generateInitialErrorChain() {
                var componentName = ts.getTextOfNode(openingLikeElement.tagName);
                return ts.chainDiagnosticMessages(/* details */ undefined, ts.Diagnostics._0_cannot_be_used_as_a_JSX_component, componentName);
            }
        }
        /**
         * Get attributes type of the given intrinsic opening-like Jsx element by resolving the tag name.
         * The function is intended to be called from a function which has checked that the opening element is an intrinsic element.
         * @param node an intrinsic JSX opening-like element
         */
        function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node) {
            ts.Debug.assert(isJsxIntrinsicIdentifier(node.tagName));
            var links = getNodeLinks(node);
            if (!links.resolvedJsxElementAttributesType) {
                var symbol = getIntrinsicTagSymbol(node);
                if (links.jsxFlags & 1 /* IntrinsicNamedElement */) {
                    return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol);
                }
                else if (links.jsxFlags & 2 /* IntrinsicIndexedElement */) {
                    return links.resolvedJsxElementAttributesType =
                        getIndexTypeOfType(getDeclaredTypeOfSymbol(symbol), 0 /* String */);
                }
                else {
                    return links.resolvedJsxElementAttributesType = errorType;
                }
            }
            return links.resolvedJsxElementAttributesType;
        }
        function getJsxElementClassTypeAt(location) {
            var type = getJsxType(JsxNames.ElementClass, location);
            if (type === errorType)
                return undefined;
            return type;
        }
        function getJsxElementTypeAt(location) {
            return getJsxType(JsxNames.Element, location);
        }
        function getJsxStatelessElementTypeAt(location) {
            var jsxElementType = getJsxElementTypeAt(location);
            if (jsxElementType) {
                return getUnionType([jsxElementType, nullType]);
            }
        }
        /**
         * Returns all the properties of the Jsx.IntrinsicElements interface
         */
        function getJsxIntrinsicTagNamesAt(location) {
            var intrinsics = getJsxType(JsxNames.IntrinsicElements, location);
            return intrinsics ? getPropertiesOfType(intrinsics) : ts.emptyArray;
        }
        function checkJsxPreconditions(errorNode) {
            // Preconditions for using JSX
            if ((compilerOptions.jsx || 0 /* None */) === 0 /* None */) {
                error(errorNode, ts.Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
            }
            if (getJsxElementTypeAt(errorNode) === undefined) {
                if (noImplicitAny) {
                    error(errorNode, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
                }
            }
        }
        function checkJsxOpeningLikeElementOrOpeningFragment(node) {
            var isNodeOpeningLikeElement = ts.isJsxOpeningLikeElement(node);
            if (isNodeOpeningLikeElement) {
                checkGrammarJsxElement(node);
            }
            checkJsxPreconditions(node);
            // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
            // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
            var reactRefErr = diagnostics && compilerOptions.jsx === 2 /* React */ ? ts.Diagnostics.Cannot_find_name_0 : undefined;
            var reactNamespace = getJsxNamespace(node);
            var reactLocation = isNodeOpeningLikeElement ? node.tagName : node;
            var reactSym = resolveName(reactLocation, reactNamespace, 111551 /* Value */, reactRefErr, reactNamespace, /*isUse*/ true);
            if (reactSym) {
                // Mark local symbol as referenced here because it might not have been marked
                // if jsx emit was not react as there wont be error being emitted
                reactSym.isReferenced = 67108863 /* All */;
                // If react symbol is alias, mark it as refereced
                if (reactSym.flags & 2097152 /* Alias */ && !getTypeOnlyAliasDeclaration(reactSym)) {
                    markAliasSymbolAsReferenced(reactSym);
                }
            }
            if (isNodeOpeningLikeElement) {
                var jsxOpeningLikeNode = node;
                var sig = getResolvedSignature(jsxOpeningLikeNode);
                checkJsxReturnAssignableToAppropriateBound(getJsxReferenceKind(jsxOpeningLikeNode), getReturnTypeOfSignature(sig), jsxOpeningLikeNode);
            }
        }
        /**
         * Check if a property with the given name is known anywhere in the given type. In an object type, a property
         * is considered known if
         * 1. the object type is empty and the check is for assignability, or
         * 2. if the object type has index signatures, or
         * 3. if the property is actually declared in the object type
         *    (this means that 'toString', for example, is not usually a known property).
         * 4. In a union or intersection type,
         *    a property is considered known if it is known in any constituent type.
         * @param targetType a type to search a given name in
         * @param name a property name to search
         * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType
         */
        function isKnownProperty(targetType, name, isComparingJsxAttributes) {
            if (targetType.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(targetType);
                if (resolved.stringIndexInfo ||
                    resolved.numberIndexInfo && isNumericLiteralName(name) ||
                    getPropertyOfObjectType(targetType, name) ||
                    isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) {
                    // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known.
                    return true;
                }
            }
            else if (targetType.flags & 3145728 /* UnionOrIntersection */ && isExcessPropertyCheckTarget(targetType)) {
                for (var _i = 0, _a = targetType.types; _i < _a.length; _i++) {
                    var t = _a[_i];
                    if (isKnownProperty(t, name, isComparingJsxAttributes)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isExcessPropertyCheckTarget(type) {
            return !!(type.flags & 524288 /* Object */ && !(ts.getObjectFlags(type) & 512 /* ObjectLiteralPatternWithComputedProperties */) ||
                type.flags & 67108864 /* NonPrimitive */ ||
                type.flags & 1048576 /* Union */ && ts.some(type.types, isExcessPropertyCheckTarget) ||
                type.flags & 2097152 /* Intersection */ && ts.every(type.types, isExcessPropertyCheckTarget));
        }
        function checkJsxExpression(node, checkMode) {
            checkGrammarJsxExpression(node);
            if (node.expression) {
                var type = checkExpression(node.expression, checkMode);
                if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) {
                    error(node, ts.Diagnostics.JSX_spread_child_must_be_an_array_type);
                }
                return type;
            }
            else {
                return errorType;
            }
        }
        function getDeclarationNodeFlagsFromSymbol(s) {
            return s.valueDeclaration ? ts.getCombinedNodeFlags(s.valueDeclaration) : 0;
        }
        /**
         * Return whether this symbol is a member of a prototype somewhere
         * Note that this is not tracked well within the compiler, so the answer may be incorrect.
         */
        function isPrototypeProperty(symbol) {
            if (symbol.flags & 8192 /* Method */ || ts.getCheckFlags(symbol) & 4 /* SyntheticMethod */) {
                return true;
            }
            if (ts.isInJSFile(symbol.valueDeclaration)) {
                var parent = symbol.valueDeclaration.parent;
                return parent && ts.isBinaryExpression(parent) &&
                    ts.getAssignmentDeclarationKind(parent) === 3 /* PrototypeProperty */;
            }
        }
        /**
         * Check whether the requested property access is valid.
         * Returns true if node is a valid property access, and false otherwise.
         * @param node The node to be checked.
         * @param isSuper True if the access is from `super.`.
         * @param type The type of the object whose property is being accessed. (Not the type of the property.)
         * @param prop The symbol for the property being accessed.
         */
        function checkPropertyAccessibility(node, isSuper, type, prop) {
            var flags = ts.getDeclarationModifierFlagsFromSymbol(prop);
            var errorNode = node.kind === 153 /* QualifiedName */ ? node.right : node.kind === 188 /* ImportType */ ? node : node.name;
            if (isSuper) {
                // TS 1.0 spec (April 2014): 4.8.2
                // - In a constructor, instance member function, instance member accessor, or
                //   instance member variable initializer where this references a derived class instance,
                //   a super property access is permitted and must specify a public instance member function of the base class.
                // - In a static member function or static member accessor
                //   where this references the constructor function object of a derived class,
                //   a super property access is permitted and must specify a public static member function of the base class.
                if (languageVersion < 2 /* ES2015 */) {
                    if (symbolHasNonMethodDeclaration(prop)) {
                        error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword);
                        return false;
                    }
                }
                if (flags & 128 /* Abstract */) {
                    // A method cannot be accessed in a super property access if the method is abstract.
                    // This error could mask a private property access error. But, a member
                    // cannot simultaneously be private and abstract, so this will trigger an
                    // additional error elsewhere.
                    error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(getDeclaringClass(prop)));
                    return false;
                }
            }
            // Referencing abstract properties within their own constructors is not allowed
            if ((flags & 128 /* Abstract */) && ts.isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) {
                var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
                if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node)) {
                    error(errorNode, ts.Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), ts.getTextOfIdentifierOrLiteral(declaringClassDeclaration.name)); // TODO: GH#18217
                    return false;
                }
            }
            if (ts.isPropertyAccessExpression(node) && ts.isPrivateIdentifier(node.name)) {
                if (!ts.getContainingClass(node)) {
                    error(errorNode, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
                    return false;
                }
                return true;
            }
            // Public properties are otherwise accessible.
            if (!(flags & 24 /* NonPublicAccessibilityModifier */)) {
                return true;
            }
            // Property is known to be private or protected at this point
            // Private property is accessible if the property is within the declaring class
            if (flags & 8 /* Private */) {
                var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
                if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                    error(errorNode, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop)));
                    return false;
                }
                return true;
            }
            // Property is known to be protected at this point
            // All protected properties of a supertype are accessible in a super access
            if (isSuper) {
                return true;
            }
            // Find the first enclosing class that has the declaring classes of the protected constituents
            // of the property as base classes
            var enclosingClass = forEachEnclosingClass(node, function (enclosingDeclaration) {
                var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration));
                return isClassDerivedFromDeclaringClasses(enclosingClass, prop) ? enclosingClass : undefined;
            });
            // A protected property is accessible if the property is within the declaring class or classes derived from it
            if (!enclosingClass) {
                // allow PropertyAccessibility if context is in function with this parameter
                // static member access is disallow
                var thisParameter = void 0;
                if (flags & 32 /* Static */ || !(thisParameter = getThisParameterFromNodeContext(node)) || !thisParameter.type) {
                    error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(getDeclaringClass(prop) || type));
                    return false;
                }
                var thisType = getTypeFromTypeNode(thisParameter.type);
                enclosingClass = ((thisType.flags & 262144 /* TypeParameter */) ? getConstraintOfTypeParameter(thisType) : thisType).target;
            }
            // No further restrictions for static properties
            if (flags & 32 /* Static */) {
                return true;
            }
            if (type.flags & 262144 /* TypeParameter */) {
                // get the original type -- represented as the type constraint of the 'this' type
                type = type.isThisType ? getConstraintOfTypeParameter(type) : getBaseConstraintOfType(type); // TODO: GH#18217 Use a different variable that's allowed to be undefined
            }
            if (!type || !hasBaseType(type, enclosingClass)) {
                error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
                return false;
            }
            return true;
        }
        function getThisParameterFromNodeContext(node) {
            var thisContainer = ts.getThisContainer(node, /* includeArrowFunctions */ false);
            return thisContainer && ts.isFunctionLike(thisContainer) ? ts.getThisParameter(thisContainer) : undefined;
        }
        function symbolHasNonMethodDeclaration(symbol) {
            return !!forEachProperty(symbol, function (prop) { return !(prop.flags & 8192 /* Method */); });
        }
        function checkNonNullExpression(node) {
            return checkNonNullType(checkExpression(node), node);
        }
        function isNullableType(type) {
            return !!((strictNullChecks ? getFalsyFlags(type) : type.flags) & 98304 /* Nullable */);
        }
        function getNonNullableTypeIfNeeded(type) {
            return isNullableType(type) ? getNonNullableType(type) : type;
        }
        function reportObjectPossiblyNullOrUndefinedError(node, flags) {
            error(node, flags & 32768 /* Undefined */ ? flags & 65536 /* Null */ ?
                ts.Diagnostics.Object_is_possibly_null_or_undefined :
                ts.Diagnostics.Object_is_possibly_undefined :
                ts.Diagnostics.Object_is_possibly_null);
        }
        function reportCannotInvokePossiblyNullOrUndefinedError(node, flags) {
            error(node, flags & 32768 /* Undefined */ ? flags & 65536 /* Null */ ?
                ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined :
                ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined :
                ts.Diagnostics.Cannot_invoke_an_object_which_is_possibly_null);
        }
        function checkNonNullTypeWithReporter(type, node, reportError) {
            if (strictNullChecks && type.flags & 2 /* Unknown */) {
                error(node, ts.Diagnostics.Object_is_of_type_unknown);
                return errorType;
            }
            var kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & 98304 /* Nullable */;
            if (kind) {
                reportError(node, kind);
                var t = getNonNullableType(type);
                return t.flags & (98304 /* Nullable */ | 131072 /* Never */) ? errorType : t;
            }
            return type;
        }
        function checkNonNullType(type, node) {
            return checkNonNullTypeWithReporter(type, node, reportObjectPossiblyNullOrUndefinedError);
        }
        function checkNonNullNonVoidType(type, node) {
            var nonNullType = checkNonNullType(type, node);
            if (nonNullType !== errorType && nonNullType.flags & 16384 /* Void */) {
                error(node, ts.Diagnostics.Object_is_possibly_undefined);
            }
            return nonNullType;
        }
        function checkPropertyAccessExpression(node) {
            return node.flags & 32 /* OptionalChain */ ? checkPropertyAccessChain(node) :
                checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullExpression(node.expression), node.name);
        }
        function checkPropertyAccessChain(node) {
            var leftType = checkExpression(node.expression);
            var nonOptionalType = getOptionalExpressionType(leftType, node.expression);
            return propagateOptionalTypeMarker(checkPropertyAccessExpressionOrQualifiedName(node, node.expression, checkNonNullType(nonOptionalType, node.expression), node.name), node, nonOptionalType !== leftType);
        }
        function checkQualifiedName(node) {
            return checkPropertyAccessExpressionOrQualifiedName(node, node.left, checkNonNullExpression(node.left), node.right);
        }
        function isMethodAccessForCall(node) {
            while (node.parent.kind === 200 /* ParenthesizedExpression */) {
                node = node.parent;
            }
            return ts.isCallOrNewExpression(node.parent) && node.parent.expression === node;
        }
        // Lookup the private identifier lexically.
        function lookupSymbolForPrivateIdentifierDeclaration(propName, location) {
            for (var containingClass = ts.getContainingClass(location); !!containingClass; containingClass = ts.getContainingClass(containingClass)) {
                var symbol = containingClass.symbol;
                var name = ts.getSymbolNameForPrivateIdentifier(symbol, propName);
                var prop = (symbol.members && symbol.members.get(name)) || (symbol.exports && symbol.exports.get(name));
                if (prop) {
                    return prop;
                }
            }
        }
        function getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedIdentifier) {
            return getPropertyOfType(leftType, lexicallyScopedIdentifier.escapedName);
        }
        function checkPrivateIdentifierPropertyAccess(leftType, right, lexicallyScopedIdentifier) {
            // Either the identifier could not be looked up in the lexical scope OR the lexically scoped identifier did not exist on the type.
            // Find a private identifier with the same description on the type.
            var propertyOnType;
            var properties = getPropertiesOfType(leftType);
            if (properties) {
                ts.forEach(properties, function (symbol) {
                    var decl = symbol.valueDeclaration;
                    if (decl && ts.isNamedDeclaration(decl) && ts.isPrivateIdentifier(decl.name) && decl.name.escapedText === right.escapedText) {
                        propertyOnType = symbol;
                        return true;
                    }
                });
            }
            var diagName = diagnosticName(right);
            if (propertyOnType) {
                var typeValueDecl = propertyOnType.valueDeclaration;
                var typeClass_1 = ts.getContainingClass(typeValueDecl);
                ts.Debug.assert(!!typeClass_1);
                // We found a private identifier property with the same description.
                // Either:
                // - There is a lexically scoped private identifier AND it shadows the one we found on the type.
                // - It is an attempt to access the private identifier outside of the class.
                if (lexicallyScopedIdentifier) {
                    var lexicalValueDecl = lexicallyScopedIdentifier.valueDeclaration;
                    var lexicalClass = ts.getContainingClass(lexicalValueDecl);
                    ts.Debug.assert(!!lexicalClass);
                    if (ts.findAncestor(lexicalClass, function (n) { return typeClass_1 === n; })) {
                        var diagnostic = error(right, ts.Diagnostics.The_property_0_cannot_be_accessed_on_type_1_within_this_class_because_it_is_shadowed_by_another_private_identifier_with_the_same_spelling, diagName, typeToString(leftType));
                        ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(lexicalValueDecl, ts.Diagnostics.The_shadowing_declaration_of_0_is_defined_here, diagName), ts.createDiagnosticForNode(typeValueDecl, ts.Diagnostics.The_declaration_of_0_that_you_probably_intended_to_use_is_defined_here, diagName));
                        return true;
                    }
                }
                error(right, ts.Diagnostics.Property_0_is_not_accessible_outside_class_1_because_it_has_a_private_identifier, diagName, diagnosticName(typeClass_1.name || anon));
                return true;
            }
            return false;
        }
        function checkPropertyAccessExpressionOrQualifiedName(node, left, leftType, right) {
            var parentSymbol = getNodeLinks(left).resolvedSymbol;
            var assignmentKind = ts.getAssignmentTargetKind(node);
            var apparentType = getApparentType(assignmentKind !== 0 /* None */ || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType);
            if (ts.isPrivateIdentifier(right)) {
                checkExternalEmitHelpers(node, 262144 /* ClassPrivateFieldGet */);
            }
            var isAnyLike = isTypeAny(apparentType) || apparentType === silentNeverType;
            var prop;
            if (ts.isPrivateIdentifier(right)) {
                var lexicallyScopedSymbol = lookupSymbolForPrivateIdentifierDeclaration(right.escapedText, right);
                if (isAnyLike) {
                    if (lexicallyScopedSymbol) {
                        return apparentType;
                    }
                    if (!ts.getContainingClass(right)) {
                        grammarErrorOnNode(right, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
                        return anyType;
                    }
                }
                prop = lexicallyScopedSymbol ? getPrivateIdentifierPropertyOfType(leftType, lexicallyScopedSymbol) : undefined;
                // Check for private-identifier-specific shadowing and lexical-scoping errors.
                if (!prop && checkPrivateIdentifierPropertyAccess(leftType, right, lexicallyScopedSymbol)) {
                    return errorType;
                }
            }
            else {
                if (isAnyLike) {
                    if (ts.isIdentifier(left) && parentSymbol) {
                        markAliasReferenced(parentSymbol, node);
                    }
                    return apparentType;
                }
                prop = getPropertyOfType(apparentType, right.escapedText);
            }
            if (ts.isIdentifier(left) && parentSymbol && !(prop && isConstEnumOrConstEnumOnlyModule(prop))) {
                markAliasReferenced(parentSymbol, node);
            }
            var propType;
            if (!prop) {
                var indexInfo = !ts.isPrivateIdentifier(right) && (assignmentKind === 0 /* None */ || !isGenericObjectType(leftType) || isThisTypeParameter(leftType)) ? getIndexInfoOfType(apparentType, 0 /* String */) : undefined;
                if (!(indexInfo && indexInfo.type)) {
                    if (isJSLiteralType(leftType)) {
                        return anyType;
                    }
                    if (leftType.symbol === globalThisSymbol) {
                        if (globalThisSymbol.exports.has(right.escapedText) && (globalThisSymbol.exports.get(right.escapedText).flags & 418 /* BlockScoped */)) {
                            error(right, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.unescapeLeadingUnderscores(right.escapedText), typeToString(leftType));
                        }
                        else if (noImplicitAny) {
                            error(right, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(leftType));
                        }
                        return anyType;
                    }
                    if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
                        reportNonexistentProperty(right, isThisTypeParameter(leftType) ? apparentType : leftType);
                    }
                    return errorType;
                }
                if (indexInfo.isReadonly && (ts.isAssignmentTarget(node) || ts.isDeleteTarget(node))) {
                    error(node, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType));
                }
                propType = indexInfo.type;
            }
            else {
                checkPropertyNotUsedBeforeDeclaration(prop, node, right);
                markPropertyAsReferenced(prop, node, left.kind === 104 /* ThisKeyword */);
                getNodeLinks(node).resolvedSymbol = prop;
                checkPropertyAccessibility(node, left.kind === 102 /* SuperKeyword */, apparentType, prop);
                if (isAssignmentToReadonlyEntity(node, prop, assignmentKind)) {
                    error(right, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_read_only_property, ts.idText(right));
                    return errorType;
                }
                propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
            }
            return getFlowTypeOfAccessExpression(node, prop, propType, right);
        }
        function getFlowTypeOfAccessExpression(node, prop, propType, errorNode) {
            // Only compute control flow type if this is a property access expression that isn't an
            // assignment target, and the referenced property was declared as a variable, property,
            // accessor, or optional method.
            var assignmentKind = ts.getAssignmentTargetKind(node);
            if (!ts.isAccessExpression(node) ||
                assignmentKind === 1 /* Definite */ ||
                prop && !(prop.flags & (3 /* Variable */ | 4 /* Property */ | 98304 /* Accessor */)) && !(prop.flags & 8192 /* Method */ && propType.flags & 1048576 /* Union */)) {
                return propType;
            }
            // If strict null checks and strict property initialization checks are enabled, if we have
            // a this.xxx property access, if the property is an instance property without an initializer,
            // and if we are in a constructor of the same class as the property declaration, assume that
            // the property is uninitialized at the top of the control flow.
            var assumeUninitialized = false;
            if (strictNullChecks && strictPropertyInitialization && node.expression.kind === 104 /* ThisKeyword */) {
                var declaration = prop && prop.valueDeclaration;
                if (declaration && isInstancePropertyWithoutInitializer(declaration)) {
                    var flowContainer = getControlFlowContainer(node);
                    if (flowContainer.kind === 162 /* Constructor */ && flowContainer.parent === declaration.parent && !(declaration.flags & 8388608 /* Ambient */)) {
                        assumeUninitialized = true;
                    }
                }
            }
            else if (strictNullChecks && prop && prop.valueDeclaration &&
                ts.isPropertyAccessExpression(prop.valueDeclaration) &&
                ts.getAssignmentDeclarationPropertyAccessKind(prop.valueDeclaration) &&
                getControlFlowContainer(node) === getControlFlowContainer(prop.valueDeclaration)) {
                assumeUninitialized = true;
            }
            var flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType);
            if (assumeUninitialized && !(getFalsyFlags(propType) & 32768 /* Undefined */) && getFalsyFlags(flowType) & 32768 /* Undefined */) {
                error(errorNode, ts.Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop)); // TODO: GH#18217
                // Return the declared type to reduce follow-on errors
                return propType;
            }
            return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType;
        }
        function checkPropertyNotUsedBeforeDeclaration(prop, node, right) {
            var valueDeclaration = prop.valueDeclaration;
            if (!valueDeclaration || ts.getSourceFileOfNode(node).isDeclarationFile) {
                return;
            }
            var diagnosticMessage;
            var declarationName = ts.idText(right);
            if (isInPropertyInitializer(node)
                && !(ts.isAccessExpression(node) && ts.isAccessExpression(node.expression))
                && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)
                && !isPropertyDeclaredInAncestorClass(prop)) {
                diagnosticMessage = error(right, ts.Diagnostics.Property_0_is_used_before_its_initialization, declarationName);
            }
            else if (valueDeclaration.kind === 245 /* ClassDeclaration */ &&
                node.parent.kind !== 169 /* TypeReference */ &&
                !(valueDeclaration.flags & 8388608 /* Ambient */) &&
                !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) {
                diagnosticMessage = error(right, ts.Diagnostics.Class_0_used_before_its_declaration, declarationName);
            }
            if (diagnosticMessage) {
                ts.addRelatedInfo(diagnosticMessage, ts.createDiagnosticForNode(valueDeclaration, ts.Diagnostics._0_is_declared_here, declarationName));
            }
        }
        function isInPropertyInitializer(node) {
            return !!ts.findAncestor(node, function (node) {
                switch (node.kind) {
                    case 159 /* PropertyDeclaration */:
                        return true;
                    case 281 /* PropertyAssignment */:
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                    case 283 /* SpreadAssignment */:
                    case 154 /* ComputedPropertyName */:
                    case 221 /* TemplateSpan */:
                    case 276 /* JsxExpression */:
                    case 273 /* JsxAttribute */:
                    case 274 /* JsxAttributes */:
                    case 275 /* JsxSpreadAttribute */:
                    case 268 /* JsxOpeningElement */:
                    case 216 /* ExpressionWithTypeArguments */:
                    case 279 /* HeritageClause */:
                        return false;
                    default:
                        return ts.isExpressionNode(node) ? false : "quit";
                }
            });
        }
        /**
         * It's possible that "prop.valueDeclaration" is a local declaration, but the property was also declared in a superclass.
         * In that case we won't consider it used before its declaration, because it gets its value from the superclass' declaration.
         */
        function isPropertyDeclaredInAncestorClass(prop) {
            if (!(prop.parent.flags & 32 /* Class */)) {
                return false;
            }
            var classType = getTypeOfSymbol(prop.parent);
            while (true) {
                classType = classType.symbol && getSuperClass(classType);
                if (!classType) {
                    return false;
                }
                var superProperty = getPropertyOfType(classType, prop.escapedName);
                if (superProperty && superProperty.valueDeclaration) {
                    return true;
                }
            }
        }
        function getSuperClass(classType) {
            var x = getBaseTypes(classType);
            if (x.length === 0) {
                return undefined;
            }
            return getIntersectionType(x);
        }
        function reportNonexistentProperty(propNode, containingType) {
            var errorInfo;
            var relatedInfo;
            if (!ts.isPrivateIdentifier(propNode) && containingType.flags & 1048576 /* Union */ && !(containingType.flags & 131068 /* Primitive */)) {
                for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) {
                    var subtype = _a[_i];
                    if (!getPropertyOfType(subtype, propNode.escapedText) && !getIndexInfoOfType(subtype, 0 /* String */)) {
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(subtype));
                        break;
                    }
                }
            }
            if (typeHasStaticProperty(propNode.escapedText, containingType)) {
                errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_is_a_static_member_of_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
            }
            else {
                var promisedType = getPromisedTypeOfPromise(containingType);
                if (promisedType && getPropertyOfType(promisedType, propNode.escapedText)) {
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
                    relatedInfo = ts.createDiagnosticForNode(propNode, ts.Diagnostics.Did_you_forget_to_use_await);
                }
                else {
                    var suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType);
                    if (suggestion !== undefined) {
                        var suggestedName = ts.symbolName(suggestion);
                        errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, ts.declarationNameToString(propNode), typeToString(containingType), suggestedName);
                        relatedInfo = suggestion.valueDeclaration && ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestedName);
                    }
                    else {
                        errorInfo = ts.chainDiagnosticMessages(elaborateNeverIntersection(errorInfo, containingType), ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType));
                    }
                }
            }
            var resultDiagnostic = ts.createDiagnosticForNodeFromMessageChain(propNode, errorInfo);
            if (relatedInfo) {
                ts.addRelatedInfo(resultDiagnostic, relatedInfo);
            }
            diagnostics.add(resultDiagnostic);
        }
        function typeHasStaticProperty(propName, containingType) {
            var prop = containingType.symbol && getPropertyOfType(getTypeOfSymbol(containingType.symbol), propName);
            return prop !== undefined && prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 32 /* Static */);
        }
        function getSuggestedSymbolForNonexistentProperty(name, containingType) {
            return getSpellingSuggestionForName(ts.isString(name) ? name : ts.idText(name), getPropertiesOfType(containingType), 111551 /* Value */);
        }
        function getSuggestionForNonexistentProperty(name, containingType) {
            var suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType);
            return suggestion && ts.symbolName(suggestion);
        }
        function getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning) {
            ts.Debug.assert(outerName !== undefined, "outername should always be defined");
            var result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, function (symbols, name, meaning) {
                ts.Debug.assertEqual(outerName, name, "name should equal outerName");
                var symbol = getSymbol(symbols, name, meaning);
                // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function
                // So the table *contains* `x` but `x` isn't actually in scope.
                // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
                return symbol || getSpellingSuggestionForName(ts.unescapeLeadingUnderscores(name), ts.arrayFrom(symbols.values()), meaning);
            });
            return result;
        }
        function getSuggestionForNonexistentSymbol(location, outerName, meaning) {
            var symbolResult = getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning);
            return symbolResult && ts.symbolName(symbolResult);
        }
        function getSuggestedSymbolForNonexistentModule(name, targetModule) {
            return targetModule.exports && getSpellingSuggestionForName(ts.idText(name), getExportsOfModuleAsArray(targetModule), 2623475 /* ModuleMember */);
        }
        function getSuggestionForNonexistentExport(name, targetModule) {
            var suggestion = getSuggestedSymbolForNonexistentModule(name, targetModule);
            return suggestion && ts.symbolName(suggestion);
        }
        function getSuggestionForNonexistentIndexSignature(objectType, expr, keyedType) {
            // check if object type has setter or getter
            function hasProp(name) {
                var prop = getPropertyOfObjectType(objectType, name);
                if (prop) {
                    var s = getSingleCallSignature(getTypeOfSymbol(prop));
                    return !!s && getMinArgumentCount(s) >= 1 && isTypeAssignableTo(keyedType, getTypeAtPosition(s, 0));
                }
                return false;
            }
            ;
            var suggestedMethod = ts.isAssignmentTarget(expr) ? "set" : "get";
            if (!hasProp(suggestedMethod)) {
                return undefined;
            }
            var suggestion = ts.tryGetPropertyAccessOrIdentifierToString(expr.expression);
            if (suggestion === undefined) {
                suggestion = suggestedMethod;
            }
            else {
                suggestion += "." + suggestedMethod;
            }
            return suggestion;
        }
        /**
         * Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough.
         * Names less than length 3 only check for case-insensitive equality, not levenshtein distance.
         *
         * If there is a candidate that's the same except for case, return that.
         * If there is a candidate that's within one edit of the name, return that.
         * Otherwise, return the candidate with the smallest Levenshtein distance,
         *    except for candidates:
         *      * With no name
         *      * Whose meaning doesn't match the `meaning` parameter.
         *      * Whose length differs from the target name by more than 0.34 of the length of the name.
         *      * Whose levenshtein distance is more than 0.4 of the length of the name
         *        (0.4 allows 1 substitution/transposition for every 5 characters,
         *         and 1 insertion/deletion at 3 characters)
         */
        function getSpellingSuggestionForName(name, symbols, meaning) {
            return ts.getSpellingSuggestion(name, symbols, getCandidateName);
            function getCandidateName(candidate) {
                var candidateName = ts.symbolName(candidate);
                if (ts.startsWith(candidateName, "\"")) {
                    return undefined;
                }
                if (candidate.flags & meaning) {
                    return candidateName;
                }
                if (candidate.flags & 2097152 /* Alias */) {
                    var alias = tryResolveAlias(candidate);
                    if (alias && alias.flags & meaning) {
                        return candidateName;
                    }
                }
                return undefined;
            }
        }
        function markPropertyAsReferenced(prop, nodeForCheckWriteOnly, isThisAccess) {
            var valueDeclaration = prop && (prop.flags & 106500 /* ClassMember */) && prop.valueDeclaration;
            if (!valueDeclaration) {
                return;
            }
            var hasPrivateModifier = ts.hasModifier(valueDeclaration, 8 /* Private */);
            var hasPrivateIdentifier = ts.isNamedDeclaration(prop.valueDeclaration) && ts.isPrivateIdentifier(prop.valueDeclaration.name);
            if (!hasPrivateModifier && !hasPrivateIdentifier) {
                return;
            }
            if (nodeForCheckWriteOnly && ts.isWriteOnlyAccess(nodeForCheckWriteOnly) && !(prop.flags & 65536 /* SetAccessor */)) {
                return;
            }
            if (isThisAccess) {
                // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters).
                var containingMethod = ts.findAncestor(nodeForCheckWriteOnly, ts.isFunctionLikeDeclaration);
                if (containingMethod && containingMethod.symbol === prop) {
                    return;
                }
            }
            (ts.getCheckFlags(prop) & 1 /* Instantiated */ ? getSymbolLinks(prop).target : prop).isReferenced = 67108863 /* All */;
        }
        function isValidPropertyAccess(node, propertyName) {
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                    return isValidPropertyAccessWithType(node, node.expression.kind === 102 /* SuperKeyword */, propertyName, getWidenedType(checkExpression(node.expression)));
                case 153 /* QualifiedName */:
                    return isValidPropertyAccessWithType(node, /*isSuper*/ false, propertyName, getWidenedType(checkExpression(node.left)));
                case 188 /* ImportType */:
                    return isValidPropertyAccessWithType(node, /*isSuper*/ false, propertyName, getTypeFromTypeNode(node));
            }
        }
        function isValidPropertyAccessForCompletions(node, type, property) {
            return isValidPropertyAccessWithType(node, node.kind === 194 /* PropertyAccessExpression */ && node.expression.kind === 102 /* SuperKeyword */, property.escapedName, type);
            // Previously we validated the 'this' type of methods but this adversely affected performance. See #31377 for more context.
        }
        function isValidPropertyAccessWithType(node, isSuper, propertyName, type) {
            if (type === errorType || isTypeAny(type)) {
                return true;
            }
            var prop = getPropertyOfType(type, propertyName);
            if (prop) {
                if (ts.isPropertyAccessExpression(node) && prop.valueDeclaration && ts.isPrivateIdentifierPropertyDeclaration(prop.valueDeclaration)) {
                    var declClass_1 = ts.getContainingClass(prop.valueDeclaration);
                    return !ts.isOptionalChain(node) && !!ts.findAncestor(node, function (parent) { return parent === declClass_1; });
                }
                return checkPropertyAccessibility(node, isSuper, type, prop);
            }
            // In js files properties of unions are allowed in completion
            return ts.isInJSFile(node) && (type.flags & 1048576 /* Union */) !== 0 && type.types.some(function (elementType) { return isValidPropertyAccessWithType(node, isSuper, propertyName, elementType); });
        }
        /**
         * Return the symbol of the for-in variable declared or referenced by the given for-in statement.
         */
        function getForInVariableSymbol(node) {
            var initializer = node.initializer;
            if (initializer.kind === 243 /* VariableDeclarationList */) {
                var variable = initializer.declarations[0];
                if (variable && !ts.isBindingPattern(variable.name)) {
                    return getSymbolOfNode(variable);
                }
            }
            else if (initializer.kind === 75 /* Identifier */) {
                return getResolvedSymbol(initializer);
            }
            return undefined;
        }
        /**
         * Return true if the given type is considered to have numeric property names.
         */
        function hasNumericPropertyNames(type) {
            return getIndexTypeOfType(type, 1 /* Number */) && !getIndexTypeOfType(type, 0 /* String */);
        }
        /**
         * Return true if given node is an expression consisting of an identifier (possibly parenthesized)
         * that references a for-in variable for an object with numeric property names.
         */
        function isForInVariableForNumericPropertyNames(expr) {
            var e = ts.skipParentheses(expr);
            if (e.kind === 75 /* Identifier */) {
                var symbol = getResolvedSymbol(e);
                if (symbol.flags & 3 /* Variable */) {
                    var child = expr;
                    var node = expr.parent;
                    while (node) {
                        if (node.kind === 231 /* ForInStatement */ &&
                            child === node.statement &&
                            getForInVariableSymbol(node) === symbol &&
                            hasNumericPropertyNames(getTypeOfExpression(node.expression))) {
                            return true;
                        }
                        child = node;
                        node = node.parent;
                    }
                }
            }
            return false;
        }
        function checkIndexedAccess(node) {
            return node.flags & 32 /* OptionalChain */ ? checkElementAccessChain(node) :
                checkElementAccessExpression(node, checkNonNullExpression(node.expression));
        }
        function checkElementAccessChain(node) {
            var exprType = checkExpression(node.expression);
            var nonOptionalType = getOptionalExpressionType(exprType, node.expression);
            return propagateOptionalTypeMarker(checkElementAccessExpression(node, checkNonNullType(nonOptionalType, node.expression)), node, nonOptionalType !== exprType);
        }
        function checkElementAccessExpression(node, exprType) {
            var objectType = ts.getAssignmentTargetKind(node) !== 0 /* None */ || isMethodAccessForCall(node) ? getWidenedType(exprType) : exprType;
            var indexExpression = node.argumentExpression;
            var indexType = checkExpression(indexExpression);
            if (objectType === errorType || objectType === silentNeverType) {
                return objectType;
            }
            if (isConstEnumObjectType(objectType) && !ts.isStringLiteralLike(indexExpression)) {
                error(indexExpression, ts.Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal);
                return errorType;
            }
            var effectiveIndexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType;
            var accessFlags = ts.isAssignmentTarget(node) ?
                2 /* Writing */ | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? 1 /* NoIndexSignatures */ : 0) :
                0 /* None */;
            var indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
            return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, indexedAccessType.symbol, indexedAccessType, indexExpression), node);
        }
        function checkThatExpressionIsProperSymbolReference(expression, expressionType, reportError) {
            if (expressionType === errorType) {
                // There is already an error, so no need to report one.
                return false;
            }
            if (!ts.isWellKnownSymbolSyntactically(expression)) {
                return false;
            }
            // Make sure the property type is the primitive symbol type
            if ((expressionType.flags & 12288 /* ESSymbolLike */) === 0) {
                if (reportError) {
                    error(expression, ts.Diagnostics.A_computed_property_name_of_the_form_0_must_be_of_type_symbol, ts.getTextOfNode(expression));
                }
                return false;
            }
            // The name is Symbol.<someName>, so make sure Symbol actually resolves to the
            // global Symbol object
            var leftHandSide = expression.expression;
            var leftHandSideSymbol = getResolvedSymbol(leftHandSide);
            if (!leftHandSideSymbol) {
                return false;
            }
            var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ true);
            if (!globalESSymbol) {
                // Already errored when we tried to look up the symbol
                return false;
            }
            if (leftHandSideSymbol !== globalESSymbol) {
                if (reportError) {
                    error(leftHandSide, ts.Diagnostics.Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object);
                }
                return false;
            }
            return true;
        }
        function callLikeExpressionMayHaveTypeArguments(node) {
            return ts.isCallOrNewExpression(node) || ts.isTaggedTemplateExpression(node) || ts.isJsxOpeningLikeElement(node);
        }
        function resolveUntypedCall(node) {
            if (callLikeExpressionMayHaveTypeArguments(node)) {
                // Check type arguments even though we will give an error that untyped calls may not accept type arguments.
                // This gets us diagnostics for the type arguments and marks them as referenced.
                ts.forEach(node.typeArguments, checkSourceElement);
            }
            if (node.kind === 198 /* TaggedTemplateExpression */) {
                checkExpression(node.template);
            }
            else if (ts.isJsxOpeningLikeElement(node)) {
                checkExpression(node.attributes);
            }
            else if (node.kind !== 157 /* Decorator */) {
                ts.forEach(node.arguments, function (argument) {
                    checkExpression(argument);
                });
            }
            return anySignature;
        }
        function resolveErrorCall(node) {
            resolveUntypedCall(node);
            return unknownSignature;
        }
        // Re-order candidate signatures into the result array. Assumes the result array to be empty.
        // The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
        // A nit here is that we reorder only signatures that belong to the same symbol,
        // so order how inherited signatures are processed is still preserved.
        // interface A { (x: string): void }
        // interface B extends A { (x: 'foo'): string }
        // const b: B;
        // b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void]
        function reorderCandidates(signatures, result, callChainFlags) {
            var lastParent;
            var lastSymbol;
            var cutoffIndex = 0;
            var index;
            var specializedIndex = -1;
            var spliceIndex;
            ts.Debug.assert(!result.length);
            for (var _i = 0, signatures_7 = signatures; _i < signatures_7.length; _i++) {
                var signature = signatures_7[_i];
                var symbol = signature.declaration && getSymbolOfNode(signature.declaration);
                var parent = signature.declaration && signature.declaration.parent;
                if (!lastSymbol || symbol === lastSymbol) {
                    if (lastParent && parent === lastParent) {
                        index = index + 1;
                    }
                    else {
                        lastParent = parent;
                        index = cutoffIndex;
                    }
                }
                else {
                    // current declaration belongs to a different symbol
                    // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex
                    index = cutoffIndex = result.length;
                    lastParent = parent;
                }
                lastSymbol = symbol;
                // specialized signatures always need to be placed before non-specialized signatures regardless
                // of the cutoff position; see GH#1133
                if (signatureHasLiteralTypes(signature)) {
                    specializedIndex++;
                    spliceIndex = specializedIndex;
                    // The cutoff index always needs to be greater than or equal to the specialized signature index
                    // in order to prevent non-specialized signatures from being added before a specialized
                    // signature.
                    cutoffIndex++;
                }
                else {
                    spliceIndex = index;
                }
                result.splice(spliceIndex, 0, callChainFlags ? getOptionalCallSignature(signature, callChainFlags) : signature);
            }
        }
        function isSpreadArgument(arg) {
            return !!arg && (arg.kind === 213 /* SpreadElement */ || arg.kind === 220 /* SyntheticExpression */ && arg.isSpread);
        }
        function getSpreadArgumentIndex(args) {
            return ts.findIndex(args, isSpreadArgument);
        }
        function acceptsVoid(t) {
            return !!(t.flags & 16384 /* Void */);
        }
        function hasCorrectArity(node, args, signature, signatureHelpTrailingComma) {
            if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
            var argCount;
            var callIsIncomplete = false; // In incomplete call we want to be lenient when we have too few arguments
            var effectiveParameterCount = getParameterCount(signature);
            var effectiveMinimumArguments = getMinArgumentCount(signature);
            if (node.kind === 198 /* TaggedTemplateExpression */) {
                argCount = args.length;
                if (node.template.kind === 211 /* TemplateExpression */) {
                    // If a tagged template expression lacks a tail literal, the call is incomplete.
                    // Specifically, a template only can end in a TemplateTail or a Missing literal.
                    var lastSpan = ts.last(node.template.templateSpans); // we should always have at least one span.
                    callIsIncomplete = ts.nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated;
                }
                else {
                    // If the template didn't end in a backtick, or its beginning occurred right prior to EOF,
                    // then this might actually turn out to be a TemplateHead in the future;
                    // so we consider the call to be incomplete.
                    var templateLiteral = node.template;
                    ts.Debug.assert(templateLiteral.kind === 14 /* NoSubstitutionTemplateLiteral */);
                    callIsIncomplete = !!templateLiteral.isUnterminated;
                }
            }
            else if (node.kind === 157 /* Decorator */) {
                argCount = getDecoratorArgumentCount(node, signature);
            }
            else if (ts.isJsxOpeningLikeElement(node)) {
                callIsIncomplete = node.attributes.end === node.end;
                if (callIsIncomplete) {
                    return true;
                }
                argCount = effectiveMinimumArguments === 0 ? args.length : 1;
                effectiveParameterCount = args.length === 0 ? effectiveParameterCount : 1; // class may have argumentless ctor functions - still resolve ctor and compare vs props member type
                effectiveMinimumArguments = Math.min(effectiveMinimumArguments, 1); // sfc may specify context argument - handled by framework and not typechecked
            }
            else {
                if (!node.arguments) {
                    // This only happens when we have something of the form: 'new C'
                    ts.Debug.assert(node.kind === 197 /* NewExpression */);
                    return getMinArgumentCount(signature) === 0;
                }
                argCount = signatureHelpTrailingComma ? args.length + 1 : args.length;
                // If we are missing the close parenthesis, the call is incomplete.
                callIsIncomplete = node.arguments.end === node.end;
                // If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range.
                var spreadArgIndex = getSpreadArgumentIndex(args);
                if (spreadArgIndex >= 0) {
                    return spreadArgIndex >= getMinArgumentCount(signature) && (hasEffectiveRestParameter(signature) || spreadArgIndex < getParameterCount(signature));
                }
            }
            // Too many arguments implies incorrect arity.
            if (!hasEffectiveRestParameter(signature) && argCount > effectiveParameterCount) {
                return false;
            }
            // If the call is incomplete, we should skip the lower bound check.
            // JSX signatures can have extra parameters provided by the library which we don't check
            if (callIsIncomplete || argCount >= effectiveMinimumArguments) {
                return true;
            }
            for (var i = argCount; i < effectiveMinimumArguments; i++) {
                var type = getTypeAtPosition(signature, i);
                if (filterType(type, acceptsVoid).flags & 131072 /* Never */) {
                    return false;
                }
            }
            return true;
        }
        function hasCorrectTypeArgumentArity(signature, typeArguments) {
            // If the user supplied type arguments, but the number of type arguments does not match
            // the declared number of type parameters, the call has an incorrect arity.
            var numTypeParameters = ts.length(signature.typeParameters);
            var minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters);
            return !ts.some(typeArguments) ||
                (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters);
        }
        // If type has a single call signature and no other members, return that signature. Otherwise, return undefined.
        function getSingleCallSignature(type) {
            return getSingleSignature(type, 0 /* Call */, /*allowMembers*/ false);
        }
        function getSingleCallOrConstructSignature(type) {
            return getSingleSignature(type, 0 /* Call */, /*allowMembers*/ false) ||
                getSingleSignature(type, 1 /* Construct */, /*allowMembers*/ false);
        }
        function getSingleSignature(type, kind, allowMembers) {
            if (type.flags & 524288 /* Object */) {
                var resolved = resolveStructuredTypeMembers(type);
                if (allowMembers || resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
                    if (kind === 0 /* Call */ && resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0) {
                        return resolved.callSignatures[0];
                    }
                    if (kind === 1 /* Construct */ && resolved.constructSignatures.length === 1 && resolved.callSignatures.length === 0) {
                        return resolved.constructSignatures[0];
                    }
                }
            }
            return undefined;
        }
        // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
        function instantiateSignatureInContextOf(signature, contextualSignature, inferenceContext, compareTypes) {
            var context = createInferenceContext(signature.typeParameters, signature, 0 /* None */, compareTypes);
            // We clone the inferenceContext to avoid fixing. For example, when the source signature is <T>(x: T) => T[] and
            // the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any')
            // for T but leave it possible to later infer '[any]' back to A.
            var restType = getEffectiveRestType(contextualSignature);
            var mapper = inferenceContext && (restType && restType.flags & 262144 /* TypeParameter */ ? inferenceContext.nonFixingMapper : inferenceContext.mapper);
            var sourceSignature = mapper ? instantiateSignature(contextualSignature, mapper) : contextualSignature;
            applyToParameterTypes(sourceSignature, signature, function (source, target) {
                // Type parameters from outer context referenced by source type are fixed by instantiation of the source type
                inferTypes(context.inferences, source, target);
            });
            if (!inferenceContext) {
                applyToReturnTypes(contextualSignature, signature, function (source, target) {
                    inferTypes(context.inferences, source, target, 32 /* ReturnType */);
                });
            }
            return getSignatureInstantiation(signature, getInferredTypes(context), ts.isInJSFile(contextualSignature.declaration));
        }
        function inferJsxTypeArguments(node, signature, checkMode, context) {
            var paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
            var checkAttrType = checkExpressionWithContextualType(node.attributes, paramType, context, checkMode);
            inferTypes(context.inferences, checkAttrType, paramType);
            return getInferredTypes(context);
        }
        function inferTypeArguments(node, signature, args, checkMode, context) {
            if (ts.isJsxOpeningLikeElement(node)) {
                return inferJsxTypeArguments(node, signature, checkMode, context);
            }
            // If a contextual type is available, infer from that type to the return type of the call expression. For
            // example, given a 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
            // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
            // return type of 'wrap'.
            if (node.kind !== 157 /* Decorator */) {
                var contextualType = getContextualType(node);
                if (contextualType) {
                    // We clone the inference context to avoid disturbing a resolution in progress for an
                    // outer call expression. Effectively we just want a snapshot of whatever has been
                    // inferred for any outer call expression so far.
                    var outerContext = getInferenceContext(node);
                    var outerMapper = getMapperFromContext(cloneInferenceContext(outerContext, 1 /* NoDefault */));
                    var instantiatedType = instantiateType(contextualType, outerMapper);
                    // If the contextual type is a generic function type with a single call signature, we
                    // instantiate the type with its own type parameters and type arguments. This ensures that
                    // the type parameters are not erased to type any during type inference such that they can
                    // be inferred as actual types from the contextual type. For example:
                    //   declare function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[];
                    //   const boxElements: <A>(a: A[]) => { value: A }[] = arrayMap(value => ({ value }));
                    // Above, the type of the 'value' parameter is inferred to be 'A'.
                    var contextualSignature = getSingleCallSignature(instantiatedType);
                    var inferenceSourceType = contextualSignature && contextualSignature.typeParameters ?
                        getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) :
                        instantiatedType;
                    var inferenceTargetType = getReturnTypeOfSignature(signature);
                    // Inferences made from return types have lower priority than all other inferences.
                    inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, 32 /* ReturnType */);
                    // Create a type mapper for instantiating generic contextual types using the inferences made
                    // from the return type. We need a separate inference pass here because (a) instantiation of
                    // the source type uses the outer context's return mapper (which excludes inferences made from
                    // outer arguments), and (b) we don't want any further inferences going into this context.
                    var returnContext = createInferenceContext(signature.typeParameters, signature, context.flags);
                    var returnSourceType = instantiateType(contextualType, outerContext && outerContext.returnMapper);
                    inferTypes(returnContext.inferences, returnSourceType, inferenceTargetType);
                    context.returnMapper = ts.some(returnContext.inferences, hasInferenceCandidates) ? getMapperFromContext(cloneInferredPartOfContext(returnContext)) : undefined;
                }
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType) {
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
                inferTypes(context.inferences, thisArgumentType, thisType);
            }
            var restType = getNonArrayRestType(signature);
            var argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
            for (var i = 0; i < argCount; i++) {
                var arg = args[i];
                if (arg.kind !== 215 /* OmittedExpression */) {
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = checkExpressionWithContextualType(arg, paramType, context, checkMode);
                    inferTypes(context.inferences, argType, paramType);
                }
            }
            if (restType) {
                var spreadType = getSpreadArgumentType(args, argCount, args.length, restType, context);
                inferTypes(context.inferences, spreadType, restType);
            }
            return getInferredTypes(context);
        }
        function getArrayifiedType(type) {
            return type.flags & 1048576 /* Union */ ? mapType(type, getArrayifiedType) :
                type.flags & (1 /* Any */ | 63176704 /* Instantiable */) || isMutableArrayOrTuple(type) ? type :
                    isTupleType(type) ? createTupleType(getTypeArguments(type), type.target.minLength, type.target.hasRestElement, /*readonly*/ false, type.target.associatedNames) :
                        createArrayType(getIndexedAccessType(type, numberType));
        }
        function getSpreadArgumentType(args, index, argCount, restType, context) {
            if (index >= argCount - 1) {
                var arg = args[argCount - 1];
                if (isSpreadArgument(arg)) {
                    // We are inferring from a spread expression in the last argument position, i.e. both the parameter
                    // and the argument are ...x forms.
                    return arg.kind === 220 /* SyntheticExpression */ ?
                        createArrayType(arg.type) :
                        getArrayifiedType(checkExpressionWithContextualType(arg.expression, restType, context, 0 /* Normal */));
                }
            }
            var types = [];
            var spreadIndex = -1;
            for (var i = index; i < argCount; i++) {
                var contextualType = getIndexedAccessType(restType, getLiteralType(i - index));
                var argType = checkExpressionWithContextualType(args[i], contextualType, context, 0 /* Normal */);
                if (spreadIndex < 0 && isSpreadArgument(args[i])) {
                    spreadIndex = i - index;
                }
                var hasPrimitiveContextualType = maybeTypeOfKind(contextualType, 131068 /* Primitive */ | 4194304 /* Index */);
                types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType));
            }
            return spreadIndex < 0 ?
                createTupleType(types) :
                createTupleType(ts.append(types.slice(0, spreadIndex), getUnionType(types.slice(spreadIndex))), spreadIndex, /*hasRestElement*/ true);
        }
        function checkTypeArguments(signature, typeArgumentNodes, reportErrors, headMessage) {
            var isJavascript = ts.isInJSFile(signature.declaration);
            var typeParameters = signature.typeParameters;
            var typeArgumentTypes = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript);
            var mapper;
            for (var i = 0; i < typeArgumentNodes.length; i++) {
                ts.Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments");
                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                if (constraint) {
                    var errorInfo = reportErrors && headMessage ? (function () { return ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1); }) : undefined;
                    var typeArgumentHeadMessage = headMessage || ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1;
                    if (!mapper) {
                        mapper = createTypeMapper(typeParameters, typeArgumentTypes);
                    }
                    var typeArgument = typeArgumentTypes[i];
                    if (!checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), reportErrors ? typeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo)) {
                        return undefined;
                    }
                }
            }
            return typeArgumentTypes;
        }
        function getJsxReferenceKind(node) {
            if (isJsxIntrinsicIdentifier(node.tagName)) {
                return 2 /* Mixed */;
            }
            var tagType = getApparentType(checkExpression(node.tagName));
            if (ts.length(getSignaturesOfType(tagType, 1 /* Construct */))) {
                return 0 /* Component */;
            }
            if (ts.length(getSignaturesOfType(tagType, 0 /* Call */))) {
                return 1 /* Function */;
            }
            return 2 /* Mixed */;
        }
        /**
         * Check if the given signature can possibly be a signature called by the JSX opening-like element.
         * @param node a JSX opening-like element we are trying to figure its call signature
         * @param signature a candidate signature we are trying whether it is a call signature
         * @param relation a relationship to check parameter and argument type
         */
        function checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer) {
            // Stateless function components can have maximum of three arguments: "props", "context", and "updater".
            // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props,
            // can be specified by users through attributes property.
            var paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
            var attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode);
            return checkTagNameDoesNotExpectTooManyArguments() && checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes, 
            /*headMessage*/ undefined, containingMessageChain, errorOutputContainer);
            function checkTagNameDoesNotExpectTooManyArguments() {
                var _a;
                var tagType = ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node) && !isJsxIntrinsicIdentifier(node.tagName) ? checkExpression(node.tagName) : undefined;
                if (!tagType) {
                    return true;
                }
                var tagCallSignatures = getSignaturesOfType(tagType, 0 /* Call */);
                if (!ts.length(tagCallSignatures)) {
                    return true;
                }
                var factory = getJsxFactoryEntity(node);
                if (!factory) {
                    return true;
                }
                var factorySymbol = resolveEntityName(factory, 111551 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, node);
                if (!factorySymbol) {
                    return true;
                }
                var factoryType = getTypeOfSymbol(factorySymbol);
                var callSignatures = getSignaturesOfType(factoryType, 0 /* Call */);
                if (!ts.length(callSignatures)) {
                    return true;
                }
                var hasFirstParamSignatures = false;
                var maxParamCount = 0;
                // Check that _some_ first parameter expects a FC-like thing, and that some overload of the SFC expects an acceptable number of arguments
                for (var _i = 0, callSignatures_1 = callSignatures; _i < callSignatures_1.length; _i++) {
                    var sig = callSignatures_1[_i];
                    var firstparam = getTypeAtPosition(sig, 0);
                    var signaturesOfParam = getSignaturesOfType(firstparam, 0 /* Call */);
                    if (!ts.length(signaturesOfParam))
                        continue;
                    for (var _b = 0, signaturesOfParam_1 = signaturesOfParam; _b < signaturesOfParam_1.length; _b++) {
                        var paramSig = signaturesOfParam_1[_b];
                        hasFirstParamSignatures = true;
                        if (hasEffectiveRestParameter(paramSig)) {
                            return true; // some signature has a rest param, so function components can have an arbitrary number of arguments
                        }
                        var paramCount = getParameterCount(paramSig);
                        if (paramCount > maxParamCount) {
                            maxParamCount = paramCount;
                        }
                    }
                }
                if (!hasFirstParamSignatures) {
                    // Not a single signature had a first parameter which expected a signature - for back compat, and
                    // to guard against generic factories which won't have signatures directly, do not error
                    return true;
                }
                var absoluteMinArgCount = Infinity;
                for (var _c = 0, tagCallSignatures_1 = tagCallSignatures; _c < tagCallSignatures_1.length; _c++) {
                    var tagSig = tagCallSignatures_1[_c];
                    var tagRequiredArgCount = getMinArgumentCount(tagSig);
                    if (tagRequiredArgCount < absoluteMinArgCount) {
                        absoluteMinArgCount = tagRequiredArgCount;
                    }
                }
                if (absoluteMinArgCount <= maxParamCount) {
                    return true; // some signature accepts the number of arguments the function component provides
                }
                if (reportErrors) {
                    var diag = ts.createDiagnosticForNode(node.tagName, ts.Diagnostics.Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3, ts.entityNameToString(node.tagName), absoluteMinArgCount, ts.entityNameToString(factory), maxParamCount);
                    var tagNameDeclaration = (_a = getSymbolAtLocation(node.tagName)) === null || _a === void 0 ? void 0 : _a.valueDeclaration;
                    if (tagNameDeclaration) {
                        ts.addRelatedInfo(diag, ts.createDiagnosticForNode(tagNameDeclaration, ts.Diagnostics._0_is_declared_here, ts.entityNameToString(node.tagName)));
                    }
                    if (errorOutputContainer && errorOutputContainer.skipLogging) {
                        (errorOutputContainer.errors || (errorOutputContainer.errors = [])).push(diag);
                    }
                    if (!errorOutputContainer.skipLogging) {
                        diagnostics.add(diag);
                    }
                }
                return false;
            }
        }
        function getSignatureApplicabilityError(node, args, signature, relation, checkMode, reportErrors, containingMessageChain) {
            var errorOutputContainer = { errors: undefined, skipLogging: true };
            if (ts.isJsxOpeningLikeElement(node)) {
                if (!checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer)) {
                    ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "jsx should have errors when reporting errors");
                    return errorOutputContainer.errors || ts.emptyArray;
                }
                return undefined;
            }
            var thisType = getThisTypeOfSignature(signature);
            if (thisType && thisType !== voidType && node.kind !== 197 /* NewExpression */) {
                // If the called expression is not of the form `x.f` or `x["f"]`, then sourceType = voidType
                // If the signature's 'this' type is voidType, then the check is skipped -- anything is compatible.
                // If the expression is a new expression, then the check is skipped.
                var thisArgumentNode = getThisArgumentOfCall(node);
                var thisArgumentType = void 0;
                if (thisArgumentNode) {
                    thisArgumentType = checkExpression(thisArgumentNode);
                    if (ts.isOptionalChainRoot(thisArgumentNode.parent)) {
                        thisArgumentType = getNonNullableType(thisArgumentType);
                    }
                    else if (ts.isOptionalChain(thisArgumentNode.parent)) {
                        thisArgumentType = removeOptionalTypeMarker(thisArgumentType);
                    }
                }
                else {
                    thisArgumentType = voidType;
                }
                var errorNode = reportErrors ? (thisArgumentNode || node) : undefined;
                var headMessage_1 = ts.Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1;
                if (!checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage_1, containingMessageChain, errorOutputContainer)) {
                    ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "this parameter should have errors when reporting errors");
                    return errorOutputContainer.errors || ts.emptyArray;
                }
            }
            var headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
            var restType = getNonArrayRestType(signature);
            var argCount = restType ? Math.min(getParameterCount(signature) - 1, args.length) : args.length;
            for (var i = 0; i < argCount; i++) {
                var arg = args[i];
                if (arg.kind !== 215 /* OmittedExpression */) {
                    var paramType = getTypeAtPosition(signature, i);
                    var argType = checkExpressionWithContextualType(arg, paramType, /*inferenceContext*/ undefined, checkMode);
                    // If one or more arguments are still excluded (as indicated by CheckMode.SkipContextSensitive),
                    // we obtain the regular type of any object literal arguments because we may not have inferred complete
                    // parameter types yet and therefore excess property checks may yield false positives (see #17041).
                    var checkArgType = checkMode & 4 /* SkipContextSensitive */ ? getRegularTypeOfObjectLiteral(argType) : argType;
                    if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain, errorOutputContainer)) {
                        ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "parameter should have errors when reporting errors");
                        maybeAddMissingAwaitInfo(arg, checkArgType, paramType);
                        return errorOutputContainer.errors || ts.emptyArray;
                    }
                }
            }
            if (restType) {
                var spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined);
                var errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined;
                if (!checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, /*containingMessageChain*/ undefined, errorOutputContainer)) {
                    ts.Debug.assert(!reportErrors || !!errorOutputContainer.errors, "rest parameter should have errors when reporting errors");
                    maybeAddMissingAwaitInfo(errorNode, spreadType, restType);
                    return errorOutputContainer.errors || ts.emptyArray;
                }
            }
            return undefined;
            function maybeAddMissingAwaitInfo(errorNode, source, target) {
                if (errorNode && reportErrors && errorOutputContainer.errors && errorOutputContainer.errors.length) {
                    // Bail if target is Promise-like---something else is wrong
                    if (getAwaitedTypeOfPromise(target)) {
                        return;
                    }
                    var awaitedTypeOfSource = getAwaitedTypeOfPromise(source);
                    if (awaitedTypeOfSource && isTypeRelatedTo(awaitedTypeOfSource, target, relation)) {
                        ts.addRelatedInfo(errorOutputContainer.errors[0], ts.createDiagnosticForNode(errorNode, ts.Diagnostics.Did_you_forget_to_use_await));
                    }
                }
            }
        }
        /**
         * Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise.
         */
        function getThisArgumentOfCall(node) {
            if (node.kind === 196 /* CallExpression */) {
                var callee = ts.skipOuterExpressions(node.expression);
                if (ts.isAccessExpression(callee)) {
                    return callee.expression;
                }
            }
        }
        function createSyntheticExpression(parent, type, isSpread) {
            var result = ts.createNode(220 /* SyntheticExpression */, parent.pos, parent.end);
            result.parent = parent;
            result.type = type;
            result.isSpread = isSpread || false;
            return result;
        }
        /**
         * Returns the effective arguments for an expression that works like a function invocation.
         */
        function getEffectiveCallArguments(node) {
            if (node.kind === 198 /* TaggedTemplateExpression */) {
                var template = node.template;
                var args_3 = [createSyntheticExpression(template, getGlobalTemplateStringsArrayType())];
                if (template.kind === 211 /* TemplateExpression */) {
                    ts.forEach(template.templateSpans, function (span) {
                        args_3.push(span.expression);
                    });
                }
                return args_3;
            }
            if (node.kind === 157 /* Decorator */) {
                return getEffectiveDecoratorArguments(node);
            }
            if (ts.isJsxOpeningLikeElement(node)) {
                return node.attributes.properties.length > 0 || (ts.isJsxOpeningElement(node) && node.parent.children.length > 0) ? [node.attributes] : ts.emptyArray;
            }
            var args = node.arguments || ts.emptyArray;
            var length = args.length;
            if (length && isSpreadArgument(args[length - 1]) && getSpreadArgumentIndex(args) === length - 1) {
                // We have a spread argument in the last position and no other spread arguments. If the type
                // of the argument is a tuple type, spread the tuple elements into the argument list. We can
                // call checkExpressionCached because spread expressions never have a contextual type.
                var spreadArgument_1 = args[length - 1];
                var type = flowLoopCount ? checkExpression(spreadArgument_1.expression) : checkExpressionCached(spreadArgument_1.expression);
                if (isTupleType(type)) {
                    var typeArguments = getTypeArguments(type);
                    var restIndex_2 = type.target.hasRestElement ? typeArguments.length - 1 : -1;
                    var syntheticArgs = ts.map(typeArguments, function (t, i) { return createSyntheticExpression(spreadArgument_1, t, /*isSpread*/ i === restIndex_2); });
                    return ts.concatenate(args.slice(0, length - 1), syntheticArgs);
                }
            }
            return args;
        }
        /**
         * Returns the synthetic argument list for a decorator invocation.
         */
        function getEffectiveDecoratorArguments(node) {
            var parent = node.parent;
            var expr = node.expression;
            switch (parent.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    // For a class decorator, the `target` is the type of the class (e.g. the
                    // "static" or "constructor" side of the class).
                    return [
                        createSyntheticExpression(expr, getTypeOfSymbol(getSymbolOfNode(parent)))
                    ];
                case 156 /* Parameter */:
                    // A parameter declaration decorator will have three arguments (see
                    // `ParameterDecorator` in core.d.ts).
                    var func = parent.parent;
                    return [
                        createSyntheticExpression(expr, parent.parent.kind === 162 /* Constructor */ ? getTypeOfSymbol(getSymbolOfNode(func)) : errorType),
                        createSyntheticExpression(expr, anyType),
                        createSyntheticExpression(expr, numberType)
                    ];
                case 159 /* PropertyDeclaration */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    // A method or accessor declaration decorator will have two or three arguments (see
                    // `PropertyDecorator` and `MethodDecorator` in core.d.ts). If we are emitting decorators
                    // for ES3, we will only pass two arguments.
                    var hasPropDesc = parent.kind !== 159 /* PropertyDeclaration */ && languageVersion !== 0 /* ES3 */;
                    return [
                        createSyntheticExpression(expr, getParentTypeOfClassElement(parent)),
                        createSyntheticExpression(expr, getClassElementPropertyKeyType(parent)),
                        createSyntheticExpression(expr, hasPropDesc ? createTypedPropertyDescriptorType(getTypeOfNode(parent)) : anyType)
                    ];
            }
            return ts.Debug.fail();
        }
        /**
         * Returns the argument count for a decorator node that works like a function invocation.
         */
        function getDecoratorArgumentCount(node, signature) {
            switch (node.parent.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return 1;
                case 159 /* PropertyDeclaration */:
                    return 2;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    // For ES3 or decorators with only two parameters we supply only two arguments
                    return languageVersion === 0 /* ES3 */ || signature.parameters.length <= 2 ? 2 : 3;
                case 156 /* Parameter */:
                    return 3;
                default:
                    return ts.Debug.fail();
            }
        }
        function getDiagnosticSpanForCallNode(node, doNotIncludeArguments) {
            var start;
            var length;
            var sourceFile = ts.getSourceFileOfNode(node);
            if (ts.isPropertyAccessExpression(node.expression)) {
                var nameSpan = ts.getErrorSpanForNode(sourceFile, node.expression.name);
                start = nameSpan.start;
                length = doNotIncludeArguments ? nameSpan.length : node.end - start;
            }
            else {
                var expressionSpan = ts.getErrorSpanForNode(sourceFile, node.expression);
                start = expressionSpan.start;
                length = doNotIncludeArguments ? expressionSpan.length : node.end - start;
            }
            return { start: start, length: length, sourceFile: sourceFile };
        }
        function getDiagnosticForCallNode(node, message, arg0, arg1, arg2, arg3) {
            if (ts.isCallExpression(node)) {
                var _a = getDiagnosticSpanForCallNode(node), sourceFile = _a.sourceFile, start = _a.start, length_5 = _a.length;
                return ts.createFileDiagnostic(sourceFile, start, length_5, message, arg0, arg1, arg2, arg3);
            }
            else {
                return ts.createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3);
            }
        }
        function getArgumentArityError(node, signatures, args) {
            var min = Number.POSITIVE_INFINITY;
            var max = Number.NEGATIVE_INFINITY;
            var belowArgCount = Number.NEGATIVE_INFINITY;
            var aboveArgCount = Number.POSITIVE_INFINITY;
            var argCount = args.length;
            var closestSignature;
            for (var _i = 0, signatures_8 = signatures; _i < signatures_8.length; _i++) {
                var sig = signatures_8[_i];
                var minCount = getMinArgumentCount(sig);
                var maxCount = getParameterCount(sig);
                if (minCount < argCount && minCount > belowArgCount)
                    belowArgCount = minCount;
                if (argCount < maxCount && maxCount < aboveArgCount)
                    aboveArgCount = maxCount;
                if (minCount < min) {
                    min = minCount;
                    closestSignature = sig;
                }
                max = Math.max(max, maxCount);
            }
            var hasRestParameter = ts.some(signatures, hasEffectiveRestParameter);
            var paramRange = hasRestParameter ? min :
                min < max ? min + "-" + max :
                    min;
            var hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
            if (argCount <= max && hasSpreadArgument) {
                argCount--;
            }
            var spanArray;
            var related;
            var error = hasRestParameter || hasSpreadArgument ? hasRestParameter && hasSpreadArgument ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
                hasRestParameter ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1 :
                    ts.Diagnostics.Expected_0_arguments_but_got_1_or_more : ts.Diagnostics.Expected_0_arguments_but_got_1;
            if (closestSignature && getMinArgumentCount(closestSignature) > argCount && closestSignature.declaration) {
                var paramDecl = closestSignature.declaration.parameters[closestSignature.thisParameter ? argCount + 1 : argCount];
                if (paramDecl) {
                    related = ts.createDiagnosticForNode(paramDecl, ts.isBindingPattern(paramDecl.name) ? ts.Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided : ts.Diagnostics.An_argument_for_0_was_not_provided, !paramDecl.name ? argCount : !ts.isBindingPattern(paramDecl.name) ? ts.idText(ts.getFirstIdentifier(paramDecl.name)) : undefined);
                }
            }
            if (min < argCount && argCount < max) {
                return getDiagnosticForCallNode(node, ts.Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, argCount, belowArgCount, aboveArgCount);
            }
            if (!hasSpreadArgument && argCount < min) {
                var diagnostic_1 = getDiagnosticForCallNode(node, error, paramRange, argCount);
                return related ? ts.addRelatedInfo(diagnostic_1, related) : diagnostic_1;
            }
            if (hasRestParameter || hasSpreadArgument) {
                spanArray = ts.createNodeArray(args);
                if (hasSpreadArgument && argCount) {
                    var nextArg = ts.elementAt(args, getSpreadArgumentIndex(args) + 1) || undefined;
                    spanArray = ts.createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : Math.min(max, args.length - 1)));
                }
            }
            else {
                spanArray = ts.createNodeArray(args.slice(max));
            }
            spanArray.pos = ts.first(spanArray).pos;
            spanArray.end = ts.last(spanArray).end;
            if (spanArray.end === spanArray.pos) {
                spanArray.end++;
            }
            var diagnostic = ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), spanArray, error, paramRange, argCount);
            return related ? ts.addRelatedInfo(diagnostic, related) : diagnostic;
        }
        function getTypeArgumentArityError(node, signatures, typeArguments) {
            var argCount = typeArguments.length;
            // No overloads exist
            if (signatures.length === 1) {
                var sig = signatures[0];
                var min_1 = getMinTypeArgumentCount(sig.typeParameters);
                var max = ts.length(sig.typeParameters);
                return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Expected_0_type_arguments_but_got_1, min_1 < max ? min_1 + "-" + max : min_1, argCount);
            }
            // Overloads exist
            var belowArgCount = -Infinity;
            var aboveArgCount = Infinity;
            for (var _i = 0, signatures_9 = signatures; _i < signatures_9.length; _i++) {
                var sig = signatures_9[_i];
                var min_2 = getMinTypeArgumentCount(sig.typeParameters);
                var max = ts.length(sig.typeParameters);
                if (min_2 > argCount) {
                    aboveArgCount = Math.min(aboveArgCount, min_2);
                }
                else if (max < argCount) {
                    belowArgCount = Math.max(belowArgCount, max);
                }
            }
            if (belowArgCount !== -Infinity && aboveArgCount !== Infinity) {
                return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments, argCount, belowArgCount, aboveArgCount);
            }
            return ts.createDiagnosticForNodeArray(ts.getSourceFileOfNode(node), typeArguments, ts.Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
        }
        function resolveCall(node, signatures, candidatesOutArray, checkMode, callChainFlags, fallbackError) {
            var isTaggedTemplate = node.kind === 198 /* TaggedTemplateExpression */;
            var isDecorator = node.kind === 157 /* Decorator */;
            var isJsxOpeningOrSelfClosingElement = ts.isJsxOpeningLikeElement(node);
            var reportErrors = !candidatesOutArray;
            var typeArguments;
            if (!isDecorator) {
                typeArguments = node.typeArguments;
                // We already perform checking on the type arguments on the class declaration itself.
                if (isTaggedTemplate || isJsxOpeningOrSelfClosingElement || node.expression.kind !== 102 /* SuperKeyword */) {
                    ts.forEach(typeArguments, checkSourceElement);
                }
            }
            var candidates = candidatesOutArray || [];
            // reorderCandidates fills up the candidates array directly
            reorderCandidates(signatures, candidates, callChainFlags);
            if (!candidates.length) {
                if (reportErrors) {
                    diagnostics.add(getDiagnosticForCallNode(node, ts.Diagnostics.Call_target_does_not_contain_any_signatures));
                }
                return resolveErrorCall(node);
            }
            var args = getEffectiveCallArguments(node);
            // The excludeArgument array contains true for each context sensitive argument (an argument
            // is context sensitive it is susceptible to a one-time permanent contextual typing).
            //
            // The idea is that we will perform type argument inference & assignability checking once
            // without using the susceptible parameters that are functions, and once more for those
            // parameters, contextually typing each as we go along.
            //
            // For a tagged template, then the first argument be 'undefined' if necessary because it
            // represents a TemplateStringsArray.
            //
            // For a decorator, no arguments are susceptible to contextual typing due to the fact
            // decorators are applied to a declaration by the emitter, and not to an expression.
            var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
            var argCheckMode = !isDecorator && !isSingleNonGenericCandidate && ts.some(args, isContextSensitive) ? 4 /* SkipContextSensitive */ : 0 /* Normal */;
            // The following variables are captured and modified by calls to chooseOverload.
            // If overload resolution or type argument inference fails, we want to report the
            // best error possible. The best error is one which says that an argument was not
            // assignable to a parameter. This implies that everything else about the overload
            // was fine. So if there is any overload that is only incorrect because of an
            // argument, we will report an error on that one.
            //
            //     function foo(s: string): void;
            //     function foo(n: number): void; // Report argument error on this overload
            //     function foo(): void;
            //     foo(true);
            //
            // If none of the overloads even made it that far, there are two possibilities.
            // There was a problem with type arguments for some overload, in which case
            // report an error on that. Or none of the overloads even had correct arity,
            // in which case give an arity error.
            //
            //     function foo<T extends string>(x: T): void; // Report type argument error
            //     function foo(): void;
            //     foo<number>(0);
            //
            var candidatesForArgumentError;
            var candidateForArgumentArityError;
            var candidateForTypeArgumentError;
            var result;
            // If we are in signature help, a trailing comma indicates that we intend to provide another argument,
            // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
            var signatureHelpTrailingComma = !!(checkMode & 16 /* IsForSignatureHelp */) && node.kind === 196 /* CallExpression */ && node.arguments.hasTrailingComma;
            // Section 4.12.1:
            // if the candidate list contains one or more signatures for which the type of each argument
            // expression is a subtype of each corresponding parameter type, the return type of the first
            // of those signatures becomes the return type of the function call.
            // Otherwise, the return type of the first signature in the candidate list becomes the return
            // type of the function call.
            //
            // Whether the call is an error is determined by assignability of the arguments. The subtype pass
            // is just important for choosing the best signature. So in the case where there is only one
            // signature, the subtype pass is useless. So skipping it is an optimization.
            if (candidates.length > 1) {
                result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma);
            }
            if (!result) {
                result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma);
            }
            if (result) {
                return result;
            }
            // No signatures were applicable. Now report errors based on the last applicable signature with
            // no arguments excluded from assignability checks.
            // If candidate is undefined, it means that no candidates had a suitable arity. In that case,
            // skip the checkApplicableSignature check.
            if (reportErrors) {
                if (candidatesForArgumentError) {
                    if (candidatesForArgumentError.length === 1 || candidatesForArgumentError.length > 3) {
                        var last_2 = candidatesForArgumentError[candidatesForArgumentError.length - 1];
                        var chain_1;
                        if (candidatesForArgumentError.length > 3) {
                            chain_1 = ts.chainDiagnosticMessages(chain_1, ts.Diagnostics.The_last_overload_gave_the_following_error);
                            chain_1 = ts.chainDiagnosticMessages(chain_1, ts.Diagnostics.No_overload_matches_this_call);
                        }
                        var diags = getSignatureApplicabilityError(node, args, last_2, assignableRelation, 0 /* Normal */, /*reportErrors*/ true, function () { return chain_1; });
                        if (diags) {
                            for (var _i = 0, diags_1 = diags; _i < diags_1.length; _i++) {
                                var d = diags_1[_i];
                                if (last_2.declaration && candidatesForArgumentError.length > 3) {
                                    ts.addRelatedInfo(d, ts.createDiagnosticForNode(last_2.declaration, ts.Diagnostics.The_last_overload_is_declared_here));
                                }
                                diagnostics.add(d);
                            }
                        }
                        else {
                            ts.Debug.fail("No error for last overload signature");
                        }
                    }
                    else {
                        var allDiagnostics = [];
                        var max = 0;
                        var min_3 = Number.MAX_VALUE;
                        var minIndex = 0;
                        var i_1 = 0;
                        var _loop_17 = function (c) {
                            var chain_2 = function () { return ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Overload_0_of_1_2_gave_the_following_error, i_1 + 1, candidates.length, signatureToString(c)); };
                            var diags_2 = getSignatureApplicabilityError(node, args, c, assignableRelation, 0 /* Normal */, /*reportErrors*/ true, chain_2);
                            if (diags_2) {
                                if (diags_2.length <= min_3) {
                                    min_3 = diags_2.length;
                                    minIndex = i_1;
                                }
                                max = Math.max(max, diags_2.length);
                                allDiagnostics.push(diags_2);
                            }
                            else {
                                ts.Debug.fail("No error for 3 or fewer overload signatures");
                            }
                            i_1++;
                        };
                        for (var _a = 0, candidatesForArgumentError_1 = candidatesForArgumentError; _a < candidatesForArgumentError_1.length; _a++) {
                            var c = candidatesForArgumentError_1[_a];
                            _loop_17(c);
                        }
                        var diags_3 = max > 1 ? allDiagnostics[minIndex] : ts.flatten(allDiagnostics);
                        ts.Debug.assert(diags_3.length > 0, "No errors reported for 3 or fewer overload signatures");
                        var chain = ts.chainDiagnosticMessages(ts.map(diags_3, function (d) { return typeof d.messageText === "string" ? d : d.messageText; }), ts.Diagnostics.No_overload_matches_this_call);
                        var related = ts.flatMap(diags_3, function (d) { return d.relatedInformation; });
                        if (ts.every(diags_3, function (d) { return d.start === diags_3[0].start && d.length === diags_3[0].length && d.file === diags_3[0].file; })) {
                            var _b = diags_3[0], file = _b.file, start = _b.start, length_6 = _b.length;
                            diagnostics.add({ file: file, start: start, length: length_6, code: chain.code, category: chain.category, messageText: chain, relatedInformation: related });
                        }
                        else {
                            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(node, chain, related));
                        }
                    }
                }
                else if (candidateForArgumentArityError) {
                    diagnostics.add(getArgumentArityError(node, [candidateForArgumentArityError], args));
                }
                else if (candidateForTypeArgumentError) {
                    checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, /*reportErrors*/ true, fallbackError);
                }
                else {
                    var signaturesWithCorrectTypeArgumentArity = ts.filter(signatures, function (s) { return hasCorrectTypeArgumentArity(s, typeArguments); });
                    if (signaturesWithCorrectTypeArgumentArity.length === 0) {
                        diagnostics.add(getTypeArgumentArityError(node, signatures, typeArguments));
                    }
                    else if (!isDecorator) {
                        diagnostics.add(getArgumentArityError(node, signaturesWithCorrectTypeArgumentArity, args));
                    }
                    else if (fallbackError) {
                        diagnostics.add(getDiagnosticForCallNode(node, fallbackError));
                    }
                }
            }
            return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray);
            function chooseOverload(candidates, relation, signatureHelpTrailingComma) {
                if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; }
                candidatesForArgumentError = undefined;
                candidateForArgumentArityError = undefined;
                candidateForTypeArgumentError = undefined;
                if (isSingleNonGenericCandidate) {
                    var candidate = candidates[0];
                    if (ts.some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                        return undefined;
                    }
                    if (getSignatureApplicabilityError(node, args, candidate, relation, 0 /* Normal */, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                        candidatesForArgumentError = [candidate];
                        return undefined;
                    }
                    return candidate;
                }
                for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
                    var candidate = candidates[candidateIndex];
                    if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                        continue;
                    }
                    var checkCandidate = void 0;
                    var inferenceContext = void 0;
                    if (candidate.typeParameters) {
                        var typeArgumentTypes = void 0;
                        if (ts.some(typeArguments)) {
                            typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
                            if (!typeArgumentTypes) {
                                candidateForTypeArgumentError = candidate;
                                continue;
                            }
                        }
                        else {
                            inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ ts.isInJSFile(node) ? 2 /* AnyDefault */ : 0 /* None */);
                            typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | 8 /* SkipGenericFunctions */, inferenceContext);
                            argCheckMode |= inferenceContext.flags & 4 /* SkippedGenericFunction */ ? 8 /* SkipGenericFunctions */ : 0 /* Normal */;
                        }
                        checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, ts.isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
                        // If the original signature has a generic rest type, instantiation may produce a
                        // signature with different arity and we need to perform another arity check.
                        if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
                            candidateForArgumentArityError = checkCandidate;
                            continue;
                        }
                    }
                    else {
                        checkCandidate = candidate;
                    }
                    if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                        // Give preference to error candidates that have no rest parameters (as they are more specific)
                        (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
                        continue;
                    }
                    if (argCheckMode) {
                        // If one or more context sensitive arguments were excluded, we start including
                        // them now (and keeping do so for any subsequent candidates) and perform a second
                        // round of type inference and applicability checking for this particular candidate.
                        argCheckMode = 0 /* Normal */;
                        if (inferenceContext) {
                            var typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
                            checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, ts.isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
                            // If the original signature has a generic rest type, instantiation may produce a
                            // signature with different arity and we need to perform another arity check.
                            if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) {
                                candidateForArgumentArityError = checkCandidate;
                                continue;
                            }
                        }
                        if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
                            // Give preference to error candidates that have no rest parameters (as they are more specific)
                            (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
                            continue;
                        }
                    }
                    candidates[candidateIndex] = checkCandidate;
                    return checkCandidate;
                }
                return undefined;
            }
        }
        // No signature was applicable. We have already reported the errors for the invalid signature.
        function getCandidateForOverloadFailure(node, candidates, args, hasCandidatesOutArray) {
            ts.Debug.assert(candidates.length > 0); // Else should not have called this.
            checkNodeDeferred(node);
            // Normally we will combine overloads. Skip this if they have type parameters since that's hard to combine.
            // Don't do this if there is a `candidatesOutArray`,
            // because then we want the chosen best candidate to be one of the overloads, not a combination.
            return hasCandidatesOutArray || candidates.length === 1 || candidates.some(function (c) { return !!c.typeParameters; })
                ? pickLongestCandidateSignature(node, candidates, args)
                : createUnionOfSignaturesForOverloadFailure(candidates);
        }
        function createUnionOfSignaturesForOverloadFailure(candidates) {
            var thisParameters = ts.mapDefined(candidates, function (c) { return c.thisParameter; });
            var thisParameter;
            if (thisParameters.length) {
                thisParameter = createCombinedSymbolFromTypes(thisParameters, thisParameters.map(getTypeOfParameter));
            }
            var _a = ts.minAndMax(candidates, getNumNonRestParameters), minArgumentCount = _a.min, maxNonRestParam = _a.max;
            var parameters = [];
            var _loop_18 = function (i) {
                var symbols = ts.mapDefined(candidates, function (s) { return signatureHasRestParameter(s) ?
                    i < s.parameters.length - 1 ? s.parameters[i] : ts.last(s.parameters) :
                    i < s.parameters.length ? s.parameters[i] : undefined; });
                ts.Debug.assert(symbols.length !== 0);
                parameters.push(createCombinedSymbolFromTypes(symbols, ts.mapDefined(candidates, function (candidate) { return tryGetTypeAtPosition(candidate, i); })));
            };
            for (var i = 0; i < maxNonRestParam; i++) {
                _loop_18(i);
            }
            var restParameterSymbols = ts.mapDefined(candidates, function (c) { return signatureHasRestParameter(c) ? ts.last(c.parameters) : undefined; });
            var flags = 0 /* None */;
            if (restParameterSymbols.length !== 0) {
                var type = createArrayType(getUnionType(ts.mapDefined(candidates, tryGetRestTypeOfSignature), 2 /* Subtype */));
                parameters.push(createCombinedSymbolForOverloadFailure(restParameterSymbols, type));
                flags |= 1 /* HasRestParameter */;
            }
            if (candidates.some(signatureHasLiteralTypes)) {
                flags |= 2 /* HasLiteralTypes */;
            }
            return createSignature(candidates[0].declaration, 
            /*typeParameters*/ undefined, // Before calling this we tested for `!candidates.some(c => !!c.typeParameters)`.
            thisParameter, parameters, 
            /*resolvedReturnType*/ getIntersectionType(candidates.map(getReturnTypeOfSignature)), 
            /*typePredicate*/ undefined, minArgumentCount, flags);
        }
        function getNumNonRestParameters(signature) {
            var numParams = signature.parameters.length;
            return signatureHasRestParameter(signature) ? numParams - 1 : numParams;
        }
        function createCombinedSymbolFromTypes(sources, types) {
            return createCombinedSymbolForOverloadFailure(sources, getUnionType(types, 2 /* Subtype */));
        }
        function createCombinedSymbolForOverloadFailure(sources, type) {
            // This function is currently only used for erroneous overloads, so it's good enough to just use the first source.
            return createSymbolWithType(ts.first(sources), type);
        }
        function pickLongestCandidateSignature(node, candidates, args) {
            // Pick the longest signature. This way we can get a contextual type for cases like:
            //     declare function f(a: { xa: number; xb: number; }, b: number);
            //     f({ |
            // Also, use explicitly-supplied type arguments if they are provided, so we can get a contextual signature in cases like:
            //     declare function f<T>(k: keyof T);
            //     f<Foo>("
            var bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === undefined ? args.length : apparentArgumentCount);
            var candidate = candidates[bestIndex];
            var typeParameters = candidate.typeParameters;
            if (!typeParameters) {
                return candidate;
            }
            var typeArgumentNodes = callLikeExpressionMayHaveTypeArguments(node) ? node.typeArguments : undefined;
            var instantiated = typeArgumentNodes
                ? createSignatureInstantiation(candidate, getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, ts.isInJSFile(node)))
                : inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args);
            candidates[bestIndex] = instantiated;
            return instantiated;
        }
        function getTypeArgumentsFromNodes(typeArgumentNodes, typeParameters, isJs) {
            var typeArguments = typeArgumentNodes.map(getTypeOfNode);
            while (typeArguments.length > typeParameters.length) {
                typeArguments.pop();
            }
            while (typeArguments.length < typeParameters.length) {
                typeArguments.push(getConstraintOfTypeParameter(typeParameters[typeArguments.length]) || getDefaultTypeArgumentType(isJs));
            }
            return typeArguments;
        }
        function inferSignatureInstantiationForOverloadFailure(node, typeParameters, candidate, args) {
            var inferenceContext = createInferenceContext(typeParameters, candidate, /*flags*/ ts.isInJSFile(node) ? 2 /* AnyDefault */ : 0 /* None */);
            var typeArgumentTypes = inferTypeArguments(node, candidate, args, 4 /* SkipContextSensitive */ | 8 /* SkipGenericFunctions */, inferenceContext);
            return createSignatureInstantiation(candidate, typeArgumentTypes);
        }
        function getLongestCandidateIndex(candidates, argsCount) {
            var maxParamsIndex = -1;
            var maxParams = -1;
            for (var i = 0; i < candidates.length; i++) {
                var candidate = candidates[i];
                var paramCount = getParameterCount(candidate);
                if (hasEffectiveRestParameter(candidate) || paramCount >= argsCount) {
                    return i;
                }
                if (paramCount > maxParams) {
                    maxParams = paramCount;
                    maxParamsIndex = i;
                }
            }
            return maxParamsIndex;
        }
        function resolveCallExpression(node, candidatesOutArray, checkMode) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                var superType = checkSuperExpression(node.expression);
                if (isTypeAny(superType)) {
                    for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) {
                        var arg = _a[_i];
                        checkExpression(arg); // Still visit arguments so they get marked for visibility, etc
                    }
                    return anySignature;
                }
                if (superType !== errorType) {
                    // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated
                    // with the type arguments specified in the extends clause.
                    var baseTypeNode = ts.getEffectiveBaseTypeNode(ts.getContainingClass(node));
                    if (baseTypeNode) {
                        var baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
                        return resolveCall(node, baseConstructors, candidatesOutArray, checkMode, 0 /* None */);
                    }
                }
                return resolveUntypedCall(node);
            }
            var callChainFlags;
            var funcType = checkExpression(node.expression);
            if (ts.isCallChain(node)) {
                var nonOptionalType = getOptionalExpressionType(funcType, node.expression);
                callChainFlags = nonOptionalType === funcType ? 0 /* None */ :
                    ts.isOutermostOptionalChain(node) ? 8 /* IsOuterCallChain */ :
                        4 /* IsInnerCallChain */;
                funcType = nonOptionalType;
            }
            else {
                callChainFlags = 0 /* None */;
            }
            funcType = checkNonNullTypeWithReporter(funcType, node.expression, reportCannotInvokePossiblyNullOrUndefinedError);
            if (funcType === silentNeverType) {
                return silentNeverSignature;
            }
            var apparentType = getApparentType(funcType);
            if (apparentType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            // Technically, this signatures list may be incomplete. We are taking the apparent type,
            // but we are not including call signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            // TS 1.0 Spec: 4.12
            // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
            // types are provided for the argument expressions, and the result is always of type Any.
            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
                // The unknownType indicates that an error already occurred (and was reported).  No
                // need to report another error in this case.
                if (funcType !== errorType && node.typeArguments) {
                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                }
                return resolveUntypedCall(node);
            }
            // If FuncExpr's apparent type(section 3.8.1) is a function type, the call is a typed function call.
            // TypeScript employs overload resolution in typed function calls in order to support functions
            // with multiple call signatures.
            if (!callSignatures.length) {
                if (numConstructSignatures) {
                    error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
                }
                else {
                    var relatedInformation = void 0;
                    if (node.arguments.length === 1) {
                        var text = ts.getSourceFileOfNode(node).text;
                        if (ts.isLineBreak(text.charCodeAt(ts.skipTrivia(text, node.expression.end, /* stopAfterLineBreak */ true) - 1))) {
                            relatedInformation = ts.createDiagnosticForNode(node.expression, ts.Diagnostics.Are_you_missing_a_semicolon);
                        }
                    }
                    invocationError(node.expression, apparentType, 0 /* Call */, relatedInformation);
                }
                return resolveErrorCall(node);
            }
            // When a call to a generic function is an argument to an outer call to a generic function for which
            // inference is in process, we have a choice to make. If the inner call relies on inferences made from
            // its contextual type to its return type, deferring the inner call processing allows the best possible
            // contextual type to accumulate. But if the outer call relies on inferences made from the return type of
            // the inner call, the inner call should be processed early. There's no sure way to know which choice is
            // right (only a full unification algorithm can determine that), so we resort to the following heuristic:
            // If no type arguments are specified in the inner call and at least one call signature is generic and
            // returns a function type, we choose to defer processing. This narrowly permits function composition
            // operators to flow inferences through return types, but otherwise processes calls right away. We
            // use the resolvingSignature singleton to indicate that we deferred processing. This result will be
            // propagated out and eventually turned into nonInferrableType (a type that is assignable to anything and
            // from which we never make inferences).
            if (checkMode & 8 /* SkipGenericFunctions */ && !node.typeArguments && callSignatures.some(isGenericFunctionReturningFunction)) {
                skippedGenericFunction(node, checkMode);
                return resolvingSignature;
            }
            // If the function is explicitly marked with `@class`, then it must be constructed.
            if (callSignatures.some(function (sig) { return ts.isInJSFile(sig.declaration) && !!ts.getJSDocClassTag(sig.declaration); })) {
                error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode, callChainFlags);
        }
        function isGenericFunctionReturningFunction(signature) {
            return !!(signature.typeParameters && isFunctionType(getReturnTypeOfSignature(signature)));
        }
        /**
         * TS 1.0 spec: 4.12
         * If FuncExpr is of type Any, or of an object type that has no call or construct signatures
         * but is a subtype of the Function interface, the call is an untyped function call.
         */
        function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) {
            // We exclude union types because we may have a union of function types that happen to have no common signatures.
            return isTypeAny(funcType) || isTypeAny(apparentFuncType) && !!(funcType.flags & 262144 /* TypeParameter */) ||
                !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (1048576 /* Union */ | 131072 /* Never */)) && isTypeAssignableTo(funcType, globalFunctionType);
        }
        function resolveNewExpression(node, candidatesOutArray, checkMode) {
            if (node.arguments && languageVersion < 1 /* ES5 */) {
                var spreadIndex = getSpreadArgumentIndex(node.arguments);
                if (spreadIndex >= 0) {
                    error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher);
                }
            }
            var expressionType = checkNonNullExpression(node.expression);
            if (expressionType === silentNeverType) {
                return silentNeverSignature;
            }
            // If expressionType's apparent type(section 3.8.1) is an object type with one or
            // more construct signatures, the expression is processed in the same manner as a
            // function call, but using the construct signatures as the initial set of candidate
            // signatures for overload resolution. The result type of the function call becomes
            // the result type of the operation.
            expressionType = getApparentType(expressionType);
            if (expressionType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            // TS 1.0 spec: 4.11
            // If expressionType is of type Any, Args can be any argument
            // list and the result of the operation is of type Any.
            if (isTypeAny(expressionType)) {
                if (node.typeArguments) {
                    error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments);
                }
                return resolveUntypedCall(node);
            }
            // Technically, this signatures list may be incomplete. We are taking the apparent type,
            // but we are not including construct signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            var constructSignatures = getSignaturesOfType(expressionType, 1 /* Construct */);
            if (constructSignatures.length) {
                if (!isConstructorAccessible(node, constructSignatures[0])) {
                    return resolveErrorCall(node);
                }
                // If the expression is a class of abstract type, then it cannot be instantiated.
                // Note, only class declarations can be declared abstract.
                // In the case of a merged class-module or class-interface declaration,
                // only the class declaration node will have the Abstract flag set.
                var valueDecl = expressionType.symbol && ts.getClassLikeDeclarationOfSymbol(expressionType.symbol);
                if (valueDecl && ts.hasModifier(valueDecl, 128 /* Abstract */)) {
                    error(node, ts.Diagnostics.Cannot_create_an_instance_of_an_abstract_class);
                    return resolveErrorCall(node);
                }
                return resolveCall(node, constructSignatures, candidatesOutArray, checkMode, 0 /* None */);
            }
            // If expressionType's apparent type is an object type with no construct signatures but
            // one or more call signatures, the expression is processed as a function call. A compile-time
            // error occurs if the result of the function call is not Void. The type of the result of the
            // operation is Any. It is an error to have a Void this type.
            var callSignatures = getSignaturesOfType(expressionType, 0 /* Call */);
            if (callSignatures.length) {
                var signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode, 0 /* None */);
                if (!noImplicitAny) {
                    if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
                        error(node, ts.Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
                    }
                    if (getThisTypeOfSignature(signature) === voidType) {
                        error(node, ts.Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void);
                    }
                }
                return signature;
            }
            invocationError(node.expression, expressionType, 1 /* Construct */);
            return resolveErrorCall(node);
        }
        function typeHasProtectedAccessibleBase(target, type) {
            var baseTypes = getBaseTypes(type);
            if (!ts.length(baseTypes)) {
                return false;
            }
            var firstBase = baseTypes[0];
            if (firstBase.flags & 2097152 /* Intersection */) {
                var types = firstBase.types;
                var mixinFlags = findMixins(types);
                var i = 0;
                for (var _i = 0, _a = firstBase.types; _i < _a.length; _i++) {
                    var intersectionMember = _a[_i];
                    // We want to ignore mixin ctors
                    if (!mixinFlags[i]) {
                        if (ts.getObjectFlags(intersectionMember) & (1 /* Class */ | 2 /* Interface */)) {
                            if (intersectionMember.symbol === target) {
                                return true;
                            }
                            if (typeHasProtectedAccessibleBase(target, intersectionMember)) {
                                return true;
                            }
                        }
                    }
                    i++;
                }
                return false;
            }
            if (firstBase.symbol === target) {
                return true;
            }
            return typeHasProtectedAccessibleBase(target, firstBase);
        }
        function isConstructorAccessible(node, signature) {
            if (!signature || !signature.declaration) {
                return true;
            }
            var declaration = signature.declaration;
            var modifiers = ts.getSelectedModifierFlags(declaration, 24 /* NonPublicAccessibilityModifier */);
            // (1) Public constructors and (2) constructor functions are always accessible.
            if (!modifiers || declaration.kind !== 162 /* Constructor */) {
                return true;
            }
            var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(declaration.parent.symbol);
            var declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol);
            // A private or protected constructor can only be instantiated within its own class (or a subclass, for protected)
            if (!isNodeWithinClass(node, declaringClassDeclaration)) {
                var containingClass = ts.getContainingClass(node);
                if (containingClass && modifiers & 16 /* Protected */) {
                    var containingType = getTypeOfNode(containingClass);
                    if (typeHasProtectedAccessibleBase(declaration.parent.symbol, containingType)) {
                        return true;
                    }
                }
                if (modifiers & 8 /* Private */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                if (modifiers & 16 /* Protected */) {
                    error(node, ts.Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass));
                }
                return false;
            }
            return true;
        }
        function invocationErrorDetails(apparentType, kind) {
            var errorInfo;
            var isCall = kind === 0 /* Call */;
            var awaitedType = getAwaitedType(apparentType);
            var maybeMissingAwait = awaitedType && getSignaturesOfType(awaitedType, kind).length > 0;
            if (apparentType.flags & 1048576 /* Union */) {
                var types = apparentType.types;
                var hasSignatures = false;
                for (var _i = 0, types_18 = types; _i < types_18.length; _i++) {
                    var constituent = types_18[_i];
                    var signatures = getSignaturesOfType(constituent, kind);
                    if (signatures.length !== 0) {
                        hasSignatures = true;
                        if (errorInfo) {
                            // Bail early if we already have an error, no chance of "No constituent of type is callable"
                            break;
                        }
                    }
                    else {
                        // Error on the first non callable constituent only
                        if (!errorInfo) {
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ?
                                ts.Diagnostics.Type_0_has_no_call_signatures :
                                ts.Diagnostics.Type_0_has_no_construct_signatures, typeToString(constituent));
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ?
                                ts.Diagnostics.Not_all_constituents_of_type_0_are_callable :
                                ts.Diagnostics.Not_all_constituents_of_type_0_are_constructable, typeToString(apparentType));
                        }
                        if (hasSignatures) {
                            // Bail early if we already found a siganture, no chance of "No constituent of type is callable"
                            break;
                        }
                    }
                }
                if (!hasSignatures) {
                    errorInfo = ts.chainDiagnosticMessages(
                    /* detials */ undefined, isCall ?
                        ts.Diagnostics.No_constituent_of_type_0_is_callable :
                        ts.Diagnostics.No_constituent_of_type_0_is_constructable, typeToString(apparentType));
                }
                if (!errorInfo) {
                    errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ?
                        ts.Diagnostics.Each_member_of_the_union_type_0_has_signatures_but_none_of_those_signatures_are_compatible_with_each_other :
                        ts.Diagnostics.Each_member_of_the_union_type_0_has_construct_signatures_but_none_of_those_signatures_are_compatible_with_each_other, typeToString(apparentType));
                }
            }
            else {
                errorInfo = ts.chainDiagnosticMessages(errorInfo, isCall ?
                    ts.Diagnostics.Type_0_has_no_call_signatures :
                    ts.Diagnostics.Type_0_has_no_construct_signatures, typeToString(apparentType));
            }
            return {
                messageChain: ts.chainDiagnosticMessages(errorInfo, isCall ? ts.Diagnostics.This_expression_is_not_callable : ts.Diagnostics.This_expression_is_not_constructable),
                relatedMessage: maybeMissingAwait ? ts.Diagnostics.Did_you_forget_to_use_await : undefined,
            };
        }
        function invocationError(errorTarget, apparentType, kind, relatedInformation) {
            var _a = invocationErrorDetails(apparentType, kind), messageChain = _a.messageChain, relatedInfo = _a.relatedMessage;
            var diagnostic = ts.createDiagnosticForNodeFromMessageChain(errorTarget, messageChain);
            if (relatedInfo) {
                ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(errorTarget, relatedInfo));
            }
            if (ts.isCallExpression(errorTarget.parent)) {
                var _b = getDiagnosticSpanForCallNode(errorTarget.parent, /* doNotIncludeArguments */ true), start = _b.start, length_7 = _b.length;
                diagnostic.start = start;
                diagnostic.length = length_7;
            }
            diagnostics.add(diagnostic);
            invocationErrorRecovery(apparentType, kind, relatedInformation ? ts.addRelatedInfo(diagnostic, relatedInformation) : diagnostic);
        }
        function invocationErrorRecovery(apparentType, kind, diagnostic) {
            if (!apparentType.symbol) {
                return;
            }
            var importNode = getSymbolLinks(apparentType.symbol).originatingImport;
            // Create a diagnostic on the originating import if possible onto which we can attach a quickfix
            //  An import call expression cannot be rewritten into another form to correct the error - the only solution is to use `.default` at the use-site
            if (importNode && !ts.isImportCall(importNode)) {
                var sigs = getSignaturesOfType(getTypeOfSymbol(getSymbolLinks(apparentType.symbol).target), kind);
                if (!sigs || !sigs.length)
                    return;
                ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(importNode, ts.Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead));
            }
        }
        function resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode) {
            var tagType = checkExpression(node.tag);
            var apparentType = getApparentType(tagType);
            if (apparentType === errorType) {
                // Another error has already been reported
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, numConstructSignatures)) {
                return resolveUntypedCall(node);
            }
            if (!callSignatures.length) {
                invocationError(node.tag, apparentType, 0 /* Call */);
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode, 0 /* None */);
        }
        /**
         * Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression.
         */
        function getDiagnosticHeadMessageForDecoratorResolution(node) {
            switch (node.parent.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression;
                case 156 /* Parameter */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression;
                case 159 /* PropertyDeclaration */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return ts.Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression;
                default:
                    return ts.Debug.fail();
            }
        }
        /**
         * Resolves a decorator as if it were a call expression.
         */
        function resolveDecorator(node, candidatesOutArray, checkMode) {
            var funcType = checkExpression(node.expression);
            var apparentType = getApparentType(funcType);
            if (apparentType === errorType) {
                return resolveErrorCall(node);
            }
            var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */);
            var numConstructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */).length;
            if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, numConstructSignatures)) {
                return resolveUntypedCall(node);
            }
            if (isPotentiallyUncalledDecorator(node, callSignatures)) {
                var nodeStr = ts.getTextOfNode(node.expression, /*includeTrivia*/ false);
                error(node, ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr);
                return resolveErrorCall(node);
            }
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            if (!callSignatures.length) {
                var errorDetails = invocationErrorDetails(apparentType, 0 /* Call */);
                var messageChain = ts.chainDiagnosticMessages(errorDetails.messageChain, headMessage);
                var diag = ts.createDiagnosticForNodeFromMessageChain(node.expression, messageChain);
                if (errorDetails.relatedMessage) {
                    ts.addRelatedInfo(diag, ts.createDiagnosticForNode(node.expression, errorDetails.relatedMessage));
                }
                diagnostics.add(diag);
                invocationErrorRecovery(apparentType, 0 /* Call */, diag);
                return resolveErrorCall(node);
            }
            return resolveCall(node, callSignatures, candidatesOutArray, checkMode, 0 /* None */, headMessage);
        }
        function createSignatureForJSXIntrinsic(node, result) {
            var namespace = getJsxNamespaceAt(node);
            var exports = namespace && getExportsOfSymbol(namespace);
            // We fake up a SFC signature for each intrinsic, however a more specific per-element signature drawn from the JSX declaration
            // file would probably be preferable.
            var typeSymbol = exports && getSymbol(exports, JsxNames.Element, 788968 /* Type */);
            var returnNode = typeSymbol && nodeBuilder.symbolToEntityName(typeSymbol, 788968 /* Type */, node);
            var declaration = ts.createFunctionTypeNode(/*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotdotdot*/ undefined, "props", /*questionMark*/ undefined, nodeBuilder.typeToTypeNode(result, node))], returnNode ? ts.createTypeReferenceNode(returnNode, /*typeArguments*/ undefined) : ts.createKeywordTypeNode(125 /* AnyKeyword */));
            var parameterSymbol = createSymbol(1 /* FunctionScopedVariable */, "props");
            parameterSymbol.type = result;
            return createSignature(declaration, 
            /*typeParameters*/ undefined, 
            /*thisParameter*/ undefined, [parameterSymbol], typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : errorType, 
            /*returnTypePredicate*/ undefined, 1, 0 /* None */);
        }
        function resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode) {
            if (isJsxIntrinsicIdentifier(node.tagName)) {
                var result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
                var fakeSignature = createSignatureForJSXIntrinsic(node, result);
                checkTypeAssignableToAndOptionallyElaborate(checkExpressionWithContextualType(node.attributes, getEffectiveFirstArgumentForJsxSignature(fakeSignature, node), /*mapper*/ undefined, 0 /* Normal */), result, node.tagName, node.attributes);
                return fakeSignature;
            }
            var exprTypes = checkExpression(node.tagName);
            var apparentType = getApparentType(exprTypes);
            if (apparentType === errorType) {
                return resolveErrorCall(node);
            }
            var signatures = getUninstantiatedJsxSignaturesOfType(exprTypes, node);
            if (isUntypedFunctionCall(exprTypes, apparentType, signatures.length, /*constructSignatures*/ 0)) {
                return resolveUntypedCall(node);
            }
            if (signatures.length === 0) {
                // We found no signatures at all, which is an error
                error(node.tagName, ts.Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, ts.getTextOfNode(node.tagName));
                return resolveErrorCall(node);
            }
            return resolveCall(node, signatures, candidatesOutArray, checkMode, 0 /* None */);
        }
        /**
         * Sometimes, we have a decorator that could accept zero arguments,
         * but is receiving too many arguments as part of the decorator invocation.
         * In those cases, a user may have meant to *call* the expression before using it as a decorator.
         */
        function isPotentiallyUncalledDecorator(decorator, signatures) {
            return signatures.length && ts.every(signatures, function (signature) {
                return signature.minArgumentCount === 0 &&
                    !signatureHasRestParameter(signature) &&
                    signature.parameters.length < getDecoratorArgumentCount(decorator, signature);
            });
        }
        function resolveSignature(node, candidatesOutArray, checkMode) {
            switch (node.kind) {
                case 196 /* CallExpression */:
                    return resolveCallExpression(node, candidatesOutArray, checkMode);
                case 197 /* NewExpression */:
                    return resolveNewExpression(node, candidatesOutArray, checkMode);
                case 198 /* TaggedTemplateExpression */:
                    return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode);
                case 157 /* Decorator */:
                    return resolveDecorator(node, candidatesOutArray, checkMode);
                case 268 /* JsxOpeningElement */:
                case 267 /* JsxSelfClosingElement */:
                    return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode);
            }
            throw ts.Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
        }
        /**
         * Resolve a signature of a given call-like expression.
         * @param node a call-like expression to try resolve a signature for
         * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service;
         *                           the function will fill it up with appropriate candidate signatures
         * @return a signature of the call-like expression or undefined if one can't be found
         */
        function getResolvedSignature(node, candidatesOutArray, checkMode) {
            var links = getNodeLinks(node);
            // If getResolvedSignature has already been called, we will have cached the resolvedSignature.
            // However, it is possible that either candidatesOutArray was not passed in the first time,
            // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work
            // to correctly fill the candidatesOutArray.
            var cached = links.resolvedSignature;
            if (cached && cached !== resolvingSignature && !candidatesOutArray) {
                return cached;
            }
            links.resolvedSignature = resolvingSignature;
            var result = resolveSignature(node, candidatesOutArray, checkMode || 0 /* Normal */);
            // When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call
            // resolution should be deferred.
            if (result !== resolvingSignature) {
                // If signature resolution originated in control flow type analysis (for example to compute the
                // assigned type in a flow assignment) we don't cache the result as it may be based on temporary
                // types from the control flow analysis.
                links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
            }
            return result;
        }
        /**
         * Indicates whether a declaration can be treated as a constructor in a JavaScript
         * file.
         */
        function isJSConstructor(node) {
            if (!node || !ts.isInJSFile(node)) {
                return false;
            }
            var func = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? node :
                ts.isVariableDeclaration(node) && node.initializer && ts.isFunctionExpression(node.initializer) ? node.initializer :
                    undefined;
            if (func) {
                // If the node has a @class tag, treat it like a constructor.
                if (ts.getJSDocClassTag(node))
                    return true;
                // If the symbol of the node has members, treat it like a constructor.
                var symbol = getSymbolOfNode(func);
                return !!symbol && ts.hasEntries(symbol.members);
            }
            return false;
        }
        function mergeJSSymbols(target, source) {
            if (source) {
                var links = getSymbolLinks(source);
                if (!links.inferredClassSymbol || !links.inferredClassSymbol.has("" + getSymbolId(target))) {
                    var inferred = ts.isTransientSymbol(target) ? target : cloneSymbol(target);
                    inferred.exports = inferred.exports || ts.createSymbolTable();
                    inferred.members = inferred.members || ts.createSymbolTable();
                    inferred.flags |= source.flags & 32 /* Class */;
                    if (ts.hasEntries(source.exports)) {
                        mergeSymbolTable(inferred.exports, source.exports);
                    }
                    if (ts.hasEntries(source.members)) {
                        mergeSymbolTable(inferred.members, source.members);
                    }
                    (links.inferredClassSymbol || (links.inferredClassSymbol = ts.createMap())).set("" + getSymbolId(inferred), inferred);
                    return inferred;
                }
                return links.inferredClassSymbol.get("" + getSymbolId(target));
            }
        }
        function getAssignedClassSymbol(decl) {
            var assignmentSymbol = decl && decl.parent &&
                (ts.isFunctionDeclaration(decl) && getSymbolOfNode(decl) ||
                    ts.isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) ||
                    ts.isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent));
            var prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype");
            var init = prototype && prototype.valueDeclaration && getAssignedJSPrototype(prototype.valueDeclaration);
            return init ? getSymbolOfNode(init) : undefined;
        }
        function getAssignedJSPrototype(node) {
            if (!node.parent) {
                return false;
            }
            var parent = node.parent;
            while (parent && parent.kind === 194 /* PropertyAccessExpression */) {
                parent = parent.parent;
            }
            if (parent && ts.isBinaryExpression(parent) && ts.isPrototypeAccess(parent.left) && parent.operatorToken.kind === 62 /* EqualsToken */) {
                var right = ts.getInitializerOfBinaryExpression(parent);
                return ts.isObjectLiteralExpression(right) && right;
            }
        }
        /**
         * Syntactically and semantically checks a call or new expression.
         * @param node The call/new expression to be checked.
         * @returns On success, the expression's signature's return type. On failure, anyType.
         */
        function checkCallExpression(node, checkMode) {
            if (!checkGrammarTypeArguments(node, node.typeArguments))
                checkGrammarArguments(node.arguments);
            var signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
            if (signature === resolvingSignature) {
                // CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
                // returns a function type. We defer checking and return nonInferrableType.
                return nonInferrableType;
            }
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return voidType;
            }
            if (node.kind === 197 /* NewExpression */) {
                var declaration = signature.declaration;
                if (declaration &&
                    declaration.kind !== 162 /* Constructor */ &&
                    declaration.kind !== 166 /* ConstructSignature */ &&
                    declaration.kind !== 171 /* ConstructorType */ &&
                    !ts.isJSDocConstructSignature(declaration) &&
                    !isJSConstructor(declaration)) {
                    // When resolved signature is a call signature (and not a construct signature) the result type is any
                    if (noImplicitAny) {
                        error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type);
                    }
                    return anyType;
                }
            }
            // In JavaScript files, calls to any identifier 'require' are treated as external module imports
            if (ts.isInJSFile(node) && isCommonJsRequire(node)) {
                return resolveExternalModuleTypeByLiteral(node.arguments[0]);
            }
            var returnType = getReturnTypeOfSignature(signature);
            // Treat any call to the global 'Symbol' function that is part of a const variable or readonly property
            // as a fresh unique symbol literal type.
            if (returnType.flags & 12288 /* ESSymbolLike */ && isSymbolOrSymbolForCall(node)) {
                return getESSymbolLikeTypeForNode(ts.walkUpParenthesizedExpressions(node.parent));
            }
            if (node.kind === 196 /* CallExpression */ && node.parent.kind === 226 /* ExpressionStatement */ &&
                returnType.flags & 16384 /* Void */ && getTypePredicateOfSignature(signature)) {
                if (!ts.isDottedName(node.expression)) {
                    error(node.expression, ts.Diagnostics.Assertions_require_the_call_target_to_be_an_identifier_or_qualified_name);
                }
                else if (!getEffectsSignature(node)) {
                    var diagnostic = error(node.expression, ts.Diagnostics.Assertions_require_every_name_in_the_call_target_to_be_declared_with_an_explicit_type_annotation);
                    getTypeOfDottedName(node.expression, diagnostic);
                }
            }
            if (ts.isInJSFile(node)) {
                var decl = ts.getDeclarationOfExpando(node);
                if (decl) {
                    var jsSymbol = getSymbolOfNode(decl);
                    if (jsSymbol && ts.hasEntries(jsSymbol.exports)) {
                        var jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, ts.emptyArray, ts.emptyArray, undefined, undefined);
                        jsAssignmentType.objectFlags |= 16384 /* JSLiteral */;
                        return getIntersectionType([returnType, jsAssignmentType]);
                    }
                }
            }
            return returnType;
        }
        function isSymbolOrSymbolForCall(node) {
            if (!ts.isCallExpression(node))
                return false;
            var left = node.expression;
            if (ts.isPropertyAccessExpression(left) && left.name.escapedText === "for") {
                left = left.expression;
            }
            if (!ts.isIdentifier(left) || left.escapedText !== "Symbol") {
                return false;
            }
            // make sure `Symbol` is the global symbol
            var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ false);
            if (!globalESSymbol) {
                return false;
            }
            return globalESSymbol === resolveName(left, "Symbol", 111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
        }
        function checkImportCallExpression(node) {
            // Check grammar of dynamic import
            if (!checkGrammarArguments(node.arguments))
                checkGrammarImportCallExpression(node);
            if (node.arguments.length === 0) {
                return createPromiseReturnType(node, anyType);
            }
            var specifier = node.arguments[0];
            var specifierType = checkExpressionCached(specifier);
            // Even though multiple arguments is grammatically incorrect, type-check extra arguments for completion
            for (var i = 1; i < node.arguments.length; ++i) {
                checkExpressionCached(node.arguments[i]);
            }
            if (specifierType.flags & 32768 /* Undefined */ || specifierType.flags & 65536 /* Null */ || !isTypeAssignableTo(specifierType, stringType)) {
                error(specifier, ts.Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType));
            }
            // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal
            var moduleSymbol = resolveExternalModuleName(node, specifier);
            if (moduleSymbol) {
                var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true, /*suppressUsageError*/ false);
                if (esModuleSymbol) {
                    return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol, moduleSymbol));
                }
            }
            return createPromiseReturnType(node, anyType);
        }
        function getTypeWithSyntheticDefaultImportType(type, symbol, originalSymbol) {
            if (allowSyntheticDefaultImports && type && type !== errorType) {
                var synthType = type;
                if (!synthType.syntheticType) {
                    var file = ts.find(originalSymbol.declarations, ts.isSourceFile);
                    var hasSyntheticDefault = canHaveSyntheticDefault(file, originalSymbol, /*dontResolveAlias*/ false);
                    if (hasSyntheticDefault) {
                        var memberTable = ts.createSymbolTable();
                        var newSymbol = createSymbol(2097152 /* Alias */, "default" /* Default */);
                        newSymbol.nameType = getLiteralType("default");
                        newSymbol.target = resolveSymbol(symbol);
                        memberTable.set("default" /* Default */, newSymbol);
                        var anonymousSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */);
                        var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
                        anonymousSymbol.type = defaultContainingObject;
                        synthType.syntheticType = isValidSpreadType(type) ? getSpreadType(type, defaultContainingObject, anonymousSymbol, /*objectFlags*/ 0, /*readonly*/ false) : defaultContainingObject;
                    }
                    else {
                        synthType.syntheticType = type;
                    }
                }
                return synthType.syntheticType;
            }
            return type;
        }
        function isCommonJsRequire(node) {
            if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
                return false;
            }
            // Make sure require is not a local function
            if (!ts.isIdentifier(node.expression))
                return ts.Debug.fail();
            var resolvedRequire = resolveName(node.expression, node.expression.escapedText, 111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); // TODO: GH#18217
            if (resolvedRequire === requireSymbol) {
                return true;
            }
            // project includes symbol named 'require' - make sure that it is ambient and local non-alias
            if (resolvedRequire.flags & 2097152 /* Alias */) {
                return false;
            }
            var targetDeclarationKind = resolvedRequire.flags & 16 /* Function */
                ? 244 /* FunctionDeclaration */
                : resolvedRequire.flags & 3 /* Variable */
                    ? 242 /* VariableDeclaration */
                    : 0 /* Unknown */;
            if (targetDeclarationKind !== 0 /* Unknown */) {
                var decl = ts.getDeclarationOfKind(resolvedRequire, targetDeclarationKind);
                // function/variable declaration should be ambient
                return !!decl && !!(decl.flags & 8388608 /* Ambient */);
            }
            return false;
        }
        function checkTaggedTemplateExpression(node) {
            if (!checkGrammarTaggedTemplateChain(node))
                checkGrammarTypeArguments(node, node.typeArguments);
            if (languageVersion < 2 /* ES2015 */) {
                checkExternalEmitHelpers(node, 131072 /* MakeTemplateObject */);
            }
            return getReturnTypeOfSignature(getResolvedSignature(node));
        }
        function checkAssertion(node) {
            return checkAssertionWorker(node, node.type, node.expression);
        }
        function isValidConstAssertionArgument(node) {
            switch (node.kind) {
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 192 /* ArrayLiteralExpression */:
                case 193 /* ObjectLiteralExpression */:
                    return true;
                case 200 /* ParenthesizedExpression */:
                    return isValidConstAssertionArgument(node.expression);
                case 207 /* PrefixUnaryExpression */:
                    var op = node.operator;
                    var arg = node.operand;
                    return op === 40 /* MinusToken */ && (arg.kind === 8 /* NumericLiteral */ || arg.kind === 9 /* BigIntLiteral */) ||
                        op === 39 /* PlusToken */ && arg.kind === 8 /* NumericLiteral */;
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    var expr = node.expression;
                    if (ts.isIdentifier(expr)) {
                        var symbol = getSymbolAtLocation(expr);
                        if (symbol && symbol.flags & 2097152 /* Alias */) {
                            symbol = resolveAlias(symbol);
                        }
                        return !!(symbol && (symbol.flags & 384 /* Enum */) && getEnumKind(symbol) === 1 /* Literal */);
                    }
            }
            return false;
        }
        function checkAssertionWorker(errNode, type, expression, checkMode) {
            var exprType = checkExpression(expression, checkMode);
            if (ts.isConstTypeReference(type)) {
                if (!isValidConstAssertionArgument(expression)) {
                    error(expression, ts.Diagnostics.A_const_assertions_can_only_be_applied_to_references_to_enum_members_or_string_number_boolean_array_or_object_literals);
                }
                return getRegularTypeOfLiteralType(exprType);
            }
            checkSourceElement(type);
            exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(exprType));
            var targetType = getTypeFromTypeNode(type);
            if (produceDiagnostics && targetType !== errorType) {
                var widenedType = getWidenedType(exprType);
                if (!isTypeComparableTo(targetType, widenedType)) {
                    checkTypeComparableTo(exprType, targetType, errNode, ts.Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first);
                }
            }
            return targetType;
        }
        function checkNonNullChain(node) {
            var leftType = checkExpression(node.expression);
            var nonOptionalType = getOptionalExpressionType(leftType, node.expression);
            return propagateOptionalTypeMarker(getNonNullableType(nonOptionalType), node, nonOptionalType !== leftType);
        }
        function checkNonNullAssertion(node) {
            return node.flags & 32 /* OptionalChain */ ? checkNonNullChain(node) :
                getNonNullableType(checkExpression(node.expression));
        }
        function checkMetaProperty(node) {
            checkGrammarMetaProperty(node);
            if (node.keywordToken === 99 /* NewKeyword */) {
                return checkNewTargetMetaProperty(node);
            }
            if (node.keywordToken === 96 /* ImportKeyword */) {
                return checkImportMetaProperty(node);
            }
            return ts.Debug.assertNever(node.keywordToken);
        }
        function checkNewTargetMetaProperty(node) {
            var container = ts.getNewTargetContainer(node);
            if (!container) {
                error(node, ts.Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target");
                return errorType;
            }
            else if (container.kind === 162 /* Constructor */) {
                var symbol = getSymbolOfNode(container.parent);
                return getTypeOfSymbol(symbol);
            }
            else {
                var symbol = getSymbolOfNode(container);
                return getTypeOfSymbol(symbol);
            }
        }
        function checkImportMetaProperty(node) {
            if (moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) {
                error(node, ts.Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_esnext_or_system);
            }
            var file = ts.getSourceFileOfNode(node);
            ts.Debug.assert(!!(file.flags & 2097152 /* PossiblyContainsImportMeta */), "Containing file is missing import meta node flag.");
            ts.Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module.");
            return node.name.escapedText === "meta" ? getGlobalImportMetaType() : errorType;
        }
        function getTypeOfParameter(symbol) {
            var type = getTypeOfSymbol(symbol);
            if (strictNullChecks) {
                var declaration = symbol.valueDeclaration;
                if (declaration && ts.hasInitializer(declaration)) {
                    return getOptionalType(type);
                }
            }
            return type;
        }
        function getParameterNameAtPosition(signature, pos) {
            var paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
            if (pos < paramCount) {
                return signature.parameters[pos].escapedName;
            }
            var restParameter = signature.parameters[paramCount] || unknownSymbol;
            var restType = getTypeOfSymbol(restParameter);
            if (isTupleType(restType)) {
                var associatedNames = restType.target.associatedNames;
                var index = pos - paramCount;
                return associatedNames && associatedNames[index] || restParameter.escapedName + "_" + index;
            }
            return restParameter.escapedName;
        }
        function getTypeAtPosition(signature, pos) {
            return tryGetTypeAtPosition(signature, pos) || anyType;
        }
        function tryGetTypeAtPosition(signature, pos) {
            var paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
            if (pos < paramCount) {
                return getTypeOfParameter(signature.parameters[pos]);
            }
            if (signatureHasRestParameter(signature)) {
                // We want to return the value undefined for an out of bounds parameter position,
                // so we need to check bounds here before calling getIndexedAccessType (which
                // otherwise would return the type 'undefined').
                var restType = getTypeOfSymbol(signature.parameters[paramCount]);
                var index = pos - paramCount;
                if (!isTupleType(restType) || restType.target.hasRestElement || index < getTypeArguments(restType).length) {
                    return getIndexedAccessType(restType, getLiteralType(index));
                }
            }
            return undefined;
        }
        function getRestTypeAtPosition(source, pos) {
            var paramCount = getParameterCount(source);
            var restType = getEffectiveRestType(source);
            var nonRestCount = paramCount - (restType ? 1 : 0);
            if (restType && pos === nonRestCount) {
                return restType;
            }
            var types = [];
            var names = [];
            for (var i = pos; i < nonRestCount; i++) {
                types.push(getTypeAtPosition(source, i));
                names.push(getParameterNameAtPosition(source, i));
            }
            if (restType) {
                types.push(getIndexedAccessType(restType, numberType));
                names.push(getParameterNameAtPosition(source, nonRestCount));
            }
            var minArgumentCount = getMinArgumentCount(source);
            var minLength = minArgumentCount < pos ? 0 : minArgumentCount - pos;
            return createTupleType(types, minLength, !!restType, /*readonly*/ false, names);
        }
        function getParameterCount(signature) {
            var length = signature.parameters.length;
            if (signatureHasRestParameter(signature)) {
                var restType = getTypeOfSymbol(signature.parameters[length - 1]);
                if (isTupleType(restType)) {
                    return length + getTypeArguments(restType).length - 1;
                }
            }
            return length;
        }
        function getMinArgumentCount(signature, strongArityForUntypedJS) {
            if (signatureHasRestParameter(signature)) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                if (isTupleType(restType)) {
                    var minLength = restType.target.minLength;
                    if (minLength > 0) {
                        return signature.parameters.length - 1 + minLength;
                    }
                }
            }
            if (!strongArityForUntypedJS && signature.flags & 16 /* IsUntypedSignatureInJSFile */) {
                return 0;
            }
            return signature.minArgumentCount;
        }
        function hasEffectiveRestParameter(signature) {
            if (signatureHasRestParameter(signature)) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                return !isTupleType(restType) || restType.target.hasRestElement;
            }
            return false;
        }
        function getEffectiveRestType(signature) {
            if (signatureHasRestParameter(signature)) {
                var restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
                return isTupleType(restType) ? getRestArrayTypeOfTupleType(restType) : restType;
            }
            return undefined;
        }
        function getNonArrayRestType(signature) {
            var restType = getEffectiveRestType(signature);
            return restType && !isArrayType(restType) && !isTypeAny(restType) && (getReducedType(restType).flags & 131072 /* Never */) === 0 ? restType : undefined;
        }
        function getTypeOfFirstParameterOfSignature(signature) {
            return getTypeOfFirstParameterOfSignatureWithFallback(signature, neverType);
        }
        function getTypeOfFirstParameterOfSignatureWithFallback(signature, fallbackType) {
            return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : fallbackType;
        }
        function inferFromAnnotatedParameters(signature, context, inferenceContext) {
            var len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var declaration = signature.parameters[i].valueDeclaration;
                if (declaration.type) {
                    var typeNode = ts.getEffectiveTypeAnnotationNode(declaration);
                    if (typeNode) {
                        inferTypes(inferenceContext.inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
                    }
                }
            }
            var restType = getEffectiveRestType(context);
            if (restType && restType.flags & 262144 /* TypeParameter */) {
                // The contextual signature has a generic rest parameter. We first instantiate the contextual
                // signature (without fixing type parameters) and assign types to contextually typed parameters.
                var instantiatedContext = instantiateSignature(context, inferenceContext.nonFixingMapper);
                assignContextualParameterTypes(signature, instantiatedContext);
                // We then infer from a tuple type representing the parameters that correspond to the contextual
                // rest parameter.
                var restPos = getParameterCount(context) - 1;
                inferTypes(inferenceContext.inferences, getRestTypeAtPosition(signature, restPos), restType);
            }
        }
        function assignContextualParameterTypes(signature, context) {
            signature.typeParameters = context.typeParameters;
            if (context.thisParameter) {
                var parameter = signature.thisParameter;
                if (!parameter || parameter.valueDeclaration && !parameter.valueDeclaration.type) {
                    if (!parameter) {
                        signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined);
                    }
                    assignParameterType(signature.thisParameter, getTypeOfSymbol(context.thisParameter));
                }
            }
            var len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
            for (var i = 0; i < len; i++) {
                var parameter = signature.parameters[i];
                if (!ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
                    var contextualParameterType = tryGetTypeAtPosition(context, i);
                    assignParameterType(parameter, contextualParameterType);
                }
            }
            if (signatureHasRestParameter(signature)) {
                // parameter might be a transient symbol generated by use of `arguments` in the function body.
                var parameter = ts.last(signature.parameters);
                if (ts.isTransientSymbol(parameter) || !ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) {
                    var contextualParameterType = getRestTypeAtPosition(context, len);
                    assignParameterType(parameter, contextualParameterType);
                }
            }
        }
        function assignNonContextualParameterTypes(signature) {
            if (signature.thisParameter) {
                assignParameterType(signature.thisParameter);
            }
            for (var _i = 0, _a = signature.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                assignParameterType(parameter);
            }
        }
        function assignParameterType(parameter, type) {
            var links = getSymbolLinks(parameter);
            if (!links.type) {
                var declaration = parameter.valueDeclaration;
                links.type = type || getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true);
                if (declaration.name.kind !== 75 /* Identifier */) {
                    // if inference didn't come up with anything but unknown, fall back to the binding pattern if present.
                    if (links.type === unknownType) {
                        links.type = getTypeFromBindingPattern(declaration.name);
                    }
                    assignBindingElementTypes(declaration.name);
                }
            }
        }
        // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push
        // the destructured type into the contained binding elements.
        function assignBindingElementTypes(pattern) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (!ts.isOmittedExpression(element)) {
                    if (element.name.kind === 75 /* Identifier */) {
                        getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
                    }
                    else {
                        assignBindingElementTypes(element.name);
                    }
                }
            }
        }
        function createPromiseType(promisedType) {
            // creates a `Promise<T>` type where `T` is the promisedType argument
            var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
            if (globalPromiseType !== emptyGenericType) {
                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
                promisedType = getAwaitedType(promisedType) || unknownType;
                return createTypeReference(globalPromiseType, [promisedType]);
            }
            return unknownType;
        }
        function createPromiseLikeType(promisedType) {
            // creates a `PromiseLike<T>` type where `T` is the promisedType argument
            var globalPromiseLikeType = getGlobalPromiseLikeType(/*reportErrors*/ true);
            if (globalPromiseLikeType !== emptyGenericType) {
                // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
                promisedType = getAwaitedType(promisedType) || unknownType;
                return createTypeReference(globalPromiseLikeType, [promisedType]);
            }
            return unknownType;
        }
        function createPromiseReturnType(func, promisedType) {
            var promiseType = createPromiseType(promisedType);
            if (promiseType === unknownType) {
                error(func, ts.isImportCall(func) ?
                    ts.Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option :
                    ts.Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option);
                return errorType;
            }
            else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) {
                error(func, ts.isImportCall(func) ?
                    ts.Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option :
                    ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
            }
            return promiseType;
        }
        function getReturnTypeFromBody(func, checkMode) {
            if (!func.body) {
                return errorType;
            }
            var functionFlags = ts.getFunctionFlags(func);
            var isAsync = (functionFlags & 2 /* Async */) !== 0;
            var isGenerator = (functionFlags & 1 /* Generator */) !== 0;
            var returnType;
            var yieldType;
            var nextType;
            var fallbackReturnType = voidType;
            if (func.body.kind !== 223 /* Block */) { // Async or normal arrow function
                returnType = checkExpressionCached(func.body, checkMode && checkMode & ~8 /* SkipGenericFunctions */);
                if (isAsync) {
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                    // return type of the body should be unwrapped to its awaited type, which we will wrap in
                    // the native Promise<T> type later in this function.
                    returnType = checkAwaitedType(returnType, /*errorNode*/ func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                }
            }
            else if (isGenerator) { // Generator or AsyncGenerator function
                var returnTypes = checkAndAggregateReturnExpressionTypes(func, checkMode);
                if (!returnTypes) {
                    fallbackReturnType = neverType;
                }
                else if (returnTypes.length > 0) {
                    returnType = getUnionType(returnTypes, 2 /* Subtype */);
                }
                var _a = checkAndAggregateYieldOperandTypes(func, checkMode), yieldTypes = _a.yieldTypes, nextTypes = _a.nextTypes;
                yieldType = ts.some(yieldTypes) ? getUnionType(yieldTypes, 2 /* Subtype */) : undefined;
                nextType = ts.some(nextTypes) ? getIntersectionType(nextTypes) : undefined;
            }
            else { // Async or normal function
                var types = checkAndAggregateReturnExpressionTypes(func, checkMode);
                if (!types) {
                    // For an async function, the return type will not be never, but rather a Promise for never.
                    return functionFlags & 2 /* Async */
                        ? createPromiseReturnType(func, neverType) // Async function
                        : neverType; // Normal function
                }
                if (types.length === 0) {
                    // For an async function, the return type will not be void, but rather a Promise for void.
                    return functionFlags & 2 /* Async */
                        ? createPromiseReturnType(func, voidType) // Async function
                        : voidType; // Normal function
                }
                // Return a union of the return expression types.
                returnType = getUnionType(types, 2 /* Subtype */);
            }
            if (returnType || yieldType || nextType) {
                if (yieldType)
                    reportErrorsFromWidening(func, yieldType, 3 /* GeneratorYield */);
                if (returnType)
                    reportErrorsFromWidening(func, returnType, 1 /* FunctionReturn */);
                if (nextType)
                    reportErrorsFromWidening(func, nextType, 2 /* GeneratorNext */);
                if (returnType && isUnitType(returnType) ||
                    yieldType && isUnitType(yieldType) ||
                    nextType && isUnitType(nextType)) {
                    var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
                    var contextualType = !contextualSignature ? undefined :
                        contextualSignature === getSignatureFromDeclaration(func) ? isGenerator ? undefined : returnType :
                            instantiateContextualType(getReturnTypeOfSignature(contextualSignature), func);
                    if (isGenerator) {
                        yieldType = getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(yieldType, contextualType, 0 /* Yield */, isAsync);
                        returnType = getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(returnType, contextualType, 1 /* Return */, isAsync);
                        nextType = getWidenedLiteralLikeTypeForContextualIterationTypeIfNeeded(nextType, contextualType, 2 /* Next */, isAsync);
                    }
                    else {
                        returnType = getWidenedLiteralLikeTypeForContextualReturnTypeIfNeeded(returnType, contextualType, isAsync);
                    }
                }
                if (yieldType)
                    yieldType = getWidenedType(yieldType);
                if (returnType)
                    returnType = getWidenedType(returnType);
                if (nextType)
                    nextType = getWidenedType(nextType);
            }
            if (isGenerator) {
                return createGeneratorReturnType(yieldType || neverType, returnType || fallbackReturnType, nextType || getContextualIterationType(2 /* Next */, func) || unknownType, isAsync);
            }
            else {
                // From within an async function you can return either a non-promise value or a promise. Any
                // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                // return type of the body is awaited type of the body, wrapped in a native Promise<T> type.
                return isAsync
                    ? createPromiseType(returnType || fallbackReturnType)
                    : returnType || fallbackReturnType;
            }
        }
        function createGeneratorReturnType(yieldType, returnType, nextType, isAsyncGenerator) {
            var resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
            var globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false);
            yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType;
            returnType = resolver.resolveIterationType(returnType, /*errorNode*/ undefined) || unknownType;
            nextType = resolver.resolveIterationType(nextType, /*errorNode*/ undefined) || unknownType;
            if (globalGeneratorType === emptyGenericType) {
                // Fall back to the global IterableIterator if returnType is assignable to the expected return iteration
                // type of IterableIterator, and the expected next iteration type of IterableIterator is assignable to
                // nextType.
                var globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false);
                var iterationTypes = globalType !== emptyGenericType ? getIterationTypesOfGlobalIterableType(globalType, resolver) : undefined;
                var iterableIteratorReturnType = iterationTypes ? iterationTypes.returnType : anyType;
                var iterableIteratorNextType = iterationTypes ? iterationTypes.nextType : undefinedType;
                if (isTypeAssignableTo(returnType, iterableIteratorReturnType) &&
                    isTypeAssignableTo(iterableIteratorNextType, nextType)) {
                    if (globalType !== emptyGenericType) {
                        return createTypeFromGenericGlobalType(globalType, [yieldType]);
                    }
                    // The global IterableIterator type doesn't exist, so report an error
                    resolver.getGlobalIterableIteratorType(/*reportErrors*/ true);
                    return emptyObjectType;
                }
                // The global Generator type doesn't exist, so report an error
                resolver.getGlobalGeneratorType(/*reportErrors*/ true);
                return emptyObjectType;
            }
            return createTypeFromGenericGlobalType(globalGeneratorType, [yieldType, returnType, nextType]);
        }
        function checkAndAggregateYieldOperandTypes(func, checkMode) {
            var yieldTypes = [];
            var nextTypes = [];
            var isAsync = (ts.getFunctionFlags(func) & 2 /* Async */) !== 0;
            ts.forEachYieldExpression(func.body, function (yieldExpression) {
                var yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : undefinedWideningType;
                ts.pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpressionType, anyType, isAsync));
                var nextType;
                if (yieldExpression.asteriskToken) {
                    var iterationTypes = getIterationTypesOfIterable(yieldExpressionType, isAsync ? 19 /* AsyncYieldStar */ : 17 /* YieldStar */, yieldExpression.expression);
                    nextType = iterationTypes && iterationTypes.nextType;
                }
                else {
                    nextType = getContextualType(yieldExpression);
                }
                if (nextType)
                    ts.pushIfUnique(nextTypes, nextType);
            });
            return { yieldTypes: yieldTypes, nextTypes: nextTypes };
        }
        function getYieldedTypeOfYieldExpression(node, expressionType, sentType, isAsync) {
            var errorNode = node.expression || node;
            // A `yield*` expression effectively yields everything that its operand yields
            var yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(isAsync ? 19 /* AsyncYieldStar */ : 17 /* YieldStar */, expressionType, sentType, errorNode) : expressionType;
            return !isAsync ? yieldedType : getAwaitedType(yieldedType, errorNode, node.asteriskToken
                ? ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member
                : ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        /**
         * Collect the TypeFacts learned from a typeof switch with
         * total clauses `witnesses`, and the active clause ranging
         * from `start` to `end`. Parameter `hasDefault` denotes
         * whether the active clause contains a default clause.
         */
        function getFactsFromTypeofSwitch(start, end, witnesses, hasDefault) {
            var facts = 0 /* None */;
            // When in the default we only collect inequality facts
            // because default is 'in theory' a set of infinite
            // equalities.
            if (hasDefault) {
                // Value is not equal to any types after the active clause.
                for (var i = end; i < witnesses.length; i++) {
                    facts |= typeofNEFacts.get(witnesses[i]) || 32768 /* TypeofNEHostObject */;
                }
                // Remove inequalities for types that appear in the
                // active clause because they appear before other
                // types collected so far.
                for (var i = start; i < end; i++) {
                    facts &= ~(typeofNEFacts.get(witnesses[i]) || 0);
                }
                // Add inequalities for types before the active clause unconditionally.
                for (var i = 0; i < start; i++) {
                    facts |= typeofNEFacts.get(witnesses[i]) || 32768 /* TypeofNEHostObject */;
                }
            }
            // When in an active clause without default the set of
            // equalities is finite.
            else {
                // Add equalities for all types in the active clause.
                for (var i = start; i < end; i++) {
                    facts |= typeofEQFacts.get(witnesses[i]) || 128 /* TypeofEQHostObject */;
                }
                // Remove equalities for types that appear before the
                // active clause.
                for (var i = 0; i < start; i++) {
                    facts &= ~(typeofEQFacts.get(witnesses[i]) || 0);
                }
            }
            return facts;
        }
        function isExhaustiveSwitchStatement(node) {
            var links = getNodeLinks(node);
            return links.isExhaustive !== undefined ? links.isExhaustive : (links.isExhaustive = computeExhaustiveSwitchStatement(node));
        }
        function computeExhaustiveSwitchStatement(node) {
            if (node.expression.kind === 204 /* TypeOfExpression */) {
                var operandType = getTypeOfExpression(node.expression.expression);
                var witnesses = getSwitchClauseTypeOfWitnesses(node, /*retainDefault*/ false);
                // notEqualFacts states that the type of the switched value is not equal to every type in the switch.
                var notEqualFacts_1 = getFactsFromTypeofSwitch(0, 0, witnesses, /*hasDefault*/ true);
                var type_3 = getBaseConstraintOfType(operandType) || operandType;
                return !!(filterType(type_3, function (t) { return (getTypeFacts(t) & notEqualFacts_1) === notEqualFacts_1; }).flags & 131072 /* Never */);
            }
            var type = getTypeOfExpression(node.expression);
            if (!isLiteralType(type)) {
                return false;
            }
            var switchTypes = getSwitchClauseTypes(node);
            if (!switchTypes.length || ts.some(switchTypes, isNeitherUnitTypeNorNever)) {
                return false;
            }
            return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
        }
        function functionHasImplicitReturn(func) {
            return func.endFlowNode && isReachableFlowNode(func.endFlowNode);
        }
        /** NOTE: Return value of `[]` means a different thing than `undefined`. `[]` means func returns `void`, `undefined` means it returns `never`. */
        function checkAndAggregateReturnExpressionTypes(func, checkMode) {
            var functionFlags = ts.getFunctionFlags(func);
            var aggregatedTypes = [];
            var hasReturnWithNoExpression = functionHasImplicitReturn(func);
            var hasReturnOfTypeNever = false;
            ts.forEachReturnStatement(func.body, function (returnStatement) {
                var expr = returnStatement.expression;
                if (expr) {
                    var type = checkExpressionCached(expr, checkMode && checkMode & ~8 /* SkipGenericFunctions */);
                    if (functionFlags & 2 /* Async */) {
                        // From within an async function you can return either a non-promise value or a promise. Any
                        // Promise/A+ compatible implementation will always assimilate any foreign promise, so the
                        // return type of the body should be unwrapped to its awaited type, which should be wrapped in
                        // the native Promise<T> type by the caller.
                        type = checkAwaitedType(type, func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                    }
                    if (type.flags & 131072 /* Never */) {
                        hasReturnOfTypeNever = true;
                    }
                    ts.pushIfUnique(aggregatedTypes, type);
                }
                else {
                    hasReturnWithNoExpression = true;
                }
            });
            if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || mayReturnNever(func))) {
                return undefined;
            }
            if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression &&
                !(isJSConstructor(func) && aggregatedTypes.some(function (t) { return t.symbol === func.symbol; }))) {
                // Javascript "callable constructors", containing eg `if (!(this instanceof A)) return new A()` should not add undefined
                ts.pushIfUnique(aggregatedTypes, undefinedType);
            }
            return aggregatedTypes;
        }
        function mayReturnNever(func) {
            switch (func.kind) {
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return true;
                case 161 /* MethodDeclaration */:
                    return func.parent.kind === 193 /* ObjectLiteralExpression */;
                default:
                    return false;
            }
        }
        /**
         * TypeScript Specification 1.0 (6.3) - July 2014
         *   An explicitly typed function whose return type isn't the Void type,
         *   the Any type, or a union type containing the Void or Any type as a constituent
         *   must have at least one return statement somewhere in its body.
         *   An exception to this rule is if the function implementation consists of a single 'throw' statement.
         *
         * @param returnType - return type of the function, can be undefined if return type is not explicitly specified
         */
        function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func, returnType) {
            if (!produceDiagnostics) {
                return;
            }
            var functionFlags = ts.getFunctionFlags(func);
            var type = returnType && unwrapReturnType(returnType, functionFlags);
            // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
            if (type && maybeTypeOfKind(type, 1 /* Any */ | 16384 /* Void */)) {
                return;
            }
            // If all we have is a function signature, or an arrow function with an expression body, then there is nothing to check.
            // also if HasImplicitReturn flag is not set this means that all codepaths in function body end with return or throw
            if (func.kind === 160 /* MethodSignature */ || ts.nodeIsMissing(func.body) || func.body.kind !== 223 /* Block */ || !functionHasImplicitReturn(func)) {
                return;
            }
            var hasExplicitReturn = func.flags & 512 /* HasExplicitReturn */;
            if (type && type.flags & 131072 /* Never */) {
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point);
            }
            else if (type && !hasExplicitReturn) {
                // minimal check: function has syntactic return type annotation and no explicit return statements in the body
                // this function does not conform to the specification.
                // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present
                error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value);
            }
            else if (type && strictNullChecks && !isTypeAssignableTo(undefinedType, type)) {
                error(ts.getEffectiveReturnTypeNode(func) || func, ts.Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined);
            }
            else if (compilerOptions.noImplicitReturns) {
                if (!type) {
                    // If return type annotation is omitted check if function has any explicit return statements.
                    // If it does not have any - its inferred return type is void - don't do any checks.
                    // Otherwise get inferred return type from function body and report error only if it is not void / anytype
                    if (!hasExplicitReturn) {
                        return;
                    }
                    var inferredReturnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func));
                    if (isUnwrappedReturnTypeVoidOrAny(func, inferredReturnType)) {
                        return;
                    }
                }
                error(ts.getEffectiveReturnTypeNode(func) || func, ts.Diagnostics.Not_all_code_paths_return_a_value);
            }
        }
        function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) {
            ts.Debug.assert(node.kind !== 161 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            checkNodeDeferred(node);
            // The identityMapper object is used to indicate that function expressions are wildcards
            if (checkMode && checkMode & 4 /* SkipContextSensitive */ && isContextSensitive(node)) {
                // Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
                if (!ts.getEffectiveReturnTypeNode(node) && !hasContextSensitiveParameters(node)) {
                    // Return plain anyFunctionType if there is no possibility we'll make inferences from the return type
                    var contextualSignature = getContextualSignature(node);
                    if (contextualSignature && couldContainTypeVariables(getReturnTypeOfSignature(contextualSignature))) {
                        var links = getNodeLinks(node);
                        if (links.contextFreeType) {
                            return links.contextFreeType;
                        }
                        var returnType = getReturnTypeFromBody(node, checkMode);
                        var returnOnlySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, 0 /* None */);
                        var returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], ts.emptyArray, undefined, undefined);
                        returnOnlyType.objectFlags |= 2097152 /* NonInferrableType */;
                        return links.contextFreeType = returnOnlyType;
                    }
                }
                return anyFunctionType;
            }
            // Grammar checking
            var hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
            if (!hasGrammarError && node.kind === 201 /* FunctionExpression */) {
                checkGrammarForGenerator(node);
            }
            contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node, checkMode);
            return getTypeOfSymbol(getSymbolOfNode(node));
        }
        function contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node, checkMode) {
            var links = getNodeLinks(node);
            // Check if function expression is contextually typed and assign parameter types if so.
            if (!(links.flags & 1024 /* ContextChecked */)) {
                var contextualSignature = getContextualSignature(node);
                // If a type check is started at a function expression that is an argument of a function call, obtaining the
                // contextual type may recursively get back to here during overload resolution of the call. If so, we will have
                // already assigned contextual types.
                if (!(links.flags & 1024 /* ContextChecked */)) {
                    links.flags |= 1024 /* ContextChecked */;
                    var signature = ts.firstOrUndefined(getSignaturesOfType(getTypeOfSymbol(getSymbolOfNode(node)), 0 /* Call */));
                    if (!signature) {
                        return;
                    }
                    if (isContextSensitive(node)) {
                        if (contextualSignature) {
                            var inferenceContext = getInferenceContext(node);
                            if (checkMode && checkMode & 2 /* Inferential */) {
                                inferFromAnnotatedParameters(signature, contextualSignature, inferenceContext);
                            }
                            var instantiatedContextualSignature = inferenceContext ?
                                instantiateSignature(contextualSignature, inferenceContext.mapper) : contextualSignature;
                            assignContextualParameterTypes(signature, instantiatedContextualSignature);
                        }
                        else {
                            // Force resolution of all parameter types such that the absence of a contextual type is consistently reflected.
                            assignNonContextualParameterTypes(signature);
                        }
                    }
                    if (contextualSignature && !getReturnTypeFromAnnotation(node) && !signature.resolvedReturnType) {
                        var returnType = getReturnTypeFromBody(node, checkMode);
                        if (!signature.resolvedReturnType) {
                            signature.resolvedReturnType = returnType;
                        }
                    }
                    checkSignatureDeclaration(node);
                }
            }
        }
        function checkFunctionExpressionOrObjectLiteralMethodDeferred(node) {
            ts.Debug.assert(node.kind !== 161 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node));
            var functionFlags = ts.getFunctionFlags(node);
            var returnType = getReturnTypeFromAnnotation(node);
            checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
            if (node.body) {
                if (!ts.getEffectiveReturnTypeNode(node)) {
                    // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors
                    // we need. An example is the noImplicitAny errors resulting from widening the return expression
                    // of a function. Because checking of function expression bodies is deferred, there was never an
                    // appropriate time to do this during the main walk of the file (see the comment at the top of
                    // checkFunctionExpressionBodies). So it must be done now.
                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
                }
                if (node.body.kind === 223 /* Block */) {
                    checkSourceElement(node.body);
                }
                else {
                    // From within an async function you can return either a non-promise value or a promise. Any
                    // Promise/A+ compatible implementation will always assimilate any foreign promise, so we
                    // should not be checking assignability of a promise to the return type. Instead, we need to
                    // check assignability of the awaited type of the expression body against the promised type of
                    // its return type annotation.
                    var exprType = checkExpression(node.body);
                    var returnOrPromisedType = returnType && unwrapReturnType(returnType, functionFlags);
                    if (returnOrPromisedType) {
                        if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */) { // Async function
                            var awaitedType = checkAwaitedType(exprType, node.body, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
                            checkTypeAssignableToAndOptionallyElaborate(awaitedType, returnOrPromisedType, node.body, node.body);
                        }
                        else { // Normal function
                            checkTypeAssignableToAndOptionallyElaborate(exprType, returnOrPromisedType, node.body, node.body);
                        }
                    }
                }
            }
        }
        function checkArithmeticOperandType(operand, type, diagnostic, isAwaitValid) {
            if (isAwaitValid === void 0) { isAwaitValid = false; }
            if (!isTypeAssignableTo(type, numberOrBigIntType)) {
                var awaitedType = isAwaitValid && getAwaitedTypeOfPromise(type);
                errorAndMaybeSuggestAwait(operand, !!awaitedType && isTypeAssignableTo(awaitedType, numberOrBigIntType), diagnostic);
                return false;
            }
            return true;
        }
        function isReadonlyAssignmentDeclaration(d) {
            if (!ts.isCallExpression(d)) {
                return false;
            }
            if (!ts.isBindableObjectDefinePropertyCall(d)) {
                return false;
            }
            var objectLitType = checkExpressionCached(d.arguments[2]);
            var valueType = getTypeOfPropertyOfType(objectLitType, "value");
            if (valueType) {
                var writableProp = getPropertyOfType(objectLitType, "writable");
                var writableType = writableProp && getTypeOfSymbol(writableProp);
                if (!writableType || writableType === falseType || writableType === regularFalseType) {
                    return true;
                }
                // We include this definition whereupon we walk back and check the type at the declaration because
                // The usual definition of `Object.defineProperty` will _not_ cause literal types to be preserved in the
                // argument types, should the type be contextualized by the call itself.
                if (writableProp && writableProp.valueDeclaration && ts.isPropertyAssignment(writableProp.valueDeclaration)) {
                    var initializer = writableProp.valueDeclaration.initializer;
                    var rawOriginalType = checkExpression(initializer);
                    if (rawOriginalType === falseType || rawOriginalType === regularFalseType) {
                        return true;
                    }
                }
                return false;
            }
            var setProp = getPropertyOfType(objectLitType, "set");
            return !setProp;
        }
        function isReadonlySymbol(symbol) {
            // The following symbols are considered read-only:
            // Properties with a 'readonly' modifier
            // Variables declared with 'const'
            // Get accessors without matching set accessors
            // Enum members
            // Object.defineProperty assignments with writable false or no setter
            // Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation)
            return !!(ts.getCheckFlags(symbol) & 8 /* Readonly */ ||
                symbol.flags & 4 /* Property */ && ts.getDeclarationModifierFlagsFromSymbol(symbol) & 64 /* Readonly */ ||
                symbol.flags & 3 /* Variable */ && getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */ ||
                symbol.flags & 98304 /* Accessor */ && !(symbol.flags & 65536 /* SetAccessor */) ||
                symbol.flags & 8 /* EnumMember */ ||
                ts.some(symbol.declarations, isReadonlyAssignmentDeclaration));
        }
        function isAssignmentToReadonlyEntity(expr, symbol, assignmentKind) {
            var _a, _b;
            if (assignmentKind === 0 /* None */) {
                // no assigment means it doesn't matter whether the entity is readonly
                return false;
            }
            if (isReadonlySymbol(symbol)) {
                // Allow assignments to readonly properties within constructors of the same class declaration.
                if (symbol.flags & 4 /* Property */ &&
                    ts.isAccessExpression(expr) &&
                    expr.expression.kind === 104 /* ThisKeyword */) {
                    // Look for if this is the constructor for the class that `symbol` is a property of.
                    var ctor = ts.getContainingFunction(expr);
                    if (!(ctor && ctor.kind === 162 /* Constructor */)) {
                        return true;
                    }
                    if (symbol.valueDeclaration) {
                        var isAssignmentDeclaration_1 = ts.isBinaryExpression(symbol.valueDeclaration);
                        var isLocalPropertyDeclaration = ctor.parent === symbol.valueDeclaration.parent;
                        var isLocalParameterProperty = ctor === symbol.valueDeclaration.parent;
                        var isLocalThisPropertyAssignment = isAssignmentDeclaration_1 && ((_a = symbol.parent) === null || _a === void 0 ? void 0 : _a.valueDeclaration) === ctor.parent;
                        var isLocalThisPropertyAssignmentConstructorFunction = isAssignmentDeclaration_1 && ((_b = symbol.parent) === null || _b === void 0 ? void 0 : _b.valueDeclaration) === ctor;
                        var isWriteableSymbol = isLocalPropertyDeclaration
                            || isLocalParameterProperty
                            || isLocalThisPropertyAssignment
                            || isLocalThisPropertyAssignmentConstructorFunction;
                        return !isWriteableSymbol;
                    }
                }
                return true;
            }
            if (ts.isAccessExpression(expr)) {
                // references through namespace import should be readonly
                var node = ts.skipParentheses(expr.expression);
                if (node.kind === 75 /* Identifier */) {
                    var symbol_2 = getNodeLinks(node).resolvedSymbol;
                    if (symbol_2.flags & 2097152 /* Alias */) {
                        var declaration = getDeclarationOfAliasSymbol(symbol_2);
                        return !!declaration && declaration.kind === 256 /* NamespaceImport */;
                    }
                }
            }
            return false;
        }
        function checkReferenceExpression(expr, invalidReferenceMessage, invalidOptionalChainMessage) {
            // References are combinations of identifiers, parentheses, and property accesses.
            var node = ts.skipOuterExpressions(expr, 6 /* Assertions */ | 1 /* Parentheses */);
            if (node.kind !== 75 /* Identifier */ && !ts.isAccessExpression(node)) {
                error(expr, invalidReferenceMessage);
                return false;
            }
            if (node.flags & 32 /* OptionalChain */) {
                error(expr, invalidOptionalChainMessage);
                return false;
            }
            return true;
        }
        function checkDeleteExpression(node) {
            checkExpression(node.expression);
            var expr = ts.skipParentheses(node.expression);
            if (!ts.isAccessExpression(expr)) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference);
                return booleanType;
            }
            // eslint-disable-next-line
            if (expr.kind === 194 /* PropertyAccessExpression */ && ts.isPrivateIdentifier(expr.name)) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_private_identifier);
            }
            var links = getNodeLinks(expr);
            var symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol);
            if (symbol && isReadonlySymbol(symbol)) {
                error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_read_only_property);
            }
            return booleanType;
        }
        function checkTypeOfExpression(node) {
            checkExpression(node.expression);
            return typeofType;
        }
        function checkVoidExpression(node) {
            checkExpression(node.expression);
            return undefinedWideningType;
        }
        function isTopLevelAwait(node) {
            var container = ts.getThisContainer(node, /*includeArrowFunctions*/ true);
            return ts.isSourceFile(container);
        }
        function checkAwaitExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 32768 /* AwaitContext */)) {
                    if (isTopLevelAwait(node)) {
                        var sourceFile = ts.getSourceFileOfNode(node);
                        if (!hasParseDiagnostics(sourceFile)) {
                            var span = void 0;
                            if (!ts.isEffectiveExternalModule(sourceFile, compilerOptions)) {
                                if (!span)
                                    span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                                var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module);
                                diagnostics.add(diagnostic);
                            }
                            if ((moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System) || languageVersion < 4 /* ES2017 */) {
                                span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                                var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher);
                                diagnostics.add(diagnostic);
                            }
                        }
                    }
                    else {
                        // use of 'await' in non-async function
                        var sourceFile = ts.getSourceFileOfNode(node);
                        if (!hasParseDiagnostics(sourceFile)) {
                            var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                            var diagnostic = ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules);
                            var func = ts.getContainingFunction(node);
                            if (func && func.kind !== 162 /* Constructor */ && (ts.getFunctionFlags(func) & 2 /* Async */) === 0) {
                                var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async);
                                ts.addRelatedInfo(diagnostic, relatedInfo);
                            }
                            diagnostics.add(diagnostic);
                        }
                    }
                }
                if (isInParameterInitializerBeforeContainingFunction(node)) {
                    error(node, ts.Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer);
                }
            }
            var operandType = checkExpression(node.expression);
            var awaitedType = checkAwaitedType(operandType, node, ts.Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
            if (awaitedType === operandType && awaitedType !== errorType && !(operandType.flags & 3 /* AnyOrUnknown */)) {
                addErrorOrSuggestion(/*isError*/ false, ts.createDiagnosticForNode(node, ts.Diagnostics.await_has_no_effect_on_the_type_of_this_expression));
            }
            return awaitedType;
        }
        function checkPrefixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            if (operandType === silentNeverType) {
                return silentNeverType;
            }
            switch (node.operand.kind) {
                case 8 /* NumericLiteral */:
                    switch (node.operator) {
                        case 40 /* MinusToken */:
                            return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text));
                        case 39 /* PlusToken */:
                            return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text));
                    }
                    break;
                case 9 /* BigIntLiteral */:
                    if (node.operator === 40 /* MinusToken */) {
                        return getFreshTypeOfLiteralType(getLiteralType({
                            negative: true,
                            base10Value: ts.parsePseudoBigInt(node.operand.text)
                        }));
                    }
            }
            switch (node.operator) {
                case 39 /* PlusToken */:
                case 40 /* MinusToken */:
                case 54 /* TildeToken */:
                    checkNonNullType(operandType, node.operand);
                    if (maybeTypeOfKind(operandType, 12288 /* ESSymbolLike */)) {
                        error(node.operand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(node.operator));
                    }
                    if (node.operator === 39 /* PlusToken */) {
                        if (maybeTypeOfKind(operandType, 2112 /* BigIntLike */)) {
                            error(node.operand, ts.Diagnostics.Operator_0_cannot_be_applied_to_type_1, ts.tokenToString(node.operator), typeToString(getBaseTypeOfLiteralType(operandType)));
                        }
                        return numberType;
                    }
                    return getUnaryResultType(operandType);
                case 53 /* ExclamationToken */:
                    checkTruthinessExpression(node.operand);
                    var facts = getTypeFacts(operandType) & (4194304 /* Truthy */ | 8388608 /* Falsy */);
                    return facts === 4194304 /* Truthy */ ? falseType :
                        facts === 8388608 /* Falsy */ ? trueType :
                            booleanType;
                case 45 /* PlusPlusToken */:
                case 46 /* MinusMinusToken */:
                    var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
                    if (ok) {
                        // run check only if former checks succeeded to avoid reporting cascading errors
                        checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access);
                    }
                    return getUnaryResultType(operandType);
            }
            return errorType;
        }
        function checkPostfixUnaryExpression(node) {
            var operandType = checkExpression(node.operand);
            if (operandType === silentNeverType) {
                return silentNeverType;
            }
            var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_bigint_or_an_enum_type);
            if (ok) {
                // run check only if former checks succeeded to avoid reporting cascading errors
                checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_may_not_be_an_optional_property_access);
            }
            return getUnaryResultType(operandType);
        }
        function getUnaryResultType(operandType) {
            if (maybeTypeOfKind(operandType, 2112 /* BigIntLike */)) {
                return isTypeAssignableToKind(operandType, 3 /* AnyOrUnknown */) || maybeTypeOfKind(operandType, 296 /* NumberLike */)
                    ? numberOrBigIntType
                    : bigintType;
            }
            // If it's not a bigint type, implicit coercion will result in a number
            return numberType;
        }
        // Return true if type might be of the given kind. A union or intersection type might be of a given
        // kind if at least one constituent type is of the given kind.
        function maybeTypeOfKind(type, kind) {
            if (type.flags & kind) {
                return true;
            }
            if (type.flags & 3145728 /* UnionOrIntersection */) {
                var types = type.types;
                for (var _i = 0, types_19 = types; _i < types_19.length; _i++) {
                    var t = types_19[_i];
                    if (maybeTypeOfKind(t, kind)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function isTypeAssignableToKind(source, kind, strict) {
            if (source.flags & kind) {
                return true;
            }
            if (strict && source.flags & (3 /* AnyOrUnknown */ | 16384 /* Void */ | 32768 /* Undefined */ | 65536 /* Null */)) {
                return false;
            }
            return !!(kind & 296 /* NumberLike */) && isTypeAssignableTo(source, numberType) ||
                !!(kind & 2112 /* BigIntLike */) && isTypeAssignableTo(source, bigintType) ||
                !!(kind & 132 /* StringLike */) && isTypeAssignableTo(source, stringType) ||
                !!(kind & 528 /* BooleanLike */) && isTypeAssignableTo(source, booleanType) ||
                !!(kind & 16384 /* Void */) && isTypeAssignableTo(source, voidType) ||
                !!(kind & 131072 /* Never */) && isTypeAssignableTo(source, neverType) ||
                !!(kind & 65536 /* Null */) && isTypeAssignableTo(source, nullType) ||
                !!(kind & 32768 /* Undefined */) && isTypeAssignableTo(source, undefinedType) ||
                !!(kind & 4096 /* ESSymbol */) && isTypeAssignableTo(source, esSymbolType) ||
                !!(kind & 67108864 /* NonPrimitive */) && isTypeAssignableTo(source, nonPrimitiveType);
        }
        function allTypesAssignableToKind(source, kind, strict) {
            return source.flags & 1048576 /* Union */ ?
                ts.every(source.types, function (subType) { return allTypesAssignableToKind(subType, kind, strict); }) :
                isTypeAssignableToKind(source, kind, strict);
        }
        function isConstEnumObjectType(type) {
            return !!(ts.getObjectFlags(type) & 16 /* Anonymous */) && !!type.symbol && isConstEnumSymbol(type.symbol);
        }
        function isConstEnumSymbol(symbol) {
            return (symbol.flags & 128 /* ConstEnum */) !== 0;
        }
        function checkInstanceOfExpression(left, right, leftType, rightType) {
            if (leftType === silentNeverType || rightType === silentNeverType) {
                return silentNeverType;
            }
            // TypeScript 1.0 spec (April 2014): 4.15.4
            // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type,
            // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature.
            // The result is always of the Boolean primitive type.
            // NOTE: do not raise error if leftType is unknown as related error was already reported
            if (!isTypeAny(leftType) &&
                allTypesAssignableToKind(leftType, 131068 /* Primitive */)) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            // NOTE: do not raise error if right is unknown as related error was already reported
            if (!(isTypeAny(rightType) || typeHasCallOrConstructSignatures(rightType) || isTypeSubtypeOf(rightType, globalFunctionType))) {
                error(right, ts.Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
            }
            return booleanType;
        }
        function checkInExpression(left, right, leftType, rightType) {
            if (leftType === silentNeverType || rightType === silentNeverType) {
                return silentNeverType;
            }
            leftType = checkNonNullType(leftType, left);
            rightType = checkNonNullType(rightType, right);
            // TypeScript 1.0 spec (April 2014): 4.15.5
            // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type,
            // and the right operand to be of type Any, an object type, or a type parameter type.
            // The result is always of the Boolean primitive type.
            if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 296 /* NumberLike */ | 12288 /* ESSymbolLike */))) {
                error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol);
            }
            if (!allTypesAssignableToKind(rightType, 67108864 /* NonPrimitive */ | 58982400 /* InstantiableNonPrimitive */)) {
                error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
            }
            return booleanType;
        }
        function checkObjectLiteralAssignment(node, sourceType, rightIsThis) {
            var properties = node.properties;
            if (strictNullChecks && properties.length === 0) {
                return checkNonNullType(sourceType, node);
            }
            for (var i = 0; i < properties.length; i++) {
                checkObjectLiteralDestructuringPropertyAssignment(node, sourceType, i, properties, rightIsThis);
            }
            return sourceType;
        }
        /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
        function checkObjectLiteralDestructuringPropertyAssignment(node, objectLiteralType, propertyIndex, allProperties, rightIsThis) {
            if (rightIsThis === void 0) { rightIsThis = false; }
            var properties = node.properties;
            var property = properties[propertyIndex];
            if (property.kind === 281 /* PropertyAssignment */ || property.kind === 282 /* ShorthandPropertyAssignment */) {
                var name = property.name;
                var exprType = getLiteralTypeFromPropertyName(name);
                if (isTypeUsableAsPropertyName(exprType)) {
                    var text = getPropertyNameFromType(exprType);
                    var prop = getPropertyOfType(objectLiteralType, text);
                    if (prop) {
                        markPropertyAsReferenced(prop, property, rightIsThis);
                        checkPropertyAccessibility(property, /*isSuper*/ false, objectLiteralType, prop);
                    }
                }
                var elementType = getIndexedAccessType(objectLiteralType, exprType, name);
                var type = getFlowTypeOfDestructuring(property, elementType);
                return checkDestructuringAssignment(property.kind === 282 /* ShorthandPropertyAssignment */ ? property : property.initializer, type);
            }
            else if (property.kind === 283 /* SpreadAssignment */) {
                if (propertyIndex < properties.length - 1) {
                    error(property, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                else {
                    if (languageVersion < 99 /* ESNext */) {
                        checkExternalEmitHelpers(property, 4 /* Rest */);
                    }
                    var nonRestNames = [];
                    if (allProperties) {
                        for (var _i = 0, allProperties_1 = allProperties; _i < allProperties_1.length; _i++) {
                            var otherProperty = allProperties_1[_i];
                            if (!ts.isSpreadAssignment(otherProperty)) {
                                nonRestNames.push(otherProperty.name);
                            }
                        }
                    }
                    var type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
                    checkGrammarForDisallowedTrailingComma(allProperties, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                    return checkDestructuringAssignment(property.expression, type);
                }
            }
            else {
                error(property, ts.Diagnostics.Property_assignment_expected);
            }
        }
        function checkArrayLiteralAssignment(node, sourceType, checkMode) {
            var elements = node.elements;
            if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                checkExternalEmitHelpers(node, 512 /* Read */);
            }
            // This elementType will be used if the specific property corresponding to this index is not
            // present (aka the tuple element property). This call also checks that the parentType is in
            // fact an iterable or array (depending on target language).
            var elementType = checkIteratedTypeOrElementType(65 /* Destructuring */, sourceType, undefinedType, node) || errorType;
            for (var i = 0; i < elements.length; i++) {
                checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode);
            }
            return sourceType;
        }
        function checkArrayLiteralDestructuringElementAssignment(node, sourceType, elementIndex, elementType, checkMode) {
            var elements = node.elements;
            var element = elements[elementIndex];
            if (element.kind !== 215 /* OmittedExpression */) {
                if (element.kind !== 213 /* SpreadElement */) {
                    var indexType = getLiteralType(elementIndex);
                    if (isArrayLikeType(sourceType)) {
                        // We create a synthetic expression so that getIndexedAccessType doesn't get confused
                        // when the element is a SyntaxKind.ElementAccessExpression.
                        var accessFlags = hasDefaultValue(element) ? 8 /* NoTupleBoundsCheck */ : 0;
                        var elementType_2 = getIndexedAccessTypeOrUndefined(sourceType, indexType, createSyntheticExpression(element, indexType), accessFlags) || errorType;
                        var assignedType = hasDefaultValue(element) ? getTypeWithFacts(elementType_2, 524288 /* NEUndefined */) : elementType_2;
                        var type = getFlowTypeOfDestructuring(element, assignedType);
                        return checkDestructuringAssignment(element, type, checkMode);
                    }
                    return checkDestructuringAssignment(element, elementType, checkMode);
                }
                if (elementIndex < elements.length - 1) {
                    error(element, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                else {
                    var restExpression = element.expression;
                    if (restExpression.kind === 209 /* BinaryExpression */ && restExpression.operatorToken.kind === 62 /* EqualsToken */) {
                        error(restExpression.operatorToken, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                    }
                    else {
                        checkGrammarForDisallowedTrailingComma(node.elements, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                        var type = everyType(sourceType, isTupleType) ?
                            mapType(sourceType, function (t) { return sliceTupleType(t, elementIndex); }) :
                            createArrayType(elementType);
                        return checkDestructuringAssignment(restExpression, type, checkMode);
                    }
                }
            }
            return undefined;
        }
        function checkDestructuringAssignment(exprOrAssignment, sourceType, checkMode, rightIsThis) {
            var target;
            if (exprOrAssignment.kind === 282 /* ShorthandPropertyAssignment */) {
                var prop = exprOrAssignment;
                if (prop.objectAssignmentInitializer) {
                    // In strict null checking mode, if a default value of a non-undefined type is specified, remove
                    // undefined from the final type.
                    if (strictNullChecks &&
                        !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & 32768 /* Undefined */)) {
                        sourceType = getTypeWithFacts(sourceType, 524288 /* NEUndefined */);
                    }
                    checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, checkMode);
                }
                target = exprOrAssignment.name;
            }
            else {
                target = exprOrAssignment;
            }
            if (target.kind === 209 /* BinaryExpression */ && target.operatorToken.kind === 62 /* EqualsToken */) {
                checkBinaryExpression(target, checkMode);
                target = target.left;
            }
            if (target.kind === 193 /* ObjectLiteralExpression */) {
                return checkObjectLiteralAssignment(target, sourceType, rightIsThis);
            }
            if (target.kind === 192 /* ArrayLiteralExpression */) {
                return checkArrayLiteralAssignment(target, sourceType, checkMode);
            }
            return checkReferenceAssignment(target, sourceType, checkMode);
        }
        function checkReferenceAssignment(target, sourceType, checkMode) {
            var targetType = checkExpression(target, checkMode);
            var error = target.parent.kind === 283 /* SpreadAssignment */ ?
                ts.Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access :
                ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access;
            var optionalError = target.parent.kind === 283 /* SpreadAssignment */ ?
                ts.Diagnostics.The_target_of_an_object_rest_assignment_may_not_be_an_optional_property_access :
                ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access;
            if (checkReferenceExpression(target, error, optionalError)) {
                checkTypeAssignableToAndOptionallyElaborate(sourceType, targetType, target, target);
            }
            if (ts.isPrivateIdentifierPropertyAccessExpression(target)) {
                checkExternalEmitHelpers(target.parent, 524288 /* ClassPrivateFieldSet */);
            }
            return sourceType;
        }
        /**
         * This is a *shallow* check: An expression is side-effect-free if the
         * evaluation of the expression *itself* cannot produce side effects.
         * For example, x++ / 3 is side-effect free because the / operator
         * does not have side effects.
         * The intent is to "smell test" an expression for correctness in positions where
         * its value is discarded (e.g. the left side of the comma operator).
         */
        function isSideEffectFree(node) {
            node = ts.skipParentheses(node);
            switch (node.kind) {
                case 75 /* Identifier */:
                case 10 /* StringLiteral */:
                case 13 /* RegularExpressionLiteral */:
                case 198 /* TaggedTemplateExpression */:
                case 211 /* TemplateExpression */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 8 /* NumericLiteral */:
                case 9 /* BigIntLiteral */:
                case 106 /* TrueKeyword */:
                case 91 /* FalseKeyword */:
                case 100 /* NullKeyword */:
                case 146 /* UndefinedKeyword */:
                case 201 /* FunctionExpression */:
                case 214 /* ClassExpression */:
                case 202 /* ArrowFunction */:
                case 192 /* ArrayLiteralExpression */:
                case 193 /* ObjectLiteralExpression */:
                case 204 /* TypeOfExpression */:
                case 218 /* NonNullExpression */:
                case 267 /* JsxSelfClosingElement */:
                case 266 /* JsxElement */:
                    return true;
                case 210 /* ConditionalExpression */:
                    return isSideEffectFree(node.whenTrue) &&
                        isSideEffectFree(node.whenFalse);
                case 209 /* BinaryExpression */:
                    if (ts.isAssignmentOperator(node.operatorToken.kind)) {
                        return false;
                    }
                    return isSideEffectFree(node.left) &&
                        isSideEffectFree(node.right);
                case 207 /* PrefixUnaryExpression */:
                case 208 /* PostfixUnaryExpression */:
                    // Unary operators ~, !, +, and - have no side effects.
                    // The rest do.
                    switch (node.operator) {
                        case 53 /* ExclamationToken */:
                        case 39 /* PlusToken */:
                        case 40 /* MinusToken */:
                        case 54 /* TildeToken */:
                            return true;
                    }
                    return false;
                // Some forms listed here for clarity
                case 205 /* VoidExpression */: // Explicit opt-out
                case 199 /* TypeAssertionExpression */: // Not SEF, but can produce useful type warnings
                case 217 /* AsExpression */: // Not SEF, but can produce useful type warnings
                default:
                    return false;
            }
        }
        function isTypeEqualityComparableTo(source, target) {
            return (target.flags & 98304 /* Nullable */) !== 0 || isTypeComparableTo(source, target);
        }
        var CheckBinaryExpressionState;
        (function (CheckBinaryExpressionState) {
            CheckBinaryExpressionState[CheckBinaryExpressionState["MaybeCheckLeft"] = 0] = "MaybeCheckLeft";
            CheckBinaryExpressionState[CheckBinaryExpressionState["CheckRight"] = 1] = "CheckRight";
            CheckBinaryExpressionState[CheckBinaryExpressionState["FinishCheck"] = 2] = "FinishCheck";
        })(CheckBinaryExpressionState || (CheckBinaryExpressionState = {}));
        function checkBinaryExpression(node, checkMode) {
            var workStacks = {
                expr: [node],
                state: [0 /* MaybeCheckLeft */],
                leftType: [undefined]
            };
            var stackIndex = 0;
            var lastResult;
            while (stackIndex >= 0) {
                node = workStacks.expr[stackIndex];
                switch (workStacks.state[stackIndex]) {
                    case 0 /* MaybeCheckLeft */: {
                        if (ts.isInJSFile(node) && ts.getAssignedExpandoInitializer(node)) {
                            finishInvocation(checkExpression(node.right, checkMode));
                            break;
                        }
                        checkGrammarNullishCoalesceWithLogicalExpression(node);
                        var operator = node.operatorToken.kind;
                        if (operator === 62 /* EqualsToken */ && (node.left.kind === 193 /* ObjectLiteralExpression */ || node.left.kind === 192 /* ArrayLiteralExpression */)) {
                            finishInvocation(checkDestructuringAssignment(node.left, checkExpression(node.right, checkMode), checkMode, node.right.kind === 104 /* ThisKeyword */));
                            break;
                        }
                        advanceState(1 /* CheckRight */);
                        maybeCheckExpression(node.left);
                        break;
                    }
                    case 1 /* CheckRight */: {
                        var leftType = lastResult;
                        workStacks.leftType[stackIndex] = leftType;
                        var operator = node.operatorToken.kind;
                        if (operator === 55 /* AmpersandAmpersandToken */ || operator === 56 /* BarBarToken */ || operator === 60 /* QuestionQuestionToken */) {
                            checkTruthinessOfType(leftType, node.left);
                        }
                        advanceState(2 /* FinishCheck */);
                        maybeCheckExpression(node.right);
                        break;
                    }
                    case 2 /* FinishCheck */: {
                        var leftType = workStacks.leftType[stackIndex];
                        var rightType = lastResult;
                        finishInvocation(checkBinaryLikeExpressionWorker(node.left, node.operatorToken, node.right, leftType, rightType, node));
                        break;
                    }
                    default: return ts.Debug.fail("Invalid state " + workStacks.state[stackIndex] + " for checkBinaryExpression");
                }
            }
            return lastResult;
            function finishInvocation(result) {
                lastResult = result;
                stackIndex--;
            }
            /**
             * Note that `advanceState` sets the _current_ head state, and that `maybeCheckExpression` potentially pushes on a new
             * head state; so `advanceState` must be called before any `maybeCheckExpression` during a state's execution.
             */
            function advanceState(nextState) {
                workStacks.state[stackIndex] = nextState;
            }
            function maybeCheckExpression(node) {
                if (ts.isBinaryExpression(node)) {
                    stackIndex++;
                    workStacks.expr[stackIndex] = node;
                    workStacks.state[stackIndex] = 0 /* MaybeCheckLeft */;
                    workStacks.leftType[stackIndex] = undefined;
                }
                else {
                    lastResult = checkExpression(node, checkMode);
                }
            }
        }
        function checkGrammarNullishCoalesceWithLogicalExpression(node) {
            var left = node.left, operatorToken = node.operatorToken, right = node.right;
            if (operatorToken.kind === 60 /* QuestionQuestionToken */) {
                if (ts.isBinaryExpression(left) && (left.operatorToken.kind === 56 /* BarBarToken */ || left.operatorToken.kind === 55 /* AmpersandAmpersandToken */)) {
                    grammarErrorOnNode(left, ts.Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, ts.tokenToString(left.operatorToken.kind), ts.tokenToString(operatorToken.kind));
                }
                if (ts.isBinaryExpression(right) && (right.operatorToken.kind === 56 /* BarBarToken */ || right.operatorToken.kind === 55 /* AmpersandAmpersandToken */)) {
                    grammarErrorOnNode(right, ts.Diagnostics._0_and_1_operations_cannot_be_mixed_without_parentheses, ts.tokenToString(right.operatorToken.kind), ts.tokenToString(operatorToken.kind));
                }
            }
        }
        // Note that this and `checkBinaryExpression` above should behave mostly the same, except this elides some
        // expression-wide checks and does not use a work stack to fold nested binary expressions into the same callstack frame
        function checkBinaryLikeExpression(left, operatorToken, right, checkMode, errorNode) {
            var operator = operatorToken.kind;
            if (operator === 62 /* EqualsToken */ && (left.kind === 193 /* ObjectLiteralExpression */ || left.kind === 192 /* ArrayLiteralExpression */)) {
                return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode, right.kind === 104 /* ThisKeyword */);
            }
            var leftType;
            if (operator === 55 /* AmpersandAmpersandToken */ || operator === 56 /* BarBarToken */ || operator === 60 /* QuestionQuestionToken */) {
                leftType = checkTruthinessExpression(left, checkMode);
            }
            else {
                leftType = checkExpression(left, checkMode);
            }
            var rightType = checkExpression(right, checkMode);
            return checkBinaryLikeExpressionWorker(left, operatorToken, right, leftType, rightType, errorNode);
        }
        function checkBinaryLikeExpressionWorker(left, operatorToken, right, leftType, rightType, errorNode) {
            var operator = operatorToken.kind;
            switch (operator) {
                case 41 /* AsteriskToken */:
                case 42 /* AsteriskAsteriskToken */:
                case 65 /* AsteriskEqualsToken */:
                case 66 /* AsteriskAsteriskEqualsToken */:
                case 43 /* SlashToken */:
                case 67 /* SlashEqualsToken */:
                case 44 /* PercentToken */:
                case 68 /* PercentEqualsToken */:
                case 40 /* MinusToken */:
                case 64 /* MinusEqualsToken */:
                case 47 /* LessThanLessThanToken */:
                case 69 /* LessThanLessThanEqualsToken */:
                case 48 /* GreaterThanGreaterThanToken */:
                case 70 /* GreaterThanGreaterThanEqualsToken */:
                case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                case 51 /* BarToken */:
                case 73 /* BarEqualsToken */:
                case 52 /* CaretToken */:
                case 74 /* CaretEqualsToken */:
                case 50 /* AmpersandToken */:
                case 72 /* AmpersandEqualsToken */:
                    if (leftType === silentNeverType || rightType === silentNeverType) {
                        return silentNeverType;
                    }
                    leftType = checkNonNullType(leftType, left);
                    rightType = checkNonNullType(rightType, right);
                    var suggestedOperator = void 0;
                    // if a user tries to apply a bitwise operator to 2 boolean operands
                    // try and return them a helpful suggestion
                    if ((leftType.flags & 528 /* BooleanLike */) &&
                        (rightType.flags & 528 /* BooleanLike */) &&
                        (suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) {
                        error(errorNode || operatorToken, ts.Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, ts.tokenToString(operatorToken.kind), ts.tokenToString(suggestedOperator));
                        return numberType;
                    }
                    else {
                        // otherwise just check each operand separately and report errors as normal
                        var leftOk = checkArithmeticOperandType(left, leftType, ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true);
                        var rightOk = checkArithmeticOperandType(right, rightType, ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_bigint_or_an_enum_type, /*isAwaitValid*/ true);
                        var resultType_1;
                        // If both are any or unknown, allow operation; assume it will resolve to number
                        if ((isTypeAssignableToKind(leftType, 3 /* AnyOrUnknown */) && isTypeAssignableToKind(rightType, 3 /* AnyOrUnknown */)) ||
                            // Or, if neither could be bigint, implicit coercion results in a number result
                            !(maybeTypeOfKind(leftType, 2112 /* BigIntLike */) || maybeTypeOfKind(rightType, 2112 /* BigIntLike */))) {
                            resultType_1 = numberType;
                        }
                        // At least one is assignable to bigint, so check that both are
                        else if (bothAreBigIntLike(leftType, rightType)) {
                            switch (operator) {
                                case 49 /* GreaterThanGreaterThanGreaterThanToken */:
                                case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */:
                                    reportOperatorError();
                            }
                            resultType_1 = bigintType;
                        }
                        // Exactly one of leftType/rightType is assignable to bigint
                        else {
                            reportOperatorError(bothAreBigIntLike);
                            resultType_1 = errorType;
                        }
                        if (leftOk && rightOk) {
                            checkAssignmentOperator(resultType_1);
                        }
                        return resultType_1;
                    }
                case 39 /* PlusToken */:
                case 63 /* PlusEqualsToken */:
                    if (leftType === silentNeverType || rightType === silentNeverType) {
                        return silentNeverType;
                    }
                    if (!isTypeAssignableToKind(leftType, 132 /* StringLike */) && !isTypeAssignableToKind(rightType, 132 /* StringLike */)) {
                        leftType = checkNonNullType(leftType, left);
                        rightType = checkNonNullType(rightType, right);
                    }
                    var resultType = void 0;
                    if (isTypeAssignableToKind(leftType, 296 /* NumberLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 296 /* NumberLike */, /*strict*/ true)) {
                        // Operands of an enum type are treated as having the primitive type Number.
                        // If both operands are of the Number primitive type, the result is of the Number primitive type.
                        resultType = numberType;
                    }
                    else if (isTypeAssignableToKind(leftType, 2112 /* BigIntLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 2112 /* BigIntLike */, /*strict*/ true)) {
                        // If both operands are of the BigInt primitive type, the result is of the BigInt primitive type.
                        resultType = bigintType;
                    }
                    else if (isTypeAssignableToKind(leftType, 132 /* StringLike */, /*strict*/ true) || isTypeAssignableToKind(rightType, 132 /* StringLike */, /*strict*/ true)) {
                        // If one or both operands are of the String primitive type, the result is of the String primitive type.
                        resultType = stringType;
                    }
                    else if (isTypeAny(leftType) || isTypeAny(rightType)) {
                        // Otherwise, the result is of type Any.
                        // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we.
                        resultType = leftType === errorType || rightType === errorType ? errorType : anyType;
                    }
                    // Symbols are not allowed at all in arithmetic expressions
                    if (resultType && !checkForDisallowedESSymbolOperand(operator)) {
                        return resultType;
                    }
                    if (!resultType) {
                        // Types that have a reasonably good chance of being a valid operand type.
                        // If both types have an awaited type of one of these, we'll assume the user
                        // might be missing an await without doing an exhaustive check that inserting
                        // await(s) will actually be a completely valid binary expression.
                        var closeEnoughKind_1 = 296 /* NumberLike */ | 2112 /* BigIntLike */ | 132 /* StringLike */ | 3 /* AnyOrUnknown */;
                        reportOperatorError(function (left, right) {
                            return isTypeAssignableToKind(left, closeEnoughKind_1) &&
                                isTypeAssignableToKind(right, closeEnoughKind_1);
                        });
                        return anyType;
                    }
                    if (operator === 63 /* PlusEqualsToken */) {
                        checkAssignmentOperator(resultType);
                    }
                    return resultType;
                case 29 /* LessThanToken */:
                case 31 /* GreaterThanToken */:
                case 32 /* LessThanEqualsToken */:
                case 33 /* GreaterThanEqualsToken */:
                    if (checkForDisallowedESSymbolOperand(operator)) {
                        leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left));
                        rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right));
                        reportOperatorErrorUnless(function (left, right) {
                            return isTypeComparableTo(left, right) || isTypeComparableTo(right, left) || (isTypeAssignableTo(left, numberOrBigIntType) && isTypeAssignableTo(right, numberOrBigIntType));
                        });
                    }
                    return booleanType;
                case 34 /* EqualsEqualsToken */:
                case 35 /* ExclamationEqualsToken */:
                case 36 /* EqualsEqualsEqualsToken */:
                case 37 /* ExclamationEqualsEqualsToken */:
                    reportOperatorErrorUnless(function (left, right) { return isTypeEqualityComparableTo(left, right) || isTypeEqualityComparableTo(right, left); });
                    return booleanType;
                case 98 /* InstanceOfKeyword */:
                    return checkInstanceOfExpression(left, right, leftType, rightType);
                case 97 /* InKeyword */:
                    return checkInExpression(left, right, leftType, rightType);
                case 55 /* AmpersandAmpersandToken */:
                    return getTypeFacts(leftType) & 4194304 /* Truthy */ ?
                        getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) :
                        leftType;
                case 56 /* BarBarToken */:
                    return getTypeFacts(leftType) & 8388608 /* Falsy */ ?
                        getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], 2 /* Subtype */) :
                        leftType;
                case 60 /* QuestionQuestionToken */:
                    return getTypeFacts(leftType) & 262144 /* EQUndefinedOrNull */ ?
                        getUnionType([getNonNullableType(leftType), rightType], 2 /* Subtype */) :
                        leftType;
                case 62 /* EqualsToken */:
                    var declKind = ts.isBinaryExpression(left.parent) ? ts.getAssignmentDeclarationKind(left.parent) : 0 /* None */;
                    checkAssignmentDeclaration(declKind, rightType);
                    if (isAssignmentDeclaration(declKind)) {
                        if (!(rightType.flags & 524288 /* Object */) ||
                            declKind !== 2 /* ModuleExports */ &&
                                declKind !== 6 /* Prototype */ &&
                                !isEmptyObjectType(rightType) &&
                                !isFunctionObjectType(rightType) &&
                                !(ts.getObjectFlags(rightType) & 1 /* Class */)) {
                            // don't check assignability of module.exports=, C.prototype=, or expando types because they will necessarily be incomplete
                            checkAssignmentOperator(rightType);
                        }
                        return leftType;
                    }
                    else {
                        checkAssignmentOperator(rightType);
                        return getRegularTypeOfObjectLiteral(rightType);
                    }
                case 27 /* CommaToken */:
                    if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left) && !isEvalNode(right)) {
                        error(left, ts.Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects);
                    }
                    return rightType;
                default:
                    return ts.Debug.fail();
            }
            function bothAreBigIntLike(left, right) {
                return isTypeAssignableToKind(left, 2112 /* BigIntLike */) && isTypeAssignableToKind(right, 2112 /* BigIntLike */);
            }
            function checkAssignmentDeclaration(kind, rightType) {
                if (kind === 2 /* ModuleExports */) {
                    for (var _i = 0, _a = getPropertiesOfObjectType(rightType); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        var propType = getTypeOfSymbol(prop);
                        if (propType.symbol && propType.symbol.flags & 32 /* Class */) {
                            var name = prop.escapedName;
                            var symbol = resolveName(prop.valueDeclaration, name, 788968 /* Type */, undefined, name, /*isUse*/ false);
                            if (symbol && symbol.declarations.some(ts.isJSDocTypedefTag)) {
                                addDuplicateDeclarationErrorsForSymbols(symbol, ts.Diagnostics.Duplicate_identifier_0, ts.unescapeLeadingUnderscores(name), prop);
                                addDuplicateDeclarationErrorsForSymbols(prop, ts.Diagnostics.Duplicate_identifier_0, ts.unescapeLeadingUnderscores(name), symbol);
                            }
                        }
                    }
                }
            }
            function isEvalNode(node) {
                return node.kind === 75 /* Identifier */ && node.escapedText === "eval";
            }
            // Return true if there was no error, false if there was an error.
            function checkForDisallowedESSymbolOperand(operator) {
                var offendingSymbolOperand = maybeTypeOfKind(leftType, 12288 /* ESSymbolLike */) ? left :
                    maybeTypeOfKind(rightType, 12288 /* ESSymbolLike */) ? right :
                        undefined;
                if (offendingSymbolOperand) {
                    error(offendingSymbolOperand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(operator));
                    return false;
                }
                return true;
            }
            function getSuggestedBooleanOperator(operator) {
                switch (operator) {
                    case 51 /* BarToken */:
                    case 73 /* BarEqualsToken */:
                        return 56 /* BarBarToken */;
                    case 52 /* CaretToken */:
                    case 74 /* CaretEqualsToken */:
                        return 37 /* ExclamationEqualsEqualsToken */;
                    case 50 /* AmpersandToken */:
                    case 72 /* AmpersandEqualsToken */:
                        return 55 /* AmpersandAmpersandToken */;
                    default:
                        return undefined;
                }
            }
            function checkAssignmentOperator(valueType) {
                if (produceDiagnostics && ts.isAssignmentOperator(operator)) {
                    // TypeScript 1.0 spec (April 2014): 4.17
                    // An assignment of the form
                    //    VarExpr = ValueExpr
                    // requires VarExpr to be classified as a reference
                    // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
                    // and the type of the non-compound operation to be assignable to the type of VarExpr.
                    if (checkReferenceExpression(left, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_may_not_be_an_optional_property_access)
                        && (!ts.isIdentifier(left) || ts.unescapeLeadingUnderscores(left.escapedText) !== "exports")) {
                        // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported
                        checkTypeAssignableToAndOptionallyElaborate(valueType, leftType, left, right);
                    }
                }
            }
            function isAssignmentDeclaration(kind) {
                switch (kind) {
                    case 2 /* ModuleExports */:
                        return true;
                    case 1 /* ExportsProperty */:
                    case 5 /* Property */:
                    case 6 /* Prototype */:
                    case 3 /* PrototypeProperty */:
                    case 4 /* ThisProperty */:
                        var symbol = getSymbolOfNode(left);
                        var init = ts.getAssignedExpandoInitializer(right);
                        return init && ts.isObjectLiteralExpression(init) &&
                            symbol && ts.hasEntries(symbol.exports);
                    default:
                        return false;
                }
            }
            /**
             * Returns true if an error is reported
             */
            function reportOperatorErrorUnless(typesAreCompatible) {
                if (!typesAreCompatible(leftType, rightType)) {
                    reportOperatorError(typesAreCompatible);
                    return true;
                }
                return false;
            }
            function reportOperatorError(isRelated) {
                var _a;
                var wouldWorkWithAwait = false;
                var errNode = errorNode || operatorToken;
                if (isRelated) {
                    var awaitedLeftType = getAwaitedType(leftType);
                    var awaitedRightType = getAwaitedType(rightType);
                    wouldWorkWithAwait = !(awaitedLeftType === leftType && awaitedRightType === rightType)
                        && !!(awaitedLeftType && awaitedRightType)
                        && isRelated(awaitedLeftType, awaitedRightType);
                }
                var effectiveLeft = leftType;
                var effectiveRight = rightType;
                if (!wouldWorkWithAwait && isRelated) {
                    _a = getBaseTypesIfUnrelated(leftType, rightType, isRelated), effectiveLeft = _a[0], effectiveRight = _a[1];
                }
                var _b = getTypeNamesForErrorDisplay(effectiveLeft, effectiveRight), leftStr = _b[0], rightStr = _b[1];
                if (!tryGiveBetterPrimaryError(errNode, wouldWorkWithAwait, leftStr, rightStr)) {
                    errorAndMaybeSuggestAwait(errNode, wouldWorkWithAwait, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(operatorToken.kind), leftStr, rightStr);
                }
            }
            function tryGiveBetterPrimaryError(errNode, maybeMissingAwait, leftStr, rightStr) {
                var typeName;
                switch (operatorToken.kind) {
                    case 36 /* EqualsEqualsEqualsToken */:
                    case 34 /* EqualsEqualsToken */:
                        typeName = "false";
                        break;
                    case 37 /* ExclamationEqualsEqualsToken */:
                    case 35 /* ExclamationEqualsToken */:
                        typeName = "true";
                }
                if (typeName) {
                    return errorAndMaybeSuggestAwait(errNode, maybeMissingAwait, ts.Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, typeName, leftStr, rightStr);
                }
                return undefined;
            }
        }
        function getBaseTypesIfUnrelated(leftType, rightType, isRelated) {
            var effectiveLeft = leftType;
            var effectiveRight = rightType;
            var leftBase = getBaseTypeOfLiteralType(leftType);
            var rightBase = getBaseTypeOfLiteralType(rightType);
            if (!isRelated(leftBase, rightBase)) {
                effectiveLeft = leftBase;
                effectiveRight = rightBase;
            }
            return [effectiveLeft, effectiveRight];
        }
        function checkYieldExpression(node) {
            // Grammar checking
            if (produceDiagnostics) {
                if (!(node.flags & 8192 /* YieldContext */)) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body);
                }
                if (isInParameterInitializerBeforeContainingFunction(node)) {
                    error(node, ts.Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer);
                }
            }
            var func = ts.getContainingFunction(node);
            if (!func)
                return anyType;
            var functionFlags = ts.getFunctionFlags(func);
            if (!(functionFlags & 1 /* Generator */)) {
                // If the user's code is syntactically correct, the func should always have a star. After all, we are in a yield context.
                return anyType;
            }
            var isAsync = (functionFlags & 2 /* Async */) !== 0;
            if (node.asteriskToken) {
                // Async generator functions prior to ESNext require the __await, __asyncDelegator,
                // and __asyncValues helpers
                if (isAsync && languageVersion < 99 /* ESNext */) {
                    checkExternalEmitHelpers(node, 53248 /* AsyncDelegatorIncludes */);
                }
                // Generator functions prior to ES2015 require the __values helper
                if (!isAsync && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                    checkExternalEmitHelpers(node, 256 /* Values */);
                }
            }
            // There is no point in doing an assignability check if the function
            // has no explicit return type because the return type is directly computed
            // from the yield expressions.
            var returnType = getReturnTypeFromAnnotation(func);
            var iterationTypes = returnType && getIterationTypesOfGeneratorFunctionReturnType(returnType, isAsync);
            var signatureYieldType = iterationTypes && iterationTypes.yieldType || anyType;
            var signatureNextType = iterationTypes && iterationTypes.nextType || anyType;
            var resolvedSignatureNextType = isAsync ? getAwaitedType(signatureNextType) || anyType : signatureNextType;
            var yieldExpressionType = node.expression ? checkExpression(node.expression) : undefinedWideningType;
            var yieldedType = getYieldedTypeOfYieldExpression(node, yieldExpressionType, resolvedSignatureNextType, isAsync);
            if (returnType && yieldedType) {
                checkTypeAssignableToAndOptionallyElaborate(yieldedType, signatureYieldType, node.expression || node, node.expression);
            }
            if (node.asteriskToken) {
                var use = isAsync ? 19 /* AsyncYieldStar */ : 17 /* YieldStar */;
                return getIterationTypeOfIterable(use, 1 /* Return */, yieldExpressionType, node.expression)
                    || anyType;
            }
            else if (returnType) {
                return getIterationTypeOfGeneratorFunctionReturnType(2 /* Next */, returnType, isAsync)
                    || anyType;
            }
            return getContextualIterationType(2 /* Next */, func) || anyType;
        }
        function checkConditionalExpression(node, checkMode) {
            var type = checkTruthinessExpression(node.condition);
            checkTestingKnownTruthyCallableType(node.condition, node.whenTrue, type);
            var type1 = checkExpression(node.whenTrue, checkMode);
            var type2 = checkExpression(node.whenFalse, checkMode);
            return getUnionType([type1, type2], 2 /* Subtype */);
        }
        function checkTemplateExpression(node) {
            // We just want to check each expressions, but we are unconcerned with
            // the type of each expression, as any value may be coerced into a string.
            // It is worth asking whether this is what we really want though.
            // A place where we actually *are* concerned with the expressions' types are
            // in tagged templates.
            ts.forEach(node.templateSpans, function (templateSpan) {
                if (maybeTypeOfKind(checkExpression(templateSpan.expression), 12288 /* ESSymbolLike */)) {
                    error(templateSpan.expression, ts.Diagnostics.Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String);
                }
            });
            return stringType;
        }
        function getContextNode(node) {
            if (node.kind === 274 /* JsxAttributes */ && !ts.isJsxSelfClosingElement(node.parent)) {
                return node.parent.parent; // Needs to be the root JsxElement, so it encompasses the attributes _and_ the children (which are essentially part of the attributes)
            }
            return node;
        }
        function checkExpressionWithContextualType(node, contextualType, inferenceContext, checkMode) {
            var context = getContextNode(node);
            var saveContextualType = context.contextualType;
            var saveInferenceContext = context.inferenceContext;
            try {
                context.contextualType = contextualType;
                context.inferenceContext = inferenceContext;
                var type = checkExpression(node, checkMode | 1 /* Contextual */ | (inferenceContext ? 2 /* Inferential */ : 0));
                // We strip literal freshness when an appropriate contextual type is present such that contextually typed
                // literals always preserve their literal types (otherwise they might widen during type inference). An alternative
                // here would be to not mark contextually typed literals as fresh in the first place.
                var result = maybeTypeOfKind(type, 2944 /* Literal */) && isLiteralOfContextualType(type, instantiateContextualType(contextualType, node)) ?
                    getRegularTypeOfLiteralType(type) : type;
                return result;
            }
            finally {
                // In the event our operation is canceled or some other exception occurs, reset the contextual type
                // so that we do not accidentally hold onto an instance of the checker, as a Type created in the services layer
                // may hold onto the checker that created it.
                context.contextualType = saveContextualType;
                context.inferenceContext = saveInferenceContext;
            }
        }
        function checkExpressionCached(node, checkMode) {
            var links = getNodeLinks(node);
            if (!links.resolvedType) {
                if (checkMode && checkMode !== 0 /* Normal */) {
                    return checkExpression(node, checkMode);
                }
                // When computing a type that we're going to cache, we need to ignore any ongoing control flow
                // analysis because variables may have transient types in indeterminable states. Moving flowLoopStart
                // to the top of the stack ensures all transient types are computed from a known point.
                var saveFlowLoopStart = flowLoopStart;
                var saveFlowTypeCache = flowTypeCache;
                flowLoopStart = flowLoopCount;
                flowTypeCache = undefined;
                links.resolvedType = checkExpression(node, checkMode);
                flowTypeCache = saveFlowTypeCache;
                flowLoopStart = saveFlowLoopStart;
            }
            return links.resolvedType;
        }
        function isTypeAssertion(node) {
            node = ts.skipParentheses(node);
            return node.kind === 199 /* TypeAssertionExpression */ || node.kind === 217 /* AsExpression */;
        }
        function checkDeclarationInitializer(declaration, contextualType) {
            var initializer = ts.getEffectiveInitializer(declaration);
            var type = getQuickTypeOfExpression(initializer) ||
                (contextualType ? checkExpressionWithContextualType(initializer, contextualType, /*inferenceContext*/ undefined, 0 /* Normal */) : checkExpressionCached(initializer));
            return ts.isParameter(declaration) && declaration.name.kind === 190 /* ArrayBindingPattern */ &&
                isTupleType(type) && !type.target.hasRestElement && getTypeReferenceArity(type) < declaration.name.elements.length ?
                padTupleType(type, declaration.name) : type;
        }
        function padTupleType(type, pattern) {
            var patternElements = pattern.elements;
            var arity = getTypeReferenceArity(type);
            var elementTypes = arity ? getTypeArguments(type).slice() : [];
            for (var i = arity; i < patternElements.length; i++) {
                var e = patternElements[i];
                if (i < patternElements.length - 1 || !(e.kind === 191 /* BindingElement */ && e.dotDotDotToken)) {
                    elementTypes.push(!ts.isOmittedExpression(e) && hasDefaultValue(e) ? getTypeFromBindingElement(e, /*includePatternInType*/ false, /*reportErrors*/ false) : anyType);
                    if (!ts.isOmittedExpression(e) && !hasDefaultValue(e)) {
                        reportImplicitAny(e, anyType);
                    }
                }
            }
            return createTupleType(elementTypes, type.target.minLength, /*hasRestElement*/ false, type.target.readonly);
        }
        function widenTypeInferredFromInitializer(declaration, type) {
            var widened = ts.getCombinedNodeFlags(declaration) & 2 /* Const */ || ts.isDeclarationReadonly(declaration) ? type : getWidenedLiteralType(type);
            if (ts.isInJSFile(declaration)) {
                if (widened.flags & 98304 /* Nullable */) {
                    reportImplicitAny(declaration, anyType);
                    return anyType;
                }
                else if (isEmptyArrayLiteralType(widened)) {
                    reportImplicitAny(declaration, anyArrayType);
                    return anyArrayType;
                }
            }
            return widened;
        }
        function isLiteralOfContextualType(candidateType, contextualType) {
            if (contextualType) {
                if (contextualType.flags & 3145728 /* UnionOrIntersection */) {
                    var types = contextualType.types;
                    return ts.some(types, function (t) { return isLiteralOfContextualType(candidateType, t); });
                }
                if (contextualType.flags & 58982400 /* InstantiableNonPrimitive */) {
                    // If the contextual type is a type variable constrained to a primitive type, consider
                    // this a literal context for literals of that primitive type. For example, given a
                    // type parameter 'T extends string', infer string literal types for T.
                    var constraint = getBaseConstraintOfType(contextualType) || unknownType;
                    return maybeTypeOfKind(constraint, 4 /* String */) && maybeTypeOfKind(candidateType, 128 /* StringLiteral */) ||
                        maybeTypeOfKind(constraint, 8 /* Number */) && maybeTypeOfKind(candidateType, 256 /* NumberLiteral */) ||
                        maybeTypeOfKind(constraint, 64 /* BigInt */) && maybeTypeOfKind(candidateType, 2048 /* BigIntLiteral */) ||
                        maybeTypeOfKind(constraint, 4096 /* ESSymbol */) && maybeTypeOfKind(candidateType, 8192 /* UniqueESSymbol */) ||
                        isLiteralOfContextualType(candidateType, constraint);
                }
                // If the contextual type is a literal of a particular primitive type, we consider this a
                // literal context for all literals of that primitive type.
                return !!(contextualType.flags & (128 /* StringLiteral */ | 4194304 /* Index */) && maybeTypeOfKind(candidateType, 128 /* StringLiteral */) ||
                    contextualType.flags & 256 /* NumberLiteral */ && maybeTypeOfKind(candidateType, 256 /* NumberLiteral */) ||
                    contextualType.flags & 2048 /* BigIntLiteral */ && maybeTypeOfKind(candidateType, 2048 /* BigIntLiteral */) ||
                    contextualType.flags & 512 /* BooleanLiteral */ && maybeTypeOfKind(candidateType, 512 /* BooleanLiteral */) ||
                    contextualType.flags & 8192 /* UniqueESSymbol */ && maybeTypeOfKind(candidateType, 8192 /* UniqueESSymbol */));
            }
            return false;
        }
        function isConstContext(node) {
            var parent = node.parent;
            return ts.isAssertionExpression(parent) && ts.isConstTypeReference(parent.type) ||
                (ts.isParenthesizedExpression(parent) || ts.isArrayLiteralExpression(parent) || ts.isSpreadElement(parent)) && isConstContext(parent) ||
                (ts.isPropertyAssignment(parent) || ts.isShorthandPropertyAssignment(parent)) && isConstContext(parent.parent);
        }
        function checkExpressionForMutableLocation(node, checkMode, contextualType, forceTuple) {
            var type = checkExpression(node, checkMode, forceTuple);
            return isConstContext(node) ? getRegularTypeOfLiteralType(type) :
                isTypeAssertion(node) ? type :
                    getWidenedLiteralLikeTypeForContextualType(type, instantiateContextualType(arguments.length === 2 ? getContextualType(node) : contextualType, node));
        }
        function checkPropertyAssignment(node, checkMode) {
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 154 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            return checkExpressionForMutableLocation(node.initializer, checkMode);
        }
        function checkObjectLiteralMethod(node, checkMode) {
            // Grammar checking
            checkGrammarMethod(node);
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 154 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
            }
            var uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
            return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
        }
        function instantiateTypeWithSingleGenericCallSignature(node, type, checkMode) {
            if (checkMode && checkMode & (2 /* Inferential */ | 8 /* SkipGenericFunctions */)) {
                var callSignature = getSingleSignature(type, 0 /* Call */, /*allowMembers*/ true);
                var constructSignature = getSingleSignature(type, 1 /* Construct */, /*allowMembers*/ true);
                var signature = callSignature || constructSignature;
                if (signature && signature.typeParameters) {
                    var contextualType = getApparentTypeOfContextualType(node, 2 /* NoConstraints */);
                    if (contextualType) {
                        var contextualSignature = getSingleSignature(getNonNullableType(contextualType), callSignature ? 0 /* Call */ : 1 /* Construct */, /*allowMembers*/ false);
                        if (contextualSignature && !contextualSignature.typeParameters) {
                            if (checkMode & 8 /* SkipGenericFunctions */) {
                                skippedGenericFunction(node, checkMode);
                                return anyFunctionType;
                            }
                            var context = getInferenceContext(node);
                            // We have an expression that is an argument of a generic function for which we are performing
                            // type argument inference. The expression is of a function type with a single generic call
                            // signature and a contextual function type with a single non-generic call signature. Now check
                            // if the outer function returns a function type with a single non-generic call signature and
                            // if some of the outer function type parameters have no inferences so far. If so, we can
                            // potentially add inferred type parameters to the outer function return type.
                            var returnType = context.signature && getReturnTypeOfSignature(context.signature);
                            var returnSignature = returnType && getSingleCallOrConstructSignature(returnType);
                            if (returnSignature && !returnSignature.typeParameters && !ts.every(context.inferences, hasInferenceCandidates)) {
                                // Instantiate the signature with its own type parameters as type arguments, possibly
                                // renaming the type parameters to ensure they have unique names.
                                var uniqueTypeParameters = getUniqueTypeParameters(context, signature.typeParameters);
                                var instantiatedSignature = getSignatureInstantiationWithoutFillingInTypeArguments(signature, uniqueTypeParameters);
                                // Infer from the parameters of the instantiated signature to the parameters of the
                                // contextual signature starting with an empty set of inference candidates.
                                var inferences_3 = ts.map(context.inferences, function (info) { return createInferenceInfo(info.typeParameter); });
                                applyToParameterTypes(instantiatedSignature, contextualSignature, function (source, target) {
                                    inferTypes(inferences_3, source, target, /*priority*/ 0, /*contravariant*/ true);
                                });
                                if (ts.some(inferences_3, hasInferenceCandidates)) {
                                    // We have inference candidates, indicating that one or more type parameters are referenced
                                    // in the parameter types of the contextual signature. Now also infer from the return type.
                                    applyToReturnTypes(instantiatedSignature, contextualSignature, function (source, target) {
                                        inferTypes(inferences_3, source, target);
                                    });
                                    // If the type parameters for which we produced candidates do not have any inferences yet,
                                    // we adopt the new inference candidates and add the type parameters of the expression type
                                    // to the set of inferred type parameters for the outer function return type.
                                    if (!hasOverlappingInferences(context.inferences, inferences_3)) {
                                        mergeInferences(context.inferences, inferences_3);
                                        context.inferredTypeParameters = ts.concatenate(context.inferredTypeParameters, uniqueTypeParameters);
                                        return getOrCreateTypeFromSignature(instantiatedSignature);
                                    }
                                }
                            }
                            return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, context));
                        }
                    }
                }
            }
            return type;
        }
        function skippedGenericFunction(node, checkMode) {
            if (checkMode & 2 /* Inferential */) {
                // We have skipped a generic function during inferential typing. Obtain the inference context and
                // indicate this has occurred such that we know a second pass of inference is be needed.
                var context = getInferenceContext(node);
                context.flags |= 4 /* SkippedGenericFunction */;
            }
        }
        function hasInferenceCandidates(info) {
            return !!(info.candidates || info.contraCandidates);
        }
        function hasOverlappingInferences(a, b) {
            for (var i = 0; i < a.length; i++) {
                if (hasInferenceCandidates(a[i]) && hasInferenceCandidates(b[i])) {
                    return true;
                }
            }
            return false;
        }
        function mergeInferences(target, source) {
            for (var i = 0; i < target.length; i++) {
                if (!hasInferenceCandidates(target[i]) && hasInferenceCandidates(source[i])) {
                    target[i] = source[i];
                }
            }
        }
        function getUniqueTypeParameters(context, typeParameters) {
            var result = [];
            var oldTypeParameters;
            var newTypeParameters;
            for (var _i = 0, typeParameters_2 = typeParameters; _i < typeParameters_2.length; _i++) {
                var tp = typeParameters_2[_i];
                var name = tp.symbol.escapedName;
                if (hasTypeParameterByName(context.inferredTypeParameters, name) || hasTypeParameterByName(result, name)) {
                    var newName = getUniqueTypeParameterName(ts.concatenate(context.inferredTypeParameters, result), name);
                    var symbol = createSymbol(262144 /* TypeParameter */, newName);
                    var newTypeParameter = createTypeParameter(symbol);
                    newTypeParameter.target = tp;
                    oldTypeParameters = ts.append(oldTypeParameters, tp);
                    newTypeParameters = ts.append(newTypeParameters, newTypeParameter);
                    result.push(newTypeParameter);
                }
                else {
                    result.push(tp);
                }
            }
            if (newTypeParameters) {
                var mapper = createTypeMapper(oldTypeParameters, newTypeParameters);
                for (var _a = 0, newTypeParameters_1 = newTypeParameters; _a < newTypeParameters_1.length; _a++) {
                    var tp = newTypeParameters_1[_a];
                    tp.mapper = mapper;
                }
            }
            return result;
        }
        function hasTypeParameterByName(typeParameters, name) {
            return ts.some(typeParameters, function (tp) { return tp.symbol.escapedName === name; });
        }
        function getUniqueTypeParameterName(typeParameters, baseName) {
            var len = baseName.length;
            while (len > 1 && baseName.charCodeAt(len - 1) >= 48 /* _0 */ && baseName.charCodeAt(len - 1) <= 57 /* _9 */)
                len--;
            var s = baseName.slice(0, len);
            for (var index = 1; true; index++) {
                var augmentedName = (s + index);
                if (!hasTypeParameterByName(typeParameters, augmentedName)) {
                    return augmentedName;
                }
            }
        }
        function getReturnTypeOfSingleNonGenericCallSignature(funcType) {
            var signature = getSingleCallSignature(funcType);
            if (signature && !signature.typeParameters) {
                return getReturnTypeOfSignature(signature);
            }
        }
        function getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) {
            var funcType = checkExpression(expr.expression);
            var nonOptionalType = getOptionalExpressionType(funcType, expr.expression);
            var returnType = getReturnTypeOfSingleNonGenericCallSignature(funcType);
            return returnType && propagateOptionalTypeMarker(returnType, expr, nonOptionalType !== funcType);
        }
        /**
         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
         * with computing the type and may not fully check all contained sub-expressions for errors.
         */
        function getTypeOfExpression(node) {
            // Don't bother caching types that require no flow analysis and are quick to compute.
            var quickType = getQuickTypeOfExpression(node);
            if (quickType) {
                return quickType;
            }
            // If a type has been cached for the node, return it.
            if (node.flags & 67108864 /* TypeCached */ && flowTypeCache) {
                var cachedType = flowTypeCache[getNodeId(node)];
                if (cachedType) {
                    return cachedType;
                }
            }
            var startInvocationCount = flowInvocationCount;
            var type = checkExpression(node);
            // If control flow analysis was required to determine the type, it is worth caching.
            if (flowInvocationCount !== startInvocationCount) {
                var cache = flowTypeCache || (flowTypeCache = []);
                cache[getNodeId(node)] = type;
                node.flags |= 67108864 /* TypeCached */;
            }
            return type;
        }
        function getQuickTypeOfExpression(node) {
            var expr = ts.skipParentheses(node);
            // Optimize for the common case of a call to a function with a single non-generic call
            // signature where we can just fetch the return type without checking the arguments.
            if (ts.isCallExpression(expr) && expr.expression.kind !== 102 /* SuperKeyword */ && !ts.isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
                var type = ts.isCallChain(expr) ? getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) :
                    getReturnTypeOfSingleNonGenericCallSignature(checkNonNullExpression(expr.expression));
                if (type) {
                    return type;
                }
            }
            else if (ts.isAssertionExpression(expr) && !ts.isConstTypeReference(expr.type)) {
                return getTypeFromTypeNode(expr.type);
            }
            else if (node.kind === 8 /* NumericLiteral */ || node.kind === 10 /* StringLiteral */ ||
                node.kind === 106 /* TrueKeyword */ || node.kind === 91 /* FalseKeyword */) {
                return checkExpression(node);
            }
            return undefined;
        }
        /**
         * Returns the type of an expression. Unlike checkExpression, this function is simply concerned
         * with computing the type and may not fully check all contained sub-expressions for errors.
         * It is intended for uses where you know there is no contextual type,
         * and requesting the contextual type might cause a circularity or other bad behaviour.
         * It sets the contextual type of the node to any before calling getTypeOfExpression.
         */
        function getContextFreeTypeOfExpression(node) {
            var links = getNodeLinks(node);
            if (links.contextFreeType) {
                return links.contextFreeType;
            }
            var saveContextualType = node.contextualType;
            node.contextualType = anyType;
            try {
                var type = links.contextFreeType = checkExpression(node, 4 /* SkipContextSensitive */);
                return type;
            }
            finally {
                // In the event our operation is canceled or some other exception occurs, reset the contextual type
                // so that we do not accidentally hold onto an instance of the checker, as a Type created in the services layer
                // may hold onto the checker that created it.
                node.contextualType = saveContextualType;
            }
        }
        function checkExpression(node, checkMode, forceTuple) {
            var saveCurrentNode = currentNode;
            currentNode = node;
            instantiationCount = 0;
            var uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
            var type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
            if (isConstEnumObjectType(type)) {
                checkConstEnumAccess(node, type);
            }
            currentNode = saveCurrentNode;
            return type;
        }
        function checkConstEnumAccess(node, type) {
            // enum object type for const enums are only permitted in:
            // - 'left' in property access
            // - 'object' in indexed access
            // - target in rhs of import statement
            var ok = (node.parent.kind === 194 /* PropertyAccessExpression */ && node.parent.expression === node) ||
                (node.parent.kind === 195 /* ElementAccessExpression */ && node.parent.expression === node) ||
                ((node.kind === 75 /* Identifier */ || node.kind === 153 /* QualifiedName */) && isInRightSideOfImportOrExportAssignment(node) ||
                    (node.parent.kind === 172 /* TypeQuery */ && node.parent.exprName === node)) ||
                (node.parent.kind === 263 /* ExportSpecifier */); // We allow reexporting const enums
            if (!ok) {
                error(node, ts.Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query);
            }
            if (compilerOptions.isolatedModules) {
                ts.Debug.assert(!!(type.symbol.flags & 128 /* ConstEnum */));
                var constEnumDeclaration = type.symbol.valueDeclaration;
                if (constEnumDeclaration.flags & 8388608 /* Ambient */) {
                    error(node, ts.Diagnostics.Cannot_access_ambient_const_enums_when_the_isolatedModules_flag_is_provided);
                }
            }
        }
        function checkParenthesizedExpression(node, checkMode) {
            var tag = ts.isInJSFile(node) ? ts.getJSDocTypeTag(node) : undefined;
            if (tag) {
                return checkAssertionWorker(tag, tag.typeExpression.type, node.expression, checkMode);
            }
            return checkExpression(node.expression, checkMode);
        }
        function checkExpressionWorker(node, checkMode, forceTuple) {
            var kind = node.kind;
            if (cancellationToken) {
                // Only bother checking on a few construct kinds.  We don't want to be excessively
                // hitting the cancellation token on every node we check.
                switch (kind) {
                    case 214 /* ClassExpression */:
                    case 201 /* FunctionExpression */:
                    case 202 /* ArrowFunction */:
                        cancellationToken.throwIfCancellationRequested();
                }
            }
            switch (kind) {
                case 75 /* Identifier */:
                    return checkIdentifier(node);
                case 104 /* ThisKeyword */:
                    return checkThisExpression(node);
                case 102 /* SuperKeyword */:
                    return checkSuperExpression(node);
                case 100 /* NullKeyword */:
                    return nullWideningType;
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 10 /* StringLiteral */:
                    return getFreshTypeOfLiteralType(getLiteralType(node.text));
                case 8 /* NumericLiteral */:
                    checkGrammarNumericLiteral(node);
                    return getFreshTypeOfLiteralType(getLiteralType(+node.text));
                case 9 /* BigIntLiteral */:
                    checkGrammarBigIntLiteral(node);
                    return getFreshTypeOfLiteralType(getBigIntLiteralType(node));
                case 106 /* TrueKeyword */:
                    return trueType;
                case 91 /* FalseKeyword */:
                    return falseType;
                case 211 /* TemplateExpression */:
                    return checkTemplateExpression(node);
                case 13 /* RegularExpressionLiteral */:
                    return globalRegExpType;
                case 192 /* ArrayLiteralExpression */:
                    return checkArrayLiteral(node, checkMode, forceTuple);
                case 193 /* ObjectLiteralExpression */:
                    return checkObjectLiteral(node, checkMode);
                case 194 /* PropertyAccessExpression */:
                    return checkPropertyAccessExpression(node);
                case 153 /* QualifiedName */:
                    return checkQualifiedName(node);
                case 195 /* ElementAccessExpression */:
                    return checkIndexedAccess(node);
                case 196 /* CallExpression */:
                    if (node.expression.kind === 96 /* ImportKeyword */) {
                        return checkImportCallExpression(node);
                    }
                // falls through
                case 197 /* NewExpression */:
                    return checkCallExpression(node, checkMode);
                case 198 /* TaggedTemplateExpression */:
                    return checkTaggedTemplateExpression(node);
                case 200 /* ParenthesizedExpression */:
                    return checkParenthesizedExpression(node, checkMode);
                case 214 /* ClassExpression */:
                    return checkClassExpression(node);
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return checkFunctionExpressionOrObjectLiteralMethod(node, checkMode);
                case 204 /* TypeOfExpression */:
                    return checkTypeOfExpression(node);
                case 199 /* TypeAssertionExpression */:
                case 217 /* AsExpression */:
                    return checkAssertion(node);
                case 218 /* NonNullExpression */:
                    return checkNonNullAssertion(node);
                case 219 /* MetaProperty */:
                    return checkMetaProperty(node);
                case 203 /* DeleteExpression */:
                    return checkDeleteExpression(node);
                case 205 /* VoidExpression */:
                    return checkVoidExpression(node);
                case 206 /* AwaitExpression */:
                    return checkAwaitExpression(node);
                case 207 /* PrefixUnaryExpression */:
                    return checkPrefixUnaryExpression(node);
                case 208 /* PostfixUnaryExpression */:
                    return checkPostfixUnaryExpression(node);
                case 209 /* BinaryExpression */:
                    return checkBinaryExpression(node, checkMode);
                case 210 /* ConditionalExpression */:
                    return checkConditionalExpression(node, checkMode);
                case 213 /* SpreadElement */:
                    return checkSpreadExpression(node, checkMode);
                case 215 /* OmittedExpression */:
                    return undefinedWideningType;
                case 212 /* YieldExpression */:
                    return checkYieldExpression(node);
                case 220 /* SyntheticExpression */:
                    return node.type;
                case 276 /* JsxExpression */:
                    return checkJsxExpression(node, checkMode);
                case 266 /* JsxElement */:
                    return checkJsxElement(node, checkMode);
                case 267 /* JsxSelfClosingElement */:
                    return checkJsxSelfClosingElement(node, checkMode);
                case 270 /* JsxFragment */:
                    return checkJsxFragment(node);
                case 274 /* JsxAttributes */:
                    return checkJsxAttributes(node, checkMode);
                case 268 /* JsxOpeningElement */:
                    ts.Debug.fail("Shouldn't ever directly check a JsxOpeningElement");
            }
            return errorType;
        }
        // DECLARATION AND STATEMENT TYPE CHECKING
        function checkTypeParameter(node) {
            // Grammar Checking
            if (node.expression) {
                grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected);
            }
            checkSourceElement(node.constraint);
            checkSourceElement(node.default);
            var typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node));
            // Resolve base constraint to reveal circularity errors
            getBaseConstraintOfType(typeParameter);
            if (!hasNonCircularTypeParameterDefault(typeParameter)) {
                error(node.default, ts.Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter));
            }
            var constraintType = getConstraintOfTypeParameter(typeParameter);
            var defaultType = getDefaultFromTypeParameter(typeParameter);
            if (constraintType && defaultType) {
                checkTypeAssignableTo(defaultType, getTypeWithThisArgument(instantiateType(constraintType, makeUnaryTypeMapper(typeParameter, defaultType)), defaultType), node.default, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
            }
            if (produceDiagnostics) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0);
            }
        }
        function checkParameter(node) {
            // Grammar checking
            // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
            // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code
            // or if its FunctionBody is strict code(11.1.5).
            checkGrammarDecoratorsAndModifiers(node);
            checkVariableLikeDeclaration(node);
            var func = ts.getContainingFunction(node);
            if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) {
                if (!(func.kind === 162 /* Constructor */ && ts.nodeIsPresent(func.body))) {
                    error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation);
                }
                if (func.kind === 162 /* Constructor */ && ts.isIdentifier(node.name) && node.name.escapedText === "constructor") {
                    error(node.name, ts.Diagnostics.constructor_cannot_be_used_as_a_parameter_property_name);
                }
            }
            if (node.questionToken && ts.isBindingPattern(node.name) && func.body) {
                error(node, ts.Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature);
            }
            if (node.name && ts.isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) {
                if (func.parameters.indexOf(node) !== 0) {
                    error(node, ts.Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText);
                }
                if (func.kind === 162 /* Constructor */ || func.kind === 166 /* ConstructSignature */ || func.kind === 171 /* ConstructorType */) {
                    error(node, ts.Diagnostics.A_constructor_cannot_have_a_this_parameter);
                }
                if (func.kind === 202 /* ArrowFunction */) {
                    error(node, ts.Diagnostics.An_arrow_function_cannot_have_a_this_parameter);
                }
                if (func.kind === 163 /* GetAccessor */ || func.kind === 164 /* SetAccessor */) {
                    error(node, ts.Diagnostics.get_and_set_accessors_cannot_declare_this_parameters);
                }
            }
            // Only check rest parameter type if it's not a binding pattern. Since binding patterns are
            // not allowed in a rest parameter, we already have an error from checkGrammarParameterList.
            if (node.dotDotDotToken && !ts.isBindingPattern(node.name) && !isTypeAssignableTo(getReducedType(getTypeOfSymbol(node.symbol)), anyReadonlyArrayType)) {
                error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type);
            }
        }
        function checkTypePredicate(node) {
            var parent = getTypePredicateParent(node);
            if (!parent) {
                // The parent must not be valid.
                error(node, ts.Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods);
                return;
            }
            var signature = getSignatureFromDeclaration(parent);
            var typePredicate = getTypePredicateOfSignature(signature);
            if (!typePredicate) {
                return;
            }
            checkSourceElement(node.type);
            var parameterName = node.parameterName;
            if (typePredicate.kind === 0 /* This */ || typePredicate.kind === 2 /* AssertsThis */) {
                getTypeFromThisTypeNode(parameterName);
            }
            else {
                if (typePredicate.parameterIndex >= 0) {
                    if (signatureHasRestParameter(signature) && typePredicate.parameterIndex === signature.parameters.length - 1) {
                        error(parameterName, ts.Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter);
                    }
                    else {
                        if (typePredicate.type) {
                            var leadingError = function () { return ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); };
                            checkTypeAssignableTo(typePredicate.type, getTypeOfSymbol(signature.parameters[typePredicate.parameterIndex]), node.type, 
                            /*headMessage*/ undefined, leadingError);
                        }
                    }
                }
                else if (parameterName) {
                    var hasReportedError = false;
                    for (var _i = 0, _a = parent.parameters; _i < _a.length; _i++) {
                        var name = _a[_i].name;
                        if (ts.isBindingPattern(name) &&
                            checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) {
                            hasReportedError = true;
                            break;
                        }
                    }
                    if (!hasReportedError) {
                        error(node.parameterName, ts.Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName);
                    }
                }
            }
        }
        function getTypePredicateParent(node) {
            switch (node.parent.kind) {
                case 202 /* ArrowFunction */:
                case 165 /* CallSignature */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 170 /* FunctionType */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    var parent = node.parent;
                    if (node === parent.type) {
                        return parent;
                    }
            }
        }
        function checkIfTypePredicateVariableIsDeclaredInBindingPattern(pattern, predicateVariableNode, predicateVariableName) {
            for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (ts.isOmittedExpression(element)) {
                    continue;
                }
                var name = element.name;
                if (name.kind === 75 /* Identifier */ && name.escapedText === predicateVariableName) {
                    error(predicateVariableNode, ts.Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, predicateVariableName);
                    return true;
                }
                else if (name.kind === 190 /* ArrayBindingPattern */ || name.kind === 189 /* ObjectBindingPattern */) {
                    if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, predicateVariableNode, predicateVariableName)) {
                        return true;
                    }
                }
            }
        }
        function checkSignatureDeclaration(node) {
            // Grammar checking
            if (node.kind === 167 /* IndexSignature */) {
                checkGrammarIndexSignature(node);
            }
            // TODO (yuisu): Remove this check in else-if when SyntaxKind.Construct is moved and ambient context is handled
            else if (node.kind === 170 /* FunctionType */ || node.kind === 244 /* FunctionDeclaration */ || node.kind === 171 /* ConstructorType */ ||
                node.kind === 165 /* CallSignature */ || node.kind === 162 /* Constructor */ ||
                node.kind === 166 /* ConstructSignature */) {
                checkGrammarFunctionLikeDeclaration(node);
            }
            var functionFlags = ts.getFunctionFlags(node);
            if (!(functionFlags & 4 /* Invalid */)) {
                // Async generators prior to ESNext require the __await and __asyncGenerator helpers
                if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ && languageVersion < 99 /* ESNext */) {
                    checkExternalEmitHelpers(node, 12288 /* AsyncGeneratorIncludes */);
                }
                // Async functions prior to ES2017 require the __awaiter helper
                if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ && languageVersion < 4 /* ES2017 */) {
                    checkExternalEmitHelpers(node, 64 /* Awaiter */);
                }
                // Generator functions, Async functions, and Async Generator functions prior to
                // ES2015 require the __generator helper
                if ((functionFlags & 3 /* AsyncGenerator */) !== 0 /* Normal */ && languageVersion < 2 /* ES2015 */) {
                    checkExternalEmitHelpers(node, 128 /* Generator */);
                }
            }
            checkTypeParameters(node.typeParameters);
            ts.forEach(node.parameters, checkParameter);
            // TODO(rbuckton): Should we start checking JSDoc types?
            if (node.type) {
                checkSourceElement(node.type);
            }
            if (produceDiagnostics) {
                checkCollisionWithArgumentsInGeneratedCode(node);
                var returnTypeNode = ts.getEffectiveReturnTypeNode(node);
                if (noImplicitAny && !returnTypeNode) {
                    switch (node.kind) {
                        case 166 /* ConstructSignature */:
                            error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                        case 165 /* CallSignature */:
                            error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type);
                            break;
                    }
                }
                if (returnTypeNode) {
                    var functionFlags_1 = ts.getFunctionFlags(node);
                    if ((functionFlags_1 & (4 /* Invalid */ | 1 /* Generator */)) === 1 /* Generator */) {
                        var returnType = getTypeFromTypeNode(returnTypeNode);
                        if (returnType === voidType) {
                            error(returnTypeNode, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation);
                        }
                        else {
                            // Naively, one could check that Generator<any, any, any> is assignable to the return type annotation.
                            // However, that would not catch the error in the following case.
                            //
                            //    interface BadGenerator extends Iterable<number>, Iterator<string> { }
                            //    function* g(): BadGenerator { } // Iterable and Iterator have different types!
                            //
                            var generatorYieldType = getIterationTypeOfGeneratorFunctionReturnType(0 /* Yield */, returnType, (functionFlags_1 & 2 /* Async */) !== 0) || anyType;
                            var generatorReturnType = getIterationTypeOfGeneratorFunctionReturnType(1 /* Return */, returnType, (functionFlags_1 & 2 /* Async */) !== 0) || generatorYieldType;
                            var generatorNextType = getIterationTypeOfGeneratorFunctionReturnType(2 /* Next */, returnType, (functionFlags_1 & 2 /* Async */) !== 0) || unknownType;
                            var generatorInstantiation = createGeneratorReturnType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags_1 & 2 /* Async */));
                            checkTypeAssignableTo(generatorInstantiation, returnType, returnTypeNode);
                        }
                    }
                    else if ((functionFlags_1 & 3 /* AsyncGenerator */) === 2 /* Async */) {
                        checkAsyncFunctionReturnType(node, returnTypeNode);
                    }
                }
                if (node.kind !== 167 /* IndexSignature */ && node.kind !== 300 /* JSDocFunctionType */) {
                    registerForUnusedIdentifiersCheck(node);
                }
            }
        }
        function checkClassForDuplicateDeclarations(node) {
            var instanceNames = ts.createUnderscoreEscapedMap();
            var staticNames = ts.createUnderscoreEscapedMap();
            // instance and static private identifiers share the same scope
            var privateIdentifiers = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 162 /* Constructor */) {
                    for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                        var param = _c[_b];
                        if (ts.isParameterPropertyDeclaration(param, member) && !ts.isBindingPattern(param.name)) {
                            addName(instanceNames, param.name, param.name.escapedText, 3 /* GetOrSetAccessor */);
                        }
                    }
                }
                else {
                    var isStatic = ts.hasModifier(member, 32 /* Static */);
                    var name = member.name;
                    if (!name) {
                        return;
                    }
                    var names = ts.isPrivateIdentifier(name) ? privateIdentifiers :
                        isStatic ? staticNames :
                            instanceNames;
                    var memberName = name && ts.getPropertyNameForPropertyNameNode(name);
                    if (memberName) {
                        switch (member.kind) {
                            case 163 /* GetAccessor */:
                                addName(names, name, memberName, 1 /* GetAccessor */);
                                break;
                            case 164 /* SetAccessor */:
                                addName(names, name, memberName, 2 /* SetAccessor */);
                                break;
                            case 159 /* PropertyDeclaration */:
                                addName(names, name, memberName, 3 /* GetOrSetAccessor */);
                                break;
                            case 161 /* MethodDeclaration */:
                                addName(names, name, memberName, 8 /* Method */);
                                break;
                        }
                    }
                }
            }
            function addName(names, location, name, meaning) {
                var prev = names.get(name);
                if (prev) {
                    if (prev & 8 /* Method */) {
                        if (meaning !== 8 /* Method */) {
                            error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                        }
                    }
                    else if (prev & meaning) {
                        error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location));
                    }
                    else {
                        names.set(name, prev | meaning);
                    }
                }
                else {
                    names.set(name, meaning);
                }
            }
        }
        /**
         * Static members being set on a constructor function may conflict with built-in properties
         * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable
         * built-in properties. This check issues a transpile error when a class has a static
         * member with the same name as a non-writable built-in property.
         *
         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3
         * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5
         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor
         * @see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances
         */
        function checkClassForStaticPropertyNameConflicts(node) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                var memberNameNode = member.name;
                var isStatic = ts.hasModifier(member, 32 /* Static */);
                if (isStatic && memberNameNode) {
                    var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode);
                    switch (memberName) {
                        case "name":
                        case "length":
                        case "caller":
                        case "arguments":
                        case "prototype":
                            var message = ts.Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1;
                            var className = getNameOfSymbolAsWritten(getSymbolOfNode(node));
                            error(memberNameNode, message, memberName, className);
                            break;
                    }
                }
            }
        }
        function checkObjectTypeForDuplicateDeclarations(node) {
            var names = ts.createMap();
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (member.kind === 158 /* PropertySignature */) {
                    var memberName = void 0;
                    var name = member.name;
                    switch (name.kind) {
                        case 10 /* StringLiteral */:
                        case 8 /* NumericLiteral */:
                            memberName = name.text;
                            break;
                        case 75 /* Identifier */:
                            memberName = ts.idText(name);
                            break;
                        default:
                            continue;
                    }
                    if (names.get(memberName)) {
                        error(ts.getNameOfDeclaration(member.symbol.valueDeclaration), ts.Diagnostics.Duplicate_identifier_0, memberName);
                        error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName);
                    }
                    else {
                        names.set(memberName, true);
                    }
                }
            }
        }
        function checkTypeForDuplicateIndexSignatures(node) {
            if (node.kind === 246 /* InterfaceDeclaration */) {
                var nodeSymbol = getSymbolOfNode(node);
                // in case of merging interface declaration it is possible that we'll enter this check procedure several times for every declaration
                // to prevent this run check only for the first declaration of a given kind
                if (nodeSymbol.declarations.length > 0 && nodeSymbol.declarations[0] !== node) {
                    return;
                }
            }
            // TypeScript 1.0 spec (April 2014)
            // 3.7.4: An object type can contain at most one string index signature and one numeric index signature.
            // 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration
            var indexSymbol = getIndexSymbol(getSymbolOfNode(node));
            if (indexSymbol) {
                var seenNumericIndexer = false;
                var seenStringIndexer = false;
                for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var declaration = decl;
                    if (declaration.parameters.length === 1 && declaration.parameters[0].type) {
                        switch (declaration.parameters[0].type.kind) {
                            case 143 /* StringKeyword */:
                                if (!seenStringIndexer) {
                                    seenStringIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_string_index_signature);
                                }
                                break;
                            case 140 /* NumberKeyword */:
                                if (!seenNumericIndexer) {
                                    seenNumericIndexer = true;
                                }
                                else {
                                    error(declaration, ts.Diagnostics.Duplicate_number_index_signature);
                                }
                                break;
                        }
                    }
                }
            }
        }
        function checkPropertyDeclaration(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node))
                checkGrammarComputedPropertyName(node.name);
            checkVariableLikeDeclaration(node);
            // Private class fields transformation relies on WeakMaps.
            if (ts.isPrivateIdentifier(node.name) && languageVersion < 99 /* ESNext */) {
                for (var lexicalScope = ts.getEnclosingBlockScopeContainer(node); !!lexicalScope; lexicalScope = ts.getEnclosingBlockScopeContainer(lexicalScope)) {
                    getNodeLinks(lexicalScope).flags |= 67108864 /* ContainsClassWithPrivateIdentifiers */;
                }
            }
        }
        function checkPropertySignature(node) {
            if (ts.isPrivateIdentifier(node.name)) {
                error(node, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
            }
            return checkPropertyDeclaration(node);
        }
        function checkMethodDeclaration(node) {
            // Grammar checking
            if (!checkGrammarMethod(node))
                checkGrammarComputedPropertyName(node.name);
            if (ts.isPrivateIdentifier(node.name)) {
                error(node, ts.Diagnostics.A_method_cannot_be_named_with_a_private_identifier);
            }
            // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration
            checkFunctionOrMethodDeclaration(node);
            // Abstract methods cannot have an implementation.
            // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node.
            if (ts.hasModifier(node, 128 /* Abstract */) && node.kind === 161 /* MethodDeclaration */ && node.body) {
                error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name));
            }
        }
        function checkConstructorDeclaration(node) {
            // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function.
            checkSignatureDeclaration(node);
            // Grammar check for checking only related to constructorDeclaration
            if (!checkGrammarConstructorTypeParameters(node))
                checkGrammarConstructorTypeAnnotation(node);
            checkSourceElement(node.body);
            var symbol = getSymbolOfNode(node);
            var firstDeclaration = ts.getDeclarationOfKind(symbol, node.kind);
            // Only type check the symbol once
            if (node === firstDeclaration) {
                checkFunctionOrConstructorSymbol(symbol);
            }
            // exit early in the case of signature - super checks are not relevant to them
            if (ts.nodeIsMissing(node.body)) {
                return;
            }
            if (!produceDiagnostics) {
                return;
            }
            function isInstancePropertyWithInitializerOrPrivateIdentifierProperty(n) {
                if (ts.isPrivateIdentifierPropertyDeclaration(n)) {
                    return true;
                }
                return n.kind === 159 /* PropertyDeclaration */ &&
                    !ts.hasModifier(n, 32 /* Static */) &&
                    !!n.initializer;
            }
            // TS 1.0 spec (April 2014): 8.3.2
            // Constructors of classes with no extends clause may not contain super calls, whereas
            // constructors of derived classes must contain at least one super call somewhere in their function body.
            var containingClassDecl = node.parent;
            if (ts.getClassExtendsHeritageElement(containingClassDecl)) {
                captureLexicalThis(node.parent, containingClassDecl);
                var classExtendsNull = classDeclarationExtendsNull(containingClassDecl);
                var superCall = getSuperCallInConstructor(node);
                if (superCall) {
                    if (classExtendsNull) {
                        error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null);
                    }
                    // The first statement in the body of a constructor (excluding prologue directives) must be a super call
                    // if both of the following are true:
                    // - The containing class is a derived class.
                    // - The constructor declares parameter properties
                    //   or the containing class declares instance member variables with initializers.
                    var superCallShouldBeFirst = (compilerOptions.target !== 99 /* ESNext */ || !compilerOptions.useDefineForClassFields) &&
                        (ts.some(node.parent.members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) ||
                            ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92 /* ParameterPropertyModifier */); }));
                    // Skip past any prologue directives to find the first statement
                    // to ensure that it was a super call.
                    if (superCallShouldBeFirst) {
                        var statements = node.body.statements;
                        var superCallStatement = void 0;
                        for (var _i = 0, statements_3 = statements; _i < statements_3.length; _i++) {
                            var statement = statements_3[_i];
                            if (statement.kind === 226 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) {
                                superCallStatement = statement;
                                break;
                            }
                            if (!ts.isPrologueDirective(statement)) {
                                break;
                            }
                        }
                        if (!superCallStatement) {
                            error(node, ts.Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_parameter_properties_or_private_identifiers);
                        }
                    }
                }
                else if (!classExtendsNull) {
                    error(node, ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call);
                }
            }
        }
        function checkAccessorDeclaration(node) {
            if (produceDiagnostics) {
                // Grammar checking accessors
                if (!checkGrammarFunctionLikeDeclaration(node) && !checkGrammarAccessor(node))
                    checkGrammarComputedPropertyName(node.name);
                checkDecorators(node);
                checkSignatureDeclaration(node);
                if (node.kind === 163 /* GetAccessor */) {
                    if (!(node.flags & 8388608 /* Ambient */) && ts.nodeIsPresent(node.body) && (node.flags & 256 /* HasImplicitReturn */)) {
                        if (!(node.flags & 512 /* HasExplicitReturn */)) {
                            error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value);
                        }
                    }
                }
                // Do not use hasDynamicName here, because that returns false for well known symbols.
                // We want to perform checkComputedPropertyName for all computed properties, including
                // well known symbols.
                if (node.name.kind === 154 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.name);
                }
                if (ts.isPrivateIdentifier(node.name)) {
                    error(node.name, ts.Diagnostics.An_accessor_cannot_be_named_with_a_private_identifier);
                }
                if (!hasNonBindableDynamicName(node)) {
                    // TypeScript 1.0 spec (April 2014): 8.4.3
                    // Accessors for the same member name must specify the same accessibility.
                    var otherKind = node.kind === 163 /* GetAccessor */ ? 164 /* SetAccessor */ : 163 /* GetAccessor */;
                    var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(node), otherKind);
                    if (otherAccessor) {
                        var nodeFlags = ts.getModifierFlags(node);
                        var otherFlags = ts.getModifierFlags(otherAccessor);
                        if ((nodeFlags & 28 /* AccessibilityModifier */) !== (otherFlags & 28 /* AccessibilityModifier */)) {
                            error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
                        }
                        if ((nodeFlags & 128 /* Abstract */) !== (otherFlags & 128 /* Abstract */)) {
                            error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract);
                        }
                        // TypeScript 1.0 spec (April 2014): 4.5
                        // If both accessors include type annotations, the specified types must be identical.
                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type);
                        checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type);
                    }
                }
                var returnType = getTypeOfAccessors(getSymbolOfNode(node));
                if (node.kind === 163 /* GetAccessor */) {
                    checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType);
                }
            }
            checkSourceElement(node.body);
        }
        function checkAccessorDeclarationTypesIdentical(first, second, getAnnotatedType, message) {
            var firstType = getAnnotatedType(first);
            var secondType = getAnnotatedType(second);
            if (firstType && secondType && !isTypeIdenticalTo(firstType, secondType)) {
                error(first, message);
            }
        }
        function checkMissingDeclaration(node) {
            checkDecorators(node);
        }
        function getEffectiveTypeArguments(node, typeParameters) {
            return fillMissingTypeArguments(ts.map(node.typeArguments, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJSFile(node));
        }
        function checkTypeArgumentConstraints(node, typeParameters) {
            var typeArguments;
            var mapper;
            var result = true;
            for (var i = 0; i < typeParameters.length; i++) {
                var constraint = getConstraintOfTypeParameter(typeParameters[i]);
                if (constraint) {
                    if (!typeArguments) {
                        typeArguments = getEffectiveTypeArguments(node, typeParameters);
                        mapper = createTypeMapper(typeParameters, typeArguments);
                    }
                    result = result && checkTypeAssignableTo(typeArguments[i], instantiateType(constraint, mapper), node.typeArguments[i], ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
                }
            }
            return result;
        }
        function getTypeParametersForTypeReference(node) {
            var type = getTypeFromTypeReference(node);
            if (type !== errorType) {
                var symbol = getNodeLinks(node).resolvedSymbol;
                if (symbol) {
                    return symbol.flags & 524288 /* TypeAlias */ && getSymbolLinks(symbol).typeParameters ||
                        (ts.getObjectFlags(type) & 4 /* Reference */ ? type.target.localTypeParameters : undefined);
                }
            }
            return undefined;
        }
        function checkTypeReferenceNode(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            if (node.kind === 169 /* TypeReference */ && node.typeName.jsdocDotPos !== undefined && !ts.isInJSFile(node) && !ts.isInJSDoc(node)) {
                grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
            }
            ts.forEach(node.typeArguments, checkSourceElement);
            var type = getTypeFromTypeReference(node);
            if (type !== errorType) {
                if (node.typeArguments && produceDiagnostics) {
                    var typeParameters = getTypeParametersForTypeReference(node);
                    if (typeParameters) {
                        checkTypeArgumentConstraints(node, typeParameters);
                    }
                }
                if (type.flags & 32 /* Enum */ && getNodeLinks(node).resolvedSymbol.flags & 8 /* EnumMember */) {
                    error(node, ts.Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type));
                }
            }
        }
        function getTypeArgumentConstraint(node) {
            var typeReferenceNode = ts.tryCast(node.parent, ts.isTypeReferenceType);
            if (!typeReferenceNode)
                return undefined;
            var typeParameters = getTypeParametersForTypeReference(typeReferenceNode); // TODO: GH#18217
            var constraint = getConstraintOfTypeParameter(typeParameters[typeReferenceNode.typeArguments.indexOf(node)]);
            return constraint && instantiateType(constraint, createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReferenceNode, typeParameters)));
        }
        function checkTypeQuery(node) {
            getTypeFromTypeQueryNode(node);
        }
        function checkTypeLiteral(node) {
            ts.forEach(node.members, checkSourceElement);
            if (produceDiagnostics) {
                var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
                checkIndexConstraints(type);
                checkTypeForDuplicateIndexSignatures(node);
                checkObjectTypeForDuplicateDeclarations(node);
            }
        }
        function checkArrayType(node) {
            checkSourceElement(node.elementType);
        }
        function checkTupleType(node) {
            var elementTypes = node.elementTypes;
            var seenOptionalElement = false;
            for (var i = 0; i < elementTypes.length; i++) {
                var e = elementTypes[i];
                if (e.kind === 177 /* RestType */) {
                    if (i !== elementTypes.length - 1) {
                        grammarErrorOnNode(e, ts.Diagnostics.A_rest_element_must_be_last_in_a_tuple_type);
                        break;
                    }
                    if (!isArrayType(getTypeFromTypeNode(e.type))) {
                        error(e, ts.Diagnostics.A_rest_element_type_must_be_an_array_type);
                    }
                }
                else if (e.kind === 176 /* OptionalType */) {
                    seenOptionalElement = true;
                }
                else if (seenOptionalElement) {
                    grammarErrorOnNode(e, ts.Diagnostics.A_required_element_cannot_follow_an_optional_element);
                    break;
                }
            }
            ts.forEach(node.elementTypes, checkSourceElement);
        }
        function checkUnionOrIntersectionType(node) {
            ts.forEach(node.types, checkSourceElement);
        }
        function checkIndexedAccessIndexType(type, accessNode) {
            if (!(type.flags & 8388608 /* IndexedAccess */)) {
                return type;
            }
            // Check if the index type is assignable to 'keyof T' for the object type.
            var objectType = type.objectType;
            var indexType = type.indexType;
            if (isTypeAssignableTo(indexType, getIndexType(objectType, /*stringsOnly*/ false))) {
                if (accessNode.kind === 195 /* ElementAccessExpression */ && ts.isAssignmentTarget(accessNode) &&
                    ts.getObjectFlags(objectType) & 32 /* Mapped */ && getMappedTypeModifiers(objectType) & 1 /* IncludeReadonly */) {
                    error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
                }
                return type;
            }
            // Check if we're indexing with a numeric type and if either object or index types
            // is a generic type with a constraint that has a numeric index signature.
            var apparentObjectType = getApparentType(objectType);
            if (getIndexInfoOfType(apparentObjectType, 1 /* Number */) && isTypeAssignableToKind(indexType, 296 /* NumberLike */)) {
                return type;
            }
            if (isGenericObjectType(objectType)) {
                var propertyName_1 = getPropertyNameFromIndex(indexType, accessNode);
                if (propertyName_1) {
                    var propertySymbol = forEachType(apparentObjectType, function (t) { return getPropertyOfType(t, propertyName_1); });
                    if (propertySymbol && ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & 24 /* NonPublicAccessibilityModifier */) {
                        error(accessNode, ts.Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, ts.unescapeLeadingUnderscores(propertyName_1));
                        return errorType;
                    }
                }
            }
            error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType));
            return errorType;
        }
        function checkIndexedAccessType(node) {
            checkSourceElement(node.objectType);
            checkSourceElement(node.indexType);
            checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node);
        }
        function checkMappedType(node) {
            checkSourceElement(node.typeParameter);
            checkSourceElement(node.type);
            if (!node.type) {
                reportImplicitAny(node, anyType);
            }
            var type = getTypeFromMappedTypeNode(node);
            var constraintType = getConstraintTypeFromMappedType(type);
            checkTypeAssignableTo(constraintType, keyofConstraintType, ts.getEffectiveConstraintOfTypeParameter(node.typeParameter));
        }
        function checkThisType(node) {
            getTypeFromThisTypeNode(node);
        }
        function checkTypeOperator(node) {
            checkGrammarTypeOperatorNode(node);
            checkSourceElement(node.type);
        }
        function checkConditionalType(node) {
            ts.forEachChild(node, checkSourceElement);
        }
        function checkInferType(node) {
            if (!ts.findAncestor(node, function (n) { return n.parent && n.parent.kind === 180 /* ConditionalType */ && n.parent.extendsType === n; })) {
                grammarErrorOnNode(node, ts.Diagnostics.infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type);
            }
            checkSourceElement(node.typeParameter);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkImportType(node) {
            checkSourceElement(node.argument);
            getTypeFromTypeNode(node);
        }
        function isPrivateWithinAmbient(node) {
            return (ts.hasModifier(node, 8 /* Private */) || ts.isPrivateIdentifierPropertyDeclaration(node)) && !!(node.flags & 8388608 /* Ambient */);
        }
        function getEffectiveDeclarationFlags(n, flagsToCheck) {
            var flags = ts.getCombinedModifierFlags(n);
            // children of classes (even ambient classes) should not be marked as ambient or export
            // because those flags have no useful semantics there.
            if (n.parent.kind !== 246 /* InterfaceDeclaration */ &&
                n.parent.kind !== 245 /* ClassDeclaration */ &&
                n.parent.kind !== 214 /* ClassExpression */ &&
                n.flags & 8388608 /* Ambient */) {
                if (!(flags & 2 /* Ambient */) && !(ts.isModuleBlock(n.parent) && ts.isModuleDeclaration(n.parent.parent) && ts.isGlobalScopeAugmentation(n.parent.parent))) {
                    // It is nested in an ambient context, which means it is automatically exported
                    flags |= 1 /* Export */;
                }
                flags |= 2 /* Ambient */;
            }
            return flags & flagsToCheck;
        }
        function checkFunctionOrConstructorSymbol(symbol) {
            if (!produceDiagnostics) {
                return;
            }
            function getCanonicalOverload(overloads, implementation) {
                // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration
                // Error on all deviations from this canonical set of flags
                // The caveat is that if some overloads are defined in lib.d.ts, we don't want to
                // report the errors on those. To achieve this, we will say that the implementation is
                // the canonical signature only if it is in the same container as the first overload
                var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent;
                return implementationSharesContainerWithFirstOverload ? implementation : overloads[0];
            }
            function checkFlagAgreementBetweenOverloads(overloads, implementation, flagsToCheck, someOverloadFlags, allOverloadFlags) {
                // Error if some overloads have a flag that is not shared by all overloads. To find the
                // deviations, we XOR someOverloadFlags with allOverloadFlags
                var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags;
                if (someButNotAllOverloadFlags !== 0) {
                    var canonicalFlags_1 = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck);
                    ts.forEach(overloads, function (o) {
                        var deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags_1;
                        if (deviation & 1 /* Export */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported);
                        }
                        else if (deviation & 2 /* Ambient */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient);
                        }
                        else if (deviation & (8 /* Private */ | 16 /* Protected */)) {
                            error(ts.getNameOfDeclaration(o) || o, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected);
                        }
                        else if (deviation & 128 /* Abstract */) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract);
                        }
                    });
                }
            }
            function checkQuestionTokenAgreementBetweenOverloads(overloads, implementation, someHaveQuestionToken, allHaveQuestionToken) {
                if (someHaveQuestionToken !== allHaveQuestionToken) {
                    var canonicalHasQuestionToken_1 = ts.hasQuestionToken(getCanonicalOverload(overloads, implementation));
                    ts.forEach(overloads, function (o) {
                        var deviation = ts.hasQuestionToken(o) !== canonicalHasQuestionToken_1;
                        if (deviation) {
                            error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_optional_or_required);
                        }
                    });
                }
            }
            var flagsToCheck = 1 /* Export */ | 2 /* Ambient */ | 8 /* Private */ | 16 /* Protected */ | 128 /* Abstract */;
            var someNodeFlags = 0 /* None */;
            var allNodeFlags = flagsToCheck;
            var someHaveQuestionToken = false;
            var allHaveQuestionToken = true;
            var hasOverloads = false;
            var bodyDeclaration;
            var lastSeenNonAmbientDeclaration;
            var previousDeclaration;
            var declarations = symbol.declarations;
            var isConstructor = (symbol.flags & 16384 /* Constructor */) !== 0;
            function reportImplementationExpectedError(node) {
                if (node.name && ts.nodeIsMissing(node.name)) {
                    return;
                }
                var seen = false;
                var subsequentNode = ts.forEachChild(node.parent, function (c) {
                    if (seen) {
                        return c;
                    }
                    else {
                        seen = c === node;
                    }
                });
                // We may be here because of some extra nodes between overloads that could not be parsed into a valid node.
                // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here.
                if (subsequentNode && subsequentNode.pos === node.end) {
                    if (subsequentNode.kind === node.kind) {
                        var errorNode_1 = subsequentNode.name || subsequentNode;
                        var subsequentName = subsequentNode.name;
                        if (node.name && subsequentName && (
                        // both are private identifiers
                        ts.isPrivateIdentifier(node.name) && ts.isPrivateIdentifier(subsequentName) && node.name.escapedText === subsequentName.escapedText ||
                            // Both are computed property names
                            // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!)
                            ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) ||
                            // Both are literal property names that are the same.
                            ts.isPropertyNameLiteral(node.name) && ts.isPropertyNameLiteral(subsequentName) &&
                                ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) {
                            var reportError = (node.kind === 161 /* MethodDeclaration */ || node.kind === 160 /* MethodSignature */) &&
                                ts.hasModifier(node, 32 /* Static */) !== ts.hasModifier(subsequentNode, 32 /* Static */);
                            // we can get here in two cases
                            // 1. mixed static and instance class members
                            // 2. something with the same name was defined before the set of overloads that prevents them from merging
                            // here we'll report error only for the first case since for second we should already report error in binder
                            if (reportError) {
                                var diagnostic = ts.hasModifier(node, 32 /* Static */) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static;
                                error(errorNode_1, diagnostic);
                            }
                            return;
                        }
                        if (ts.nodeIsPresent(subsequentNode.body)) {
                            error(errorNode_1, ts.Diagnostics.Function_implementation_name_must_be_0, ts.declarationNameToString(node.name));
                            return;
                        }
                    }
                }
                var errorNode = node.name || node;
                if (isConstructor) {
                    error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing);
                }
                else {
                    // Report different errors regarding non-consecutive blocks of declarations depending on whether
                    // the node in question is abstract.
                    if (ts.hasModifier(node, 128 /* Abstract */)) {
                        error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive);
                    }
                    else {
                        error(errorNode, ts.Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration);
                    }
                }
            }
            var duplicateFunctionDeclaration = false;
            var multipleConstructorImplementation = false;
            var hasNonAmbientClass = false;
            for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) {
                var current = declarations_4[_i];
                var node = current;
                var inAmbientContext = node.flags & 8388608 /* Ambient */;
                var inAmbientContextOrInterface = node.parent.kind === 246 /* InterfaceDeclaration */ || node.parent.kind === 173 /* TypeLiteral */ || inAmbientContext;
                if (inAmbientContextOrInterface) {
                    // check if declarations are consecutive only if they are non-ambient
                    // 1. ambient declarations can be interleaved
                    // i.e. this is legal
                    //     declare function foo();
                    //     declare function bar();
                    //     declare function foo();
                    // 2. mixing ambient and non-ambient declarations is a separate error that will be reported - do not want to report an extra one
                    previousDeclaration = undefined;
                }
                if ((node.kind === 245 /* ClassDeclaration */ || node.kind === 214 /* ClassExpression */) && !inAmbientContext) {
                    hasNonAmbientClass = true;
                }
                if (node.kind === 244 /* FunctionDeclaration */ || node.kind === 161 /* MethodDeclaration */ || node.kind === 160 /* MethodSignature */ || node.kind === 162 /* Constructor */) {
                    var currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
                    someNodeFlags |= currentNodeFlags;
                    allNodeFlags &= currentNodeFlags;
                    someHaveQuestionToken = someHaveQuestionToken || ts.hasQuestionToken(node);
                    allHaveQuestionToken = allHaveQuestionToken && ts.hasQuestionToken(node);
                    if (ts.nodeIsPresent(node.body) && bodyDeclaration) {
                        if (isConstructor) {
                            multipleConstructorImplementation = true;
                        }
                        else {
                            duplicateFunctionDeclaration = true;
                        }
                    }
                    else if (previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
                        reportImplementationExpectedError(previousDeclaration);
                    }
                    if (ts.nodeIsPresent(node.body)) {
                        if (!bodyDeclaration) {
                            bodyDeclaration = node;
                        }
                    }
                    else {
                        hasOverloads = true;
                    }
                    previousDeclaration = node;
                    if (!inAmbientContextOrInterface) {
                        lastSeenNonAmbientDeclaration = node;
                    }
                }
            }
            if (multipleConstructorImplementation) {
                ts.forEach(declarations, function (declaration) {
                    error(declaration, ts.Diagnostics.Multiple_constructor_implementations_are_not_allowed);
                });
            }
            if (duplicateFunctionDeclaration) {
                ts.forEach(declarations, function (declaration) {
                    error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Duplicate_function_implementation);
                });
            }
            if (hasNonAmbientClass && !isConstructor && symbol.flags & 16 /* Function */) {
                // A non-ambient class cannot be an implementation for a non-constructor function/class merge
                // TODO: The below just replicates our older error from when classes and functions were
                // entirely unable to merge - a more helpful message like "Class declaration cannot implement overload list"
                // might be warranted. :shrug:
                ts.forEach(declarations, function (declaration) {
                    addDuplicateDeclarationError(declaration, ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(symbol), declarations);
                });
            }
            // Abstract methods can't have an implementation -- in particular, they don't need one.
            if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body &&
                !ts.hasModifier(lastSeenNonAmbientDeclaration, 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) {
                reportImplementationExpectedError(lastSeenNonAmbientDeclaration);
            }
            if (hasOverloads) {
                checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags);
                checkQuestionTokenAgreementBetweenOverloads(declarations, bodyDeclaration, someHaveQuestionToken, allHaveQuestionToken);
                if (bodyDeclaration) {
                    var signatures = getSignaturesOfSymbol(symbol);
                    var bodySignature = getSignatureFromDeclaration(bodyDeclaration);
                    for (var _a = 0, signatures_10 = signatures; _a < signatures_10.length; _a++) {
                        var signature = signatures_10[_a];
                        if (!isImplementationCompatibleWithOverload(bodySignature, signature)) {
                            ts.addRelatedInfo(error(signature.declaration, ts.Diagnostics.This_overload_signature_is_not_compatible_with_its_implementation_signature), ts.createDiagnosticForNode(bodyDeclaration, ts.Diagnostics.The_implementation_signature_is_declared_here));
                            break;
                        }
                    }
                }
            }
        }
        function checkExportsOnMergedDeclarations(node) {
            if (!produceDiagnostics) {
                return;
            }
            // if localSymbol is defined on node then node itself is exported - check is required
            var symbol = node.localSymbol;
            if (!symbol) {
                // local symbol is undefined => this declaration is non-exported.
                // however symbol might contain other declarations that are exported
                symbol = getSymbolOfNode(node);
                if (!symbol.exportSymbol) {
                    // this is a pure local symbol (all declarations are non-exported) - no need to check anything
                    return;
                }
            }
            // run the check only for the first declaration in the list
            if (ts.getDeclarationOfKind(symbol, node.kind) !== node) {
                return;
            }
            var exportedDeclarationSpaces = 0 /* None */;
            var nonExportedDeclarationSpaces = 0 /* None */;
            var defaultExportedDeclarationSpaces = 0 /* None */;
            for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                var d = _a[_i];
                var declarationSpaces = getDeclarationSpaces(d);
                var effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, 1 /* Export */ | 512 /* Default */);
                if (effectiveDeclarationFlags & 1 /* Export */) {
                    if (effectiveDeclarationFlags & 512 /* Default */) {
                        defaultExportedDeclarationSpaces |= declarationSpaces;
                    }
                    else {
                        exportedDeclarationSpaces |= declarationSpaces;
                    }
                }
                else {
                    nonExportedDeclarationSpaces |= declarationSpaces;
                }
            }
            // Spaces for anything not declared a 'default export'.
            var nonDefaultExportedDeclarationSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces;
            var commonDeclarationSpacesForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces;
            var commonDeclarationSpacesForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationSpaces;
            if (commonDeclarationSpacesForExportsAndLocals || commonDeclarationSpacesForDefaultAndNonDefault) {
                // declaration spaces for exported and non-exported declarations intersect
                for (var _b = 0, _c = symbol.declarations; _b < _c.length; _b++) {
                    var d = _c[_b];
                    var declarationSpaces = getDeclarationSpaces(d);
                    var name = ts.getNameOfDeclaration(d);
                    // Only error on the declarations that contributed to the intersecting spaces.
                    if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) {
                        error(name, ts.Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, ts.declarationNameToString(name));
                    }
                    else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) {
                        error(name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(name));
                    }
                }
            }
            function getDeclarationSpaces(decl) {
                var d = decl;
                switch (d.kind) {
                    case 246 /* InterfaceDeclaration */:
                    case 247 /* TypeAliasDeclaration */:
                    // A jsdoc typedef and callback are, by definition, type aliases.
                    // falls through
                    case 322 /* JSDocTypedefTag */:
                    case 315 /* JSDocCallbackTag */:
                    case 316 /* JSDocEnumTag */:
                        return 2 /* ExportType */;
                    case 249 /* ModuleDeclaration */:
                        return ts.isAmbientModule(d) || ts.getModuleInstanceState(d) !== 0 /* NonInstantiated */
                            ? 4 /* ExportNamespace */ | 1 /* ExportValue */
                            : 4 /* ExportNamespace */;
                    case 245 /* ClassDeclaration */:
                    case 248 /* EnumDeclaration */:
                    case 284 /* EnumMember */:
                        return 2 /* ExportType */ | 1 /* ExportValue */;
                    case 290 /* SourceFile */:
                        return 2 /* ExportType */ | 1 /* ExportValue */ | 4 /* ExportNamespace */;
                    case 259 /* ExportAssignment */:
                        // Export assigned entity name expressions act as aliases and should fall through, otherwise they export values
                        if (!ts.isEntityNameExpression(d.expression)) {
                            return 1 /* ExportValue */;
                        }
                        d = d.expression;
                    // The below options all declare an Alias, which is allowed to merge with other values within the importing module.
                    // falls through
                    case 253 /* ImportEqualsDeclaration */:
                    case 256 /* NamespaceImport */:
                    case 255 /* ImportClause */:
                        var result_10 = 0 /* None */;
                        var target = resolveAlias(getSymbolOfNode(d));
                        ts.forEach(target.declarations, function (d) { result_10 |= getDeclarationSpaces(d); });
                        return result_10;
                    case 242 /* VariableDeclaration */:
                    case 191 /* BindingElement */:
                    case 244 /* FunctionDeclaration */:
                    case 258 /* ImportSpecifier */: // https://github.com/Microsoft/TypeScript/pull/7591
                    case 75 /* Identifier */: // https://github.com/microsoft/TypeScript/issues/36098
                        // Identifiers are used as declarations of assignment declarations whose parents may be
                        // SyntaxKind.CallExpression - `Object.defineProperty(thing, "aField", {value: 42});`
                        // SyntaxKind.ElementAccessExpression - `thing["aField"] = 42;` or `thing["aField"];` (with a doc comment on it)
                        // or SyntaxKind.PropertyAccessExpression - `thing.aField = 42;`
                        // all of which are pretty much always values, or at least imply a value meaning.
                        // It may be apprpriate to treat these as aliases in the future.
                        return 1 /* ExportValue */;
                    default:
                        return ts.Debug.failBadSyntaxKind(d);
                }
            }
        }
        function getAwaitedTypeOfPromise(type, errorNode, diagnosticMessage, arg0) {
            var promisedType = getPromisedTypeOfPromise(type, errorNode);
            return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0);
        }
        /**
         * Gets the "promised type" of a promise.
         * @param type The type of the promise.
         * @remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback.
         */
        function getPromisedTypeOfPromise(type, errorNode) {
            //
            //  { // type
            //      then( // thenFunction
            //          onfulfilled: ( // onfulfilledParameterType
            //              value: T // valueParameterType
            //          ) => any
            //      ): any;
            //  }
            //
            if (isTypeAny(type)) {
                return undefined;
            }
            var typeAsPromise = type;
            if (typeAsPromise.promisedTypeOfPromise) {
                return typeAsPromise.promisedTypeOfPromise;
            }
            if (isReferenceToType(type, getGlobalPromiseType(/*reportErrors*/ false))) {
                return typeAsPromise.promisedTypeOfPromise = getTypeArguments(type)[0];
            }
            var thenFunction = getTypeOfPropertyOfType(type, "then"); // TODO: GH#18217
            if (isTypeAny(thenFunction)) {
                return undefined;
            }
            var thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, 0 /* Call */) : ts.emptyArray;
            if (thenSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, ts.Diagnostics.A_promise_must_have_a_then_method);
                }
                return undefined;
            }
            var onfulfilledParameterType = getTypeWithFacts(getUnionType(ts.map(thenSignatures, getTypeOfFirstParameterOfSignature)), 2097152 /* NEUndefinedOrNull */);
            if (isTypeAny(onfulfilledParameterType)) {
                return undefined;
            }
            var onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, 0 /* Call */);
            if (onfulfilledParameterSignatures.length === 0) {
                if (errorNode) {
                    error(errorNode, ts.Diagnostics.The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback);
                }
                return undefined;
            }
            return typeAsPromise.promisedTypeOfPromise = getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), 2 /* Subtype */);
        }
        /**
         * Gets the "awaited type" of a type.
         * @param type The type to await.
         * @remarks The "awaited type" of an expression is its "promised type" if the expression is a
         * Promise-like type; otherwise, it is the type of the expression. This is used to reflect
         * The runtime behavior of the `await` keyword.
         */
        function checkAwaitedType(type, errorNode, diagnosticMessage, arg0) {
            var awaitedType = getAwaitedType(type, errorNode, diagnosticMessage, arg0);
            return awaitedType || errorType;
        }
        /**
         * Determines whether a type has a callable `then` member.
         */
        function isThenableType(type) {
            var thenFunction = getTypeOfPropertyOfType(type, "then");
            return !!thenFunction && getSignaturesOfType(getTypeWithFacts(thenFunction, 2097152 /* NEUndefinedOrNull */), 0 /* Call */).length > 0;
        }
        /**
         * Gets the "awaited type" of a type.
         *
         * The "awaited type" of an expression is its "promised type" if the expression is a
         * Promise-like type; otherwise, it is the type of the expression. If the "promised
         * type" is itself a Promise-like, the "promised type" is recursively unwrapped until a
         * non-promise type is found.
         *
         * This is used to reflect the runtime behavior of the `await` keyword.
         */
        function getAwaitedType(type, errorNode, diagnosticMessage, arg0) {
            if (isTypeAny(type)) {
                return type;
            }
            var typeAsAwaitable = type;
            if (typeAsAwaitable.awaitedTypeOfType) {
                return typeAsAwaitable.awaitedTypeOfType;
            }
            // For a union, get a union of the awaited types of each constituent.
            //
            return typeAsAwaitable.awaitedTypeOfType =
                mapType(type, errorNode ? function (constituentType) { return getAwaitedTypeWorker(constituentType, errorNode, diagnosticMessage, arg0); } : getAwaitedTypeWorker);
        }
        function getAwaitedTypeWorker(type, errorNode, diagnosticMessage, arg0) {
            var typeAsAwaitable = type;
            if (typeAsAwaitable.awaitedTypeOfType) {
                return typeAsAwaitable.awaitedTypeOfType;
            }
            var promisedType = getPromisedTypeOfPromise(type);
            if (promisedType) {
                if (type.id === promisedType.id || awaitedTypeStack.lastIndexOf(promisedType.id) >= 0) {
                    // Verify that we don't have a bad actor in the form of a promise whose
                    // promised type is the same as the promise type, or a mutually recursive
                    // promise. If so, we return undefined as we cannot guess the shape. If this
                    // were the actual case in the JavaScript, this Promise would never resolve.
                    //
                    // An example of a bad actor with a singly-recursive promise type might
                    // be:
                    //
                    //  interface BadPromise {
                    //      then(
                    //          onfulfilled: (value: BadPromise) => any,
                    //          onrejected: (error: any) => any): BadPromise;
                    //  }
                    //
                    // The above interface will pass the PromiseLike check, and return a
                    // promised type of `BadPromise`. Since this is a self reference, we
                    // don't want to keep recursing ad infinitum.
                    //
                    // An example of a bad actor in the form of a mutually-recursive
                    // promise type might be:
                    //
                    //  interface BadPromiseA {
                    //      then(
                    //          onfulfilled: (value: BadPromiseB) => any,
                    //          onrejected: (error: any) => any): BadPromiseB;
                    //  }
                    //
                    //  interface BadPromiseB {
                    //      then(
                    //          onfulfilled: (value: BadPromiseA) => any,
                    //          onrejected: (error: any) => any): BadPromiseA;
                    //  }
                    //
                    if (errorNode) {
                        error(errorNode, ts.Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method);
                    }
                    return undefined;
                }
                // Keep track of the type we're about to unwrap to avoid bad recursive promise types.
                // See the comments above for more information.
                awaitedTypeStack.push(type.id);
                var awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0);
                awaitedTypeStack.pop();
                if (!awaitedType) {
                    return undefined;
                }
                return typeAsAwaitable.awaitedTypeOfType = awaitedType;
            }
            // The type was not a promise, so it could not be unwrapped any further.
            // As long as the type does not have a callable "then" property, it is
            // safe to return the type; otherwise, an error is reported and we return
            // undefined.
            //
            // An example of a non-promise "thenable" might be:
            //
            //  await { then(): void {} }
            //
            // The "thenable" does not match the minimal definition for a promise. When
            // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
            // will never settle. We treat this as an error to help flag an early indicator
            // of a runtime problem. If the user wants to return this value from an async
            // function, they would need to wrap it in some other value. If they want it to
            // be treated as a promise, they can cast to <any>.
            if (isThenableType(type)) {
                if (errorNode) {
                    if (!diagnosticMessage)
                        return ts.Debug.fail();
                    error(errorNode, diagnosticMessage, arg0);
                }
                return undefined;
            }
            return typeAsAwaitable.awaitedTypeOfType = type;
        }
        /**
         * Checks the return type of an async function to ensure it is a compatible
         * Promise implementation.
         *
         * This checks that an async function has a valid Promise-compatible return type.
         * An async function has a valid Promise-compatible return type if the resolved value
         * of the return type has a construct signature that takes in an `initializer` function
         * that in turn supplies a `resolve` function as one of its arguments and results in an
         * object with a callable `then` signature.
         *
         * @param node The signature to check
         */
        function checkAsyncFunctionReturnType(node, returnTypeNode) {
            // As part of our emit for an async function, we will need to emit the entity name of
            // the return type annotation as an expression. To meet the necessary runtime semantics
            // for __awaiter, we must also check that the type of the declaration (e.g. the static
            // side or "constructor" of the promise type) is compatible `PromiseConstructorLike`.
            //
            // An example might be (from lib.es6.d.ts):
            //
            //  interface Promise<T> { ... }
            //  interface PromiseConstructor {
            //      new <T>(...): Promise<T>;
            //  }
            //  declare var Promise: PromiseConstructor;
            //
            // When an async function declares a return type annotation of `Promise<T>`, we
            // need to get the type of the `Promise` variable declaration above, which would
            // be `PromiseConstructor`.
            //
            // The same case applies to a class:
            //
            //  declare class Promise<T> {
            //      constructor(...);
            //      then<U>(...): Promise<U>;
            //  }
            //
            var returnType = getTypeFromTypeNode(returnTypeNode);
            if (languageVersion >= 2 /* ES2015 */) {
                if (returnType === errorType) {
                    return;
                }
                var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true);
                if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) {
                    // The promise type was not a valid type reference to the global promise type, so we
                    // report an error and return the unknown type.
                    error(returnTypeNode, ts.Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
                    return;
                }
            }
            else {
                // Always mark the type node as referenced if it points to a value
                markTypeNodeAsReferenced(returnTypeNode);
                if (returnType === errorType) {
                    return;
                }
                var promiseConstructorName = ts.getEntityNameFromTypeNode(returnTypeNode);
                if (promiseConstructorName === undefined) {
                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType));
                    return;
                }
                var promiseConstructorSymbol = resolveEntityName(promiseConstructorName, 111551 /* Value */, /*ignoreErrors*/ true);
                var promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : errorType;
                if (promiseConstructorType === errorType) {
                    if (promiseConstructorName.kind === 75 /* Identifier */ && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) {
                        error(returnTypeNode, ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option);
                    }
                    else {
                        error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
                    }
                    return;
                }
                var globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(/*reportErrors*/ true);
                if (globalPromiseConstructorLikeType === emptyObjectType) {
                    // If we couldn't resolve the global PromiseConstructorLike type we cannot verify
                    // compatibility with __awaiter.
                    error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName));
                    return;
                }
                if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) {
                    return;
                }
                // Verify there is no local declaration that could collide with the promise constructor.
                var rootName = promiseConstructorName && ts.getFirstIdentifier(promiseConstructorName);
                var collidingSymbol = getSymbol(node.locals, rootName.escapedText, 111551 /* Value */);
                if (collidingSymbol) {
                    error(collidingSymbol.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, ts.idText(rootName), ts.entityNameToString(promiseConstructorName));
                    return;
                }
            }
            checkAwaitedType(returnType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
        }
        /** Check a decorator */
        function checkDecorator(node) {
            var signature = getResolvedSignature(node);
            var returnType = getReturnTypeOfSignature(signature);
            if (returnType.flags & 1 /* Any */) {
                return;
            }
            var expectedReturnType;
            var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node);
            var errorInfo;
            switch (node.parent.kind) {
                case 245 /* ClassDeclaration */:
                    var classSymbol = getSymbolOfNode(node.parent);
                    var classConstructorType = getTypeOfSymbol(classSymbol);
                    expectedReturnType = getUnionType([classConstructorType, voidType]);
                    break;
                case 156 /* Parameter */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any);
                    break;
                case 159 /* PropertyDeclaration */:
                    expectedReturnType = voidType;
                    errorInfo = ts.chainDiagnosticMessages(
                    /*details*/ undefined, ts.Diagnostics.The_return_type_of_a_property_decorator_function_must_be_either_void_or_any);
                    break;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    var methodType = getTypeOfNode(node.parent);
                    var descriptorType = createTypedPropertyDescriptorType(methodType);
                    expectedReturnType = getUnionType([descriptorType, voidType]);
                    break;
                default:
                    return ts.Debug.fail();
            }
            checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage, function () { return errorInfo; });
        }
        /**
         * If a TypeNode can be resolved to a value symbol imported from an external module, it is
         * marked as referenced to prevent import elision.
         */
        function markTypeNodeAsReferenced(node) {
            markEntityNameOrEntityExpressionAsReference(node && ts.getEntityNameFromTypeNode(node));
        }
        function markEntityNameOrEntityExpressionAsReference(typeName) {
            if (!typeName)
                return;
            var rootName = ts.getFirstIdentifier(typeName);
            var meaning = (typeName.kind === 75 /* Identifier */ ? 788968 /* Type */ : 1920 /* Namespace */) | 2097152 /* Alias */;
            var rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isRefernce*/ true);
            if (rootSymbol
                && rootSymbol.flags & 2097152 /* Alias */
                && symbolIsValue(rootSymbol)
                && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))
                && !getTypeOnlyAliasDeclaration(rootSymbol)) {
                markAliasSymbolAsReferenced(rootSymbol);
            }
        }
        /**
         * This function marks the type used for metadata decorator as referenced if it is import
         * from external module.
         * This is different from markTypeNodeAsReferenced because it tries to simplify type nodes in
         * union and intersection type
         * @param node
         */
        function markDecoratorMedataDataTypeNodeAsReferenced(node) {
            var entityName = getEntityNameForDecoratorMetadata(node);
            if (entityName && ts.isEntityName(entityName)) {
                markEntityNameOrEntityExpressionAsReference(entityName);
            }
        }
        function getEntityNameForDecoratorMetadata(node) {
            if (node) {
                switch (node.kind) {
                    case 179 /* IntersectionType */:
                    case 178 /* UnionType */:
                        return getEntityNameForDecoratorMetadataFromTypeList(node.types);
                    case 180 /* ConditionalType */:
                        return getEntityNameForDecoratorMetadataFromTypeList([node.trueType, node.falseType]);
                    case 182 /* ParenthesizedType */:
                        return getEntityNameForDecoratorMetadata(node.type);
                    case 169 /* TypeReference */:
                        return node.typeName;
                }
            }
        }
        function getEntityNameForDecoratorMetadataFromTypeList(types) {
            var commonEntityName;
            for (var _i = 0, types_20 = types; _i < types_20.length; _i++) {
                var typeNode = types_20[_i];
                while (typeNode.kind === 182 /* ParenthesizedType */) {
                    typeNode = typeNode.type; // Skip parens if need be
                }
                if (typeNode.kind === 137 /* NeverKeyword */) {
                    continue; // Always elide `never` from the union/intersection if possible
                }
                if (!strictNullChecks && (typeNode.kind === 100 /* NullKeyword */ || typeNode.kind === 146 /* UndefinedKeyword */)) {
                    continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
                }
                var individualEntityName = getEntityNameForDecoratorMetadata(typeNode);
                if (!individualEntityName) {
                    // Individual is something like string number
                    // So it would be serialized to either that type or object
                    // Safe to return here
                    return undefined;
                }
                if (commonEntityName) {
                    // Note this is in sync with the transformation that happens for type node.
                    // Keep this in sync with serializeUnionOrIntersectionType
                    // Verify if they refer to same entity and is identifier
                    // return undefined if they dont match because we would emit object
                    if (!ts.isIdentifier(commonEntityName) ||
                        !ts.isIdentifier(individualEntityName) ||
                        commonEntityName.escapedText !== individualEntityName.escapedText) {
                        return undefined;
                    }
                }
                else {
                    commonEntityName = individualEntityName;
                }
            }
            return commonEntityName;
        }
        function getParameterTypeNodeForDecoratorCheck(node) {
            var typeNode = ts.getEffectiveTypeAnnotationNode(node);
            return ts.isRestParameter(node) ? ts.getRestParameterElementType(typeNode) : typeNode;
        }
        /** Check the decorators of a node */
        function checkDecorators(node) {
            if (!node.decorators) {
                return;
            }
            // skip this check for nodes that cannot have decorators. These should have already had an error reported by
            // checkGrammarDecorators.
            if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) {
                return;
            }
            if (!compilerOptions.experimentalDecorators) {
                error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning);
            }
            var firstDecorator = node.decorators[0];
            checkExternalEmitHelpers(firstDecorator, 8 /* Decorate */);
            if (node.kind === 156 /* Parameter */) {
                checkExternalEmitHelpers(firstDecorator, 32 /* Param */);
            }
            if (compilerOptions.emitDecoratorMetadata) {
                checkExternalEmitHelpers(firstDecorator, 16 /* Metadata */);
                // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
                switch (node.kind) {
                    case 245 /* ClassDeclaration */:
                        var constructor = ts.getFirstConstructorWithBody(node);
                        if (constructor) {
                            for (var _i = 0, _a = constructor.parameters; _i < _a.length; _i++) {
                                var parameter = _a[_i];
                                markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                            }
                        }
                        break;
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        var otherKind = node.kind === 163 /* GetAccessor */ ? 164 /* SetAccessor */ : 163 /* GetAccessor */;
                        var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(node), otherKind);
                        markDecoratorMedataDataTypeNodeAsReferenced(getAnnotatedAccessorTypeNode(node) || otherAccessor && getAnnotatedAccessorTypeNode(otherAccessor));
                        break;
                    case 161 /* MethodDeclaration */:
                        for (var _b = 0, _c = node.parameters; _b < _c.length; _b++) {
                            var parameter = _c[_b];
                            markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                        }
                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveReturnTypeNode(node));
                        break;
                    case 159 /* PropertyDeclaration */:
                        markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveTypeAnnotationNode(node));
                        break;
                    case 156 /* Parameter */:
                        markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node));
                        var containingSignature = node.parent;
                        for (var _d = 0, _e = containingSignature.parameters; _d < _e.length; _d++) {
                            var parameter = _e[_d];
                            markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
                        }
                        break;
                }
            }
            ts.forEach(node.decorators, checkDecorator);
        }
        function checkFunctionDeclaration(node) {
            if (produceDiagnostics) {
                checkFunctionOrMethodDeclaration(node);
                checkGrammarForGenerator(node);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            }
        }
        function checkJSDocTypeAliasTag(node) {
            if (!node.typeExpression) {
                // If the node had `@property` tags, `typeExpression` would have been set to the first property tag.
                error(node.name, ts.Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags);
            }
            if (node.name) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
            }
            checkSourceElement(node.typeExpression);
        }
        function checkJSDocTemplateTag(node) {
            checkSourceElement(node.constraint);
            for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) {
                var tp = _a[_i];
                checkSourceElement(tp);
            }
        }
        function checkJSDocTypeTag(node) {
            checkSourceElement(node.typeExpression);
        }
        function checkJSDocParameterTag(node) {
            checkSourceElement(node.typeExpression);
            if (!ts.getParameterSymbolFromJSDoc(node)) {
                var decl = ts.getHostSignatureFromJSDoc(node);
                // don't issue an error for invalid hosts -- just functions --
                // and give a better error message when the host function mentions `arguments`
                // but the tag doesn't have an array type
                if (decl) {
                    var i = ts.getJSDocTags(decl).filter(ts.isJSDocParameterTag).indexOf(node);
                    if (i > -1 && i < decl.parameters.length && ts.isBindingPattern(decl.parameters[i].name)) {
                        return;
                    }
                    if (!containsArgumentsReference(decl)) {
                        if (ts.isQualifiedName(node.name)) {
                            error(node.name, ts.Diagnostics.Qualified_name_0_is_not_allowed_without_a_leading_param_object_1, ts.entityNameToString(node.name), ts.entityNameToString(node.name.left));
                        }
                        else {
                            error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name));
                        }
                    }
                    else if (ts.findLast(ts.getJSDocTags(decl), ts.isJSDocParameterTag) === node &&
                        node.typeExpression && node.typeExpression.type &&
                        !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) {
                        error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, ts.idText(node.name.kind === 153 /* QualifiedName */ ? node.name.right : node.name));
                    }
                }
            }
        }
        function checkJSDocPropertyTag(node) {
            checkSourceElement(node.typeExpression);
        }
        function checkJSDocFunctionType(node) {
            if (produceDiagnostics && !node.type && !ts.isJSDocConstructSignature(node)) {
                reportImplicitAny(node, anyType);
            }
            checkSignatureDeclaration(node);
        }
        function checkJSDocImplementsTag(node) {
            var classLike = ts.getEffectiveJSDocHost(node);
            if (!classLike || !ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) {
                error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName));
            }
        }
        function checkJSDocAugmentsTag(node) {
            var classLike = ts.getEffectiveJSDocHost(node);
            if (!classLike || !ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) {
                error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName));
                return;
            }
            var augmentsTags = ts.getJSDocTags(classLike).filter(ts.isJSDocAugmentsTag);
            ts.Debug.assert(augmentsTags.length > 0);
            if (augmentsTags.length > 1) {
                error(augmentsTags[1], ts.Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag);
            }
            var name = getIdentifierFromEntityNameExpression(node.class.expression);
            var extend = ts.getClassExtendsHeritageElement(classLike);
            if (extend) {
                var className = getIdentifierFromEntityNameExpression(extend.expression);
                if (className && name.escapedText !== className.escapedText) {
                    error(name, ts.Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, ts.idText(node.tagName), ts.idText(name), ts.idText(className));
                }
            }
        }
        function getIdentifierFromEntityNameExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return node;
                case 194 /* PropertyAccessExpression */:
                    return node.name;
                default:
                    return undefined;
            }
        }
        function checkFunctionOrMethodDeclaration(node) {
            checkDecorators(node);
            checkSignatureDeclaration(node);
            var functionFlags = ts.getFunctionFlags(node);
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name && node.name.kind === 154 /* ComputedPropertyName */) {
                // This check will account for methods in class/interface declarations,
                // as well as accessors in classes/object literals
                checkComputedPropertyName(node.name);
            }
            if (!hasNonBindableDynamicName(node)) {
                // first we want to check the local symbol that contain this declaration
                // - if node.localSymbol !== undefined - this is current declaration is exported and localSymbol points to the local symbol
                // - if node.localSymbol === undefined - this node is non-exported so we can just pick the result of getSymbolOfNode
                var symbol = getSymbolOfNode(node);
                var localSymbol = node.localSymbol || symbol;
                // Since the javascript won't do semantic analysis like typescript,
                // if the javascript file comes before the typescript file and both contain same name functions,
                // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function.
                var firstDeclaration = ts.find(localSymbol.declarations, 
                // Get first non javascript function declaration
                function (declaration) { return declaration.kind === node.kind && !(declaration.flags & 131072 /* JavaScriptFile */); });
                // Only type check the symbol once
                if (node === firstDeclaration) {
                    checkFunctionOrConstructorSymbol(localSymbol);
                }
                if (symbol.parent) {
                    // run check once for the first declaration
                    if (ts.getDeclarationOfKind(symbol, node.kind) === node) {
                        // run check on export symbol to check that modifiers agree across all exported declarations
                        checkFunctionOrConstructorSymbol(symbol);
                    }
                }
            }
            var body = node.kind === 160 /* MethodSignature */ ? undefined : node.body;
            checkSourceElement(body);
            checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, getReturnTypeFromAnnotation(node));
            if (produceDiagnostics && !ts.getEffectiveReturnTypeNode(node)) {
                // Report an implicit any error if there is no body, no explicit return type, and node is not a private method
                // in an ambient context
                if (ts.nodeIsMissing(body) && !isPrivateWithinAmbient(node)) {
                    reportImplicitAny(node, anyType);
                }
                if (functionFlags & 1 /* Generator */ && ts.nodeIsPresent(body)) {
                    // A generator with a body and no type annotation can still cause errors. It can error if the
                    // yielded values have no common supertype, or it can give an implicit any error if it has no
                    // yielded values. The only way to trigger these errors is to try checking its return type.
                    getReturnTypeOfSignature(getSignatureFromDeclaration(node));
                }
            }
            // A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
            if (ts.isInJSFile(node)) {
                var typeTag = ts.getJSDocTypeTag(node);
                if (typeTag && typeTag.typeExpression && !getContextualCallSignature(getTypeFromTypeNode(typeTag.typeExpression), node)) {
                    error(typeTag, ts.Diagnostics.The_type_of_a_function_declaration_must_match_the_function_s_signature);
                }
            }
        }
        function registerForUnusedIdentifiersCheck(node) {
            // May be in a call such as getTypeOfNode that happened to call this. But potentiallyUnusedIdentifiers is only defined in the scope of `checkSourceFile`.
            if (produceDiagnostics) {
                var sourceFile = ts.getSourceFileOfNode(node);
                var potentiallyUnusedIdentifiers = allPotentiallyUnusedIdentifiers.get(sourceFile.path);
                if (!potentiallyUnusedIdentifiers) {
                    potentiallyUnusedIdentifiers = [];
                    allPotentiallyUnusedIdentifiers.set(sourceFile.path, potentiallyUnusedIdentifiers);
                }
                // TODO: GH#22580
                // Debug.assert(addToSeen(seenPotentiallyUnusedIdentifiers, getNodeId(node)), "Adding potentially-unused identifier twice");
                potentiallyUnusedIdentifiers.push(node);
            }
        }
        function checkUnusedIdentifiers(potentiallyUnusedIdentifiers, addDiagnostic) {
            for (var _i = 0, potentiallyUnusedIdentifiers_1 = potentiallyUnusedIdentifiers; _i < potentiallyUnusedIdentifiers_1.length; _i++) {
                var node = potentiallyUnusedIdentifiers_1[_i];
                switch (node.kind) {
                    case 245 /* ClassDeclaration */:
                    case 214 /* ClassExpression */:
                        checkUnusedClassMembers(node, addDiagnostic);
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 290 /* SourceFile */:
                    case 249 /* ModuleDeclaration */:
                    case 223 /* Block */:
                    case 251 /* CaseBlock */:
                    case 230 /* ForStatement */:
                    case 231 /* ForInStatement */:
                    case 232 /* ForOfStatement */:
                        checkUnusedLocalsAndParameters(node, addDiagnostic);
                        break;
                    case 162 /* Constructor */:
                    case 201 /* FunctionExpression */:
                    case 244 /* FunctionDeclaration */:
                    case 202 /* ArrowFunction */:
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        if (node.body) { // Don't report unused parameters in overloads
                            checkUnusedLocalsAndParameters(node, addDiagnostic);
                        }
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 160 /* MethodSignature */:
                    case 165 /* CallSignature */:
                    case 166 /* ConstructSignature */:
                    case 170 /* FunctionType */:
                    case 171 /* ConstructorType */:
                    case 247 /* TypeAliasDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                        checkUnusedTypeParameters(node, addDiagnostic);
                        break;
                    case 181 /* InferType */:
                        checkUnusedInferTypeParameter(node, addDiagnostic);
                        break;
                    default:
                        ts.Debug.assertNever(node, "Node should not have been registered for unused identifiers check");
                }
            }
        }
        function errorUnusedLocal(declaration, name, addDiagnostic) {
            var node = ts.getNameOfDeclaration(declaration) || declaration;
            var message = isTypeDeclaration(declaration) ? ts.Diagnostics._0_is_declared_but_never_used : ts.Diagnostics._0_is_declared_but_its_value_is_never_read;
            addDiagnostic(declaration, 0 /* Local */, ts.createDiagnosticForNode(node, message, name));
        }
        function isIdentifierThatStartsWithUnderscore(node) {
            return ts.isIdentifier(node) && ts.idText(node).charCodeAt(0) === 95 /* _ */;
        }
        function checkUnusedClassMembers(node, addDiagnostic) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                switch (member.kind) {
                    case 161 /* MethodDeclaration */:
                    case 159 /* PropertyDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        if (member.kind === 164 /* SetAccessor */ && member.symbol.flags & 32768 /* GetAccessor */) {
                            // Already would have reported an error on the getter.
                            break;
                        }
                        var symbol = getSymbolOfNode(member);
                        if (!symbol.isReferenced
                            && (ts.hasModifier(member, 8 /* Private */) || ts.isNamedDeclaration(member) && ts.isPrivateIdentifier(member.name))
                            && !(member.flags & 8388608 /* Ambient */)) {
                            addDiagnostic(member, 0 /* Local */, ts.createDiagnosticForNode(member.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
                        }
                        break;
                    case 162 /* Constructor */:
                        for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) {
                            var parameter = _c[_b];
                            if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8 /* Private */)) {
                                addDiagnostic(parameter, 0 /* Local */, ts.createDiagnosticForNode(parameter.name, ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read, ts.symbolName(parameter.symbol)));
                            }
                        }
                        break;
                    case 167 /* IndexSignature */:
                    case 222 /* SemicolonClassElement */:
                        // Can't be private
                        break;
                    default:
                        ts.Debug.fail();
                }
            }
        }
        function checkUnusedInferTypeParameter(node, addDiagnostic) {
            var typeParameter = node.typeParameter;
            if (isTypeParameterUnused(typeParameter)) {
                addDiagnostic(node, 1 /* Parameter */, ts.createDiagnosticForNode(node, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.idText(typeParameter.name)));
            }
        }
        function checkUnusedTypeParameters(node, addDiagnostic) {
            // Only report errors on the last declaration for the type parameter container;
            // this ensures that all uses have been accounted for.
            if (ts.last(getSymbolOfNode(node).declarations) !== node)
                return;
            var typeParameters = ts.getEffectiveTypeParameterDeclarations(node);
            var seenParentsWithEveryUnused = new ts.NodeSet();
            for (var _i = 0, typeParameters_3 = typeParameters; _i < typeParameters_3.length; _i++) {
                var typeParameter = typeParameters_3[_i];
                if (!isTypeParameterUnused(typeParameter))
                    continue;
                var name = ts.idText(typeParameter.name);
                var parent = typeParameter.parent;
                if (parent.kind !== 181 /* InferType */ && parent.typeParameters.every(isTypeParameterUnused)) {
                    if (seenParentsWithEveryUnused.tryAdd(parent)) {
                        var range = ts.isJSDocTemplateTag(parent)
                            // Whole @template tag
                            ? ts.rangeOfNode(parent)
                            // Include the `<>` in the error message
                            : ts.rangeOfTypeParameters(parent.typeParameters);
                        var only = parent.typeParameters.length === 1;
                        var message = only ? ts.Diagnostics._0_is_declared_but_its_value_is_never_read : ts.Diagnostics.All_type_parameters_are_unused;
                        var arg0 = only ? name : undefined;
                        addDiagnostic(typeParameter, 1 /* Parameter */, ts.createFileDiagnostic(ts.getSourceFileOfNode(parent), range.pos, range.end - range.pos, message, arg0));
                    }
                }
                else {
                    addDiagnostic(typeParameter, 1 /* Parameter */, ts.createDiagnosticForNode(typeParameter, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, name));
                }
            }
        }
        function isTypeParameterUnused(typeParameter) {
            return !(getMergedSymbol(typeParameter.symbol).isReferenced & 262144 /* TypeParameter */) && !isIdentifierThatStartsWithUnderscore(typeParameter.name);
        }
        function addToGroup(map, key, value, getKey) {
            var keyString = String(getKey(key));
            var group = map.get(keyString);
            if (group) {
                group[1].push(value);
            }
            else {
                map.set(keyString, [key, [value]]);
            }
        }
        function tryGetRootParameterDeclaration(node) {
            return ts.tryCast(ts.getRootDeclaration(node), ts.isParameter);
        }
        function isValidUnusedLocalDeclaration(declaration) {
            if (ts.isBindingElement(declaration) && isIdentifierThatStartsWithUnderscore(declaration.name)) {
                return !!ts.findAncestor(declaration.parent, function (ancestor) {
                    return ts.isArrayBindingPattern(ancestor) || ts.isVariableDeclaration(ancestor) || ts.isVariableDeclarationList(ancestor) ? false :
                        ts.isForOfStatement(ancestor) ? true : "quit";
                });
            }
            return ts.isAmbientModule(declaration) ||
                (ts.isVariableDeclaration(declaration) && ts.isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name);
        }
        function checkUnusedLocalsAndParameters(nodeWithLocals, addDiagnostic) {
            // Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value.
            var unusedImports = ts.createMap();
            var unusedDestructures = ts.createMap();
            var unusedVariables = ts.createMap();
            nodeWithLocals.locals.forEach(function (local) {
                // If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`.
                // If it's a type parameter merged with a parameter, check if the parameter-side is used.
                if (local.flags & 262144 /* TypeParameter */ ? !(local.flags & 3 /* Variable */ && !(local.isReferenced & 3 /* Variable */)) : local.isReferenced || local.exportSymbol) {
                    return;
                }
                for (var _i = 0, _a = local.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    if (isValidUnusedLocalDeclaration(declaration)) {
                        continue;
                    }
                    if (isImportedDeclaration(declaration)) {
                        addToGroup(unusedImports, importClauseFromImported(declaration), declaration, getNodeId);
                    }
                    else if (ts.isBindingElement(declaration) && ts.isObjectBindingPattern(declaration.parent)) {
                        // In `{ a, ...b }, `a` is considered used since it removes a property from `b`. `b` may still be unused though.
                        var lastElement = ts.last(declaration.parent.elements);
                        if (declaration === lastElement || !ts.last(declaration.parent.elements).dotDotDotToken) {
                            addToGroup(unusedDestructures, declaration.parent, declaration, getNodeId);
                        }
                    }
                    else if (ts.isVariableDeclaration(declaration)) {
                        addToGroup(unusedVariables, declaration.parent, declaration, getNodeId);
                    }
                    else {
                        var parameter = local.valueDeclaration && tryGetRootParameterDeclaration(local.valueDeclaration);
                        var name = local.valueDeclaration && ts.getNameOfDeclaration(local.valueDeclaration);
                        if (parameter && name) {
                            if (!ts.isParameterPropertyDeclaration(parameter, parameter.parent) && !ts.parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) {
                                addDiagnostic(parameter, 1 /* Parameter */, ts.createDiagnosticForNode(name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(local)));
                            }
                        }
                        else {
                            errorUnusedLocal(declaration, ts.symbolName(local), addDiagnostic);
                        }
                    }
                }
            });
            unusedImports.forEach(function (_a) {
                var importClause = _a[0], unuseds = _a[1];
                var importDecl = importClause.parent;
                var nDeclarations = (importClause.name ? 1 : 0) +
                    (importClause.namedBindings ?
                        (importClause.namedBindings.kind === 256 /* NamespaceImport */ ? 1 : importClause.namedBindings.elements.length)
                        : 0);
                if (nDeclarations === unuseds.length) {
                    addDiagnostic(importDecl, 0 /* Local */, unuseds.length === 1
                        ? ts.createDiagnosticForNode(importDecl, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.idText(ts.first(unuseds).name))
                        : ts.createDiagnosticForNode(importDecl, ts.Diagnostics.All_imports_in_import_declaration_are_unused));
                }
                else {
                    for (var _i = 0, unuseds_1 = unuseds; _i < unuseds_1.length; _i++) {
                        var unused = unuseds_1[_i];
                        errorUnusedLocal(unused, ts.idText(unused.name), addDiagnostic);
                    }
                }
            });
            unusedDestructures.forEach(function (_a) {
                var bindingPattern = _a[0], bindingElements = _a[1];
                var kind = tryGetRootParameterDeclaration(bindingPattern.parent) ? 1 /* Parameter */ : 0 /* Local */;
                if (bindingPattern.elements.length === bindingElements.length) {
                    if (bindingElements.length === 1 && bindingPattern.parent.kind === 242 /* VariableDeclaration */ && bindingPattern.parent.parent.kind === 243 /* VariableDeclarationList */) {
                        addToGroup(unusedVariables, bindingPattern.parent.parent, bindingPattern.parent, getNodeId);
                    }
                    else {
                        addDiagnostic(bindingPattern, kind, bindingElements.length === 1
                            ? ts.createDiagnosticForNode(bindingPattern, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(ts.first(bindingElements).name))
                            : ts.createDiagnosticForNode(bindingPattern, ts.Diagnostics.All_destructured_elements_are_unused));
                    }
                }
                else {
                    for (var _i = 0, bindingElements_1 = bindingElements; _i < bindingElements_1.length; _i++) {
                        var e = bindingElements_1[_i];
                        addDiagnostic(e, kind, ts.createDiagnosticForNode(e, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(e.name)));
                    }
                }
            });
            unusedVariables.forEach(function (_a) {
                var declarationList = _a[0], declarations = _a[1];
                if (declarationList.declarations.length === declarations.length) {
                    addDiagnostic(declarationList, 0 /* Local */, declarations.length === 1
                        ? ts.createDiagnosticForNode(ts.first(declarations).name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(ts.first(declarations).name))
                        : ts.createDiagnosticForNode(declarationList.parent.kind === 225 /* VariableStatement */ ? declarationList.parent : declarationList, ts.Diagnostics.All_variables_are_unused));
                }
                else {
                    for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) {
                        var decl = declarations_5[_i];
                        addDiagnostic(decl, 0 /* Local */, ts.createDiagnosticForNode(decl, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(decl.name)));
                    }
                }
            });
        }
        function bindingNameText(name) {
            switch (name.kind) {
                case 75 /* Identifier */:
                    return ts.idText(name);
                case 190 /* ArrayBindingPattern */:
                case 189 /* ObjectBindingPattern */:
                    return bindingNameText(ts.cast(ts.first(name.elements), ts.isBindingElement).name);
                default:
                    return ts.Debug.assertNever(name);
            }
        }
        function isImportedDeclaration(node) {
            return node.kind === 255 /* ImportClause */ || node.kind === 258 /* ImportSpecifier */ || node.kind === 256 /* NamespaceImport */;
        }
        function importClauseFromImported(decl) {
            return decl.kind === 255 /* ImportClause */ ? decl : decl.kind === 256 /* NamespaceImport */ ? decl.parent : decl.parent.parent;
        }
        function checkBlock(node) {
            // Grammar checking for SyntaxKind.Block
            if (node.kind === 223 /* Block */) {
                checkGrammarStatementInAmbientContext(node);
            }
            if (ts.isFunctionOrModuleBlock(node)) {
                var saveFlowAnalysisDisabled = flowAnalysisDisabled;
                ts.forEach(node.statements, checkSourceElement);
                flowAnalysisDisabled = saveFlowAnalysisDisabled;
            }
            else {
                ts.forEach(node.statements, checkSourceElement);
            }
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkCollisionWithArgumentsInGeneratedCode(node) {
            // no rest parameters \ declaration context \ overload - no codegen impact
            if (languageVersion >= 2 /* ES2015 */ || compilerOptions.noEmit || !ts.hasRestParameter(node) || node.flags & 8388608 /* Ambient */ || ts.nodeIsMissing(node.body)) {
                return;
            }
            ts.forEach(node.parameters, function (p) {
                if (p.name && !ts.isBindingPattern(p.name) && p.name.escapedText === argumentsSymbol.escapedName) {
                    error(p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters);
                }
            });
        }
        function needCollisionCheckForIdentifier(node, identifier, name) {
            if (!(identifier && identifier.escapedText === name)) {
                return false;
            }
            if (node.kind === 159 /* PropertyDeclaration */ ||
                node.kind === 158 /* PropertySignature */ ||
                node.kind === 161 /* MethodDeclaration */ ||
                node.kind === 160 /* MethodSignature */ ||
                node.kind === 163 /* GetAccessor */ ||
                node.kind === 164 /* SetAccessor */) {
                // it is ok to have member named '_super' or '_this' - member access is always qualified
                return false;
            }
            if (node.flags & 8388608 /* Ambient */) {
                // ambient context - no codegen impact
                return false;
            }
            var root = ts.getRootDeclaration(node);
            if (root.kind === 156 /* Parameter */ && ts.nodeIsMissing(root.parent.body)) {
                // just an overload - no codegen impact
                return false;
            }
            return true;
        }
        // this function will run after checking the source file so 'CaptureThis' is correct for all nodes
        function checkIfThisIsCapturedInEnclosingScope(node) {
            ts.findAncestor(node, function (current) {
                if (getNodeCheckFlags(current) & 4 /* CaptureThis */) {
                    var isDeclaration_1 = node.kind !== 75 /* Identifier */;
                    if (isDeclaration_1) {
                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference);
                    }
                    return true;
                }
                return false;
            });
        }
        function checkIfNewTargetIsCapturedInEnclosingScope(node) {
            ts.findAncestor(node, function (current) {
                if (getNodeCheckFlags(current) & 8 /* CaptureNewTarget */) {
                    var isDeclaration_2 = node.kind !== 75 /* Identifier */;
                    if (isDeclaration_2) {
                        error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference);
                    }
                    else {
                        error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference);
                    }
                    return true;
                }
                return false;
            });
        }
        function checkWeakMapCollision(node) {
            var enclosingBlockScope = ts.getEnclosingBlockScopeContainer(node);
            if (getNodeCheckFlags(enclosingBlockScope) & 67108864 /* ContainsClassWithPrivateIdentifiers */) {
                error(node, ts.Diagnostics.Compiler_reserves_name_0_when_emitting_private_identifier_downlevel, "WeakMap");
            }
        }
        function checkCollisionWithRequireExportsInGeneratedCode(node, name) {
            // No need to check for require or exports for ES6 modules and later
            if (moduleKind >= ts.ModuleKind.ES2015 || compilerOptions.noEmit) {
                return;
            }
            if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (ts.isModuleDeclaration(node) && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                return;
            }
            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
            var parent = getDeclarationContainer(node);
            if (parent.kind === 290 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent)) {
                // If the declaration happens to be in external module, report error that require and exports are reserved keywords
                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name));
            }
        }
        function checkCollisionWithGlobalPromiseInGeneratedCode(node, name) {
            if (languageVersion >= 4 /* ES2017 */ || compilerOptions.noEmit || !needCollisionCheckForIdentifier(node, name, "Promise")) {
                return;
            }
            // Uninstantiated modules shouldnt do this check
            if (ts.isModuleDeclaration(node) && ts.getModuleInstanceState(node) !== 1 /* Instantiated */) {
                return;
            }
            // In case of variable declaration, node.parent is variable statement so look at the variable statement's parent
            var parent = getDeclarationContainer(node);
            if (parent.kind === 290 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent) && parent.flags & 2048 /* HasAsyncFunctions */) {
                // If the declaration happens to be in external module, report error that Promise is a reserved identifier.
                error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions, ts.declarationNameToString(name), ts.declarationNameToString(name));
            }
        }
        function checkVarDeclaredNamesNotShadowed(node) {
            // - ScriptBody : StatementList
            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
            // also occurs in the VarDeclaredNames of StatementList.
            // - Block : { StatementList }
            // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList
            // also occurs in the VarDeclaredNames of StatementList.
            // Variable declarations are hoisted to the top of their function scope. They can shadow
            // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition
            // by the binder as the declaration scope is different.
            // A non-initialized declaration is a no-op as the block declaration will resolve before the var
            // declaration. the problem is if the declaration has an initializer. this will act as a write to the
            // block declared value. this is fine for let, but not const.
            // Only consider declarations with initializers, uninitialized const declarations will not
            // step on a let/const variable.
            // Do not consider const and const declarations, as duplicate block-scoped declarations
            // are handled by the binder.
            // We are only looking for const declarations that step on let\const declarations from a
            // different scope. e.g.:
            //      {
            //          const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration
            //          const x = 0; // symbol for this declaration will be 'symbol'
            //      }
            // skip block-scoped variables and parameters
            if ((ts.getCombinedNodeFlags(node) & 3 /* BlockScoped */) !== 0 || ts.isParameterDeclaration(node)) {
                return;
            }
            // skip variable declarations that don't have initializers
            // NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern
            // so we'll always treat binding elements as initialized
            if (node.kind === 242 /* VariableDeclaration */ && !node.initializer) {
                return;
            }
            var symbol = getSymbolOfNode(node);
            if (symbol.flags & 1 /* FunctionScopedVariable */) {
                if (!ts.isIdentifier(node.name))
                    return ts.Debug.fail();
                var localDeclarationSymbol = resolveName(node, node.name.escapedText, 3 /* Variable */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
                if (localDeclarationSymbol &&
                    localDeclarationSymbol !== symbol &&
                    localDeclarationSymbol.flags & 2 /* BlockScopedVariable */) {
                    if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & 3 /* BlockScoped */) {
                        var varDeclList = ts.getAncestor(localDeclarationSymbol.valueDeclaration, 243 /* VariableDeclarationList */);
                        var container = varDeclList.parent.kind === 225 /* VariableStatement */ && varDeclList.parent.parent
                            ? varDeclList.parent.parent
                            : undefined;
                        // names of block-scoped and function scoped variables can collide only
                        // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting)
                        var namesShareScope = container &&
                            (container.kind === 223 /* Block */ && ts.isFunctionLike(container.parent) ||
                                container.kind === 250 /* ModuleBlock */ ||
                                container.kind === 249 /* ModuleDeclaration */ ||
                                container.kind === 290 /* SourceFile */);
                        // here we know that function scoped variable is shadowed by block scoped one
                        // if they are defined in the same scope - binder has already reported redeclaration error
                        // otherwise if variable has an initializer - show error that initialization will fail
                        // since LHS will be block scoped name instead of function scoped
                        if (!namesShareScope) {
                            var name = symbolToString(localDeclarationSymbol);
                            error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
                        }
                    }
                }
            }
        }
        function convertAutoToAny(type) {
            return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type;
        }
        // Check variable, parameter, or property declaration
        function checkVariableLikeDeclaration(node) {
            checkDecorators(node);
            if (!ts.isBindingElement(node)) {
                checkSourceElement(node.type);
            }
            // JSDoc `function(string, string): string` syntax results in parameters with no name
            if (!node.name) {
                return;
            }
            // For a computed property, just check the initializer and exit
            // Do not use hasDynamicName here, because that returns false for well known symbols.
            // We want to perform checkComputedPropertyName for all computed properties, including
            // well known symbols.
            if (node.name.kind === 154 /* ComputedPropertyName */) {
                checkComputedPropertyName(node.name);
                if (node.initializer) {
                    checkExpressionCached(node.initializer);
                }
            }
            if (node.kind === 191 /* BindingElement */) {
                if (node.parent.kind === 189 /* ObjectBindingPattern */ && languageVersion < 99 /* ESNext */) {
                    checkExternalEmitHelpers(node, 4 /* Rest */);
                }
                // check computed properties inside property names of binding elements
                if (node.propertyName && node.propertyName.kind === 154 /* ComputedPropertyName */) {
                    checkComputedPropertyName(node.propertyName);
                }
                // check private/protected variable access
                var parent = node.parent.parent;
                var parentType = getTypeForBindingElementParent(parent);
                var name = node.propertyName || node.name;
                if (parentType && !ts.isBindingPattern(name)) {
                    var exprType = getLiteralTypeFromPropertyName(name);
                    if (isTypeUsableAsPropertyName(exprType)) {
                        var nameText = getPropertyNameFromType(exprType);
                        var property = getPropertyOfType(parentType, nameText);
                        if (property) {
                            markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
                            checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === 102 /* SuperKeyword */, parentType, property);
                        }
                    }
                }
            }
            // For a binding pattern, check contained binding elements
            if (ts.isBindingPattern(node.name)) {
                if (node.name.kind === 190 /* ArrayBindingPattern */ && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) {
                    checkExternalEmitHelpers(node, 512 /* Read */);
                }
                ts.forEach(node.name.elements, checkSourceElement);
            }
            // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body
            if (node.initializer && ts.getRootDeclaration(node).kind === 156 /* Parameter */ && ts.nodeIsMissing(ts.getContainingFunction(node).body)) {
                error(node, ts.Diagnostics.A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation);
                return;
            }
            // For a binding pattern, validate the initializer and exit
            if (ts.isBindingPattern(node.name)) {
                var needCheckInitializer = node.initializer && node.parent.parent.kind !== 231 /* ForInStatement */;
                var needCheckWidenedType = node.name.elements.length === 0;
                if (needCheckInitializer || needCheckWidenedType) {
                    // Don't validate for-in initializer as it is already an error
                    var widenedType = getWidenedTypeForVariableLikeDeclaration(node);
                    if (needCheckInitializer) {
                        var initializerType = checkExpressionCached(node.initializer);
                        if (strictNullChecks && needCheckWidenedType) {
                            checkNonNullNonVoidType(initializerType, node);
                        }
                        else {
                            checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
                        }
                    }
                    // check the binding pattern with empty elements
                    if (needCheckWidenedType) {
                        if (ts.isArrayBindingPattern(node.name)) {
                            checkIteratedTypeOrElementType(65 /* Destructuring */, widenedType, undefinedType, node);
                        }
                        else if (strictNullChecks) {
                            checkNonNullNonVoidType(widenedType, node);
                        }
                    }
                }
                return;
            }
            var symbol = getSymbolOfNode(node);
            var type = convertAutoToAny(getTypeOfSymbol(symbol));
            if (node === symbol.valueDeclaration) {
                // Node is the primary declaration of the symbol, just validate the initializer
                // Don't validate for-in initializer as it is already an error
                var initializer = ts.getEffectiveInitializer(node);
                if (initializer) {
                    var isJSObjectLiteralInitializer = ts.isInJSFile(node) &&
                        ts.isObjectLiteralExpression(initializer) &&
                        (initializer.properties.length === 0 || ts.isPrototypeAccess(node.name)) &&
                        ts.hasEntries(symbol.exports);
                    if (!isJSObjectLiteralInitializer && node.parent.parent.kind !== 231 /* ForInStatement */) {
                        checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(initializer), type, node, initializer, /*headMessage*/ undefined);
                    }
                }
                if (symbol.declarations.length > 1) {
                    if (ts.some(symbol.declarations, function (d) { return d !== node && ts.isVariableLike(d) && !areDeclarationFlagsIdentical(d, node); })) {
                        error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
                    }
                }
            }
            else {
                // Node is a secondary declaration, check that type is identical to primary declaration and check that
                // initializer is consistent with type associated with the node
                var declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
                if (type !== errorType && declarationType !== errorType &&
                    !isTypeIdenticalTo(type, declarationType) &&
                    !(symbol.flags & 67108864 /* Assignment */)) {
                    errorNextVariableOrPropertyDeclarationMustHaveSameType(symbol.valueDeclaration, type, node, declarationType);
                }
                if (node.initializer) {
                    checkTypeAssignableToAndOptionallyElaborate(checkExpressionCached(node.initializer), declarationType, node, node.initializer, /*headMessage*/ undefined);
                }
                if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) {
                    error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name));
                }
            }
            if (node.kind !== 159 /* PropertyDeclaration */ && node.kind !== 158 /* PropertySignature */) {
                // We know we don't have a binding pattern or computed name here
                checkExportsOnMergedDeclarations(node);
                if (node.kind === 242 /* VariableDeclaration */ || node.kind === 191 /* BindingElement */) {
                    checkVarDeclaredNamesNotShadowed(node);
                }
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                if (!compilerOptions.noEmit && languageVersion < 99 /* ESNext */ && needCollisionCheckForIdentifier(node, node.name, "WeakMap")) {
                    potentialWeakMapCollisions.push(node);
                }
            }
        }
        function errorNextVariableOrPropertyDeclarationMustHaveSameType(firstDeclaration, firstType, nextDeclaration, nextType) {
            var nextDeclarationName = ts.getNameOfDeclaration(nextDeclaration);
            var message = nextDeclaration.kind === 159 /* PropertyDeclaration */ || nextDeclaration.kind === 158 /* PropertySignature */
                ? ts.Diagnostics.Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2
                : ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2;
            var declName = ts.declarationNameToString(nextDeclarationName);
            var err = error(nextDeclarationName, message, declName, typeToString(firstType), typeToString(nextType));
            if (firstDeclaration) {
                ts.addRelatedInfo(err, ts.createDiagnosticForNode(firstDeclaration, ts.Diagnostics._0_was_also_declared_here, declName));
            }
        }
        function areDeclarationFlagsIdentical(left, right) {
            if ((left.kind === 156 /* Parameter */ && right.kind === 242 /* VariableDeclaration */) ||
                (left.kind === 242 /* VariableDeclaration */ && right.kind === 156 /* Parameter */)) {
                // Differences in optionality between parameters and variables are allowed.
                return true;
            }
            if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) {
                return false;
            }
            var interestingFlags = 8 /* Private */ |
                16 /* Protected */ |
                256 /* Async */ |
                128 /* Abstract */ |
                64 /* Readonly */ |
                32 /* Static */;
            return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags);
        }
        function checkVariableDeclaration(node) {
            checkGrammarVariableDeclaration(node);
            return checkVariableLikeDeclaration(node);
        }
        function checkBindingElement(node) {
            checkGrammarBindingElement(node);
            return checkVariableLikeDeclaration(node);
        }
        function checkVariableStatement(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarVariableDeclarationList(node.declarationList))
                checkGrammarForDisallowedLetOrConstStatement(node);
            ts.forEach(node.declarationList.declarations, checkSourceElement);
        }
        function checkExpressionStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkExpression(node.expression);
        }
        function checkIfStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            var type = checkTruthinessExpression(node.expression);
            checkTestingKnownTruthyCallableType(node.expression, node.thenStatement, type);
            checkSourceElement(node.thenStatement);
            if (node.thenStatement.kind === 224 /* EmptyStatement */) {
                error(node.thenStatement, ts.Diagnostics.The_body_of_an_if_statement_cannot_be_the_empty_statement);
            }
            checkSourceElement(node.elseStatement);
        }
        function checkTestingKnownTruthyCallableType(condExpr, body, type) {
            if (!strictNullChecks) {
                return;
            }
            var testedNode = ts.isIdentifier(condExpr)
                ? condExpr
                : ts.isPropertyAccessExpression(condExpr)
                    ? condExpr.name
                    : undefined;
            if (!testedNode) {
                return;
            }
            var possiblyFalsy = getFalsyFlags(type);
            if (possiblyFalsy) {
                return;
            }
            // While it technically should be invalid for any known-truthy value
            // to be tested, we de-scope to functions unrefenced in the block as a
            // heuristic to identify the most common bugs. There are too many
            // false positives for values sourced from type definitions without
            // strictNullChecks otherwise.
            var callSignatures = getSignaturesOfType(type, 0 /* Call */);
            if (callSignatures.length === 0) {
                return;
            }
            var testedFunctionSymbol = getSymbolAtLocation(testedNode);
            if (!testedFunctionSymbol) {
                return;
            }
            var functionIsUsedInBody = ts.forEachChild(body, function check(childNode) {
                if (ts.isIdentifier(childNode)) {
                    var childSymbol = getSymbolAtLocation(childNode);
                    if (childSymbol && childSymbol === testedFunctionSymbol) {
                        // If the test was a simple identifier, the above check is sufficient
                        if (ts.isIdentifier(condExpr)) {
                            return true;
                        }
                        // Otherwise we need to ensure the symbol is called on the same target
                        var testedExpression = testedNode.parent;
                        var childExpression = childNode.parent;
                        while (testedExpression && childExpression) {
                            if (ts.isIdentifier(testedExpression) && ts.isIdentifier(childExpression) ||
                                testedExpression.kind === 104 /* ThisKeyword */ && childExpression.kind === 104 /* ThisKeyword */) {
                                return getSymbolAtLocation(testedExpression) === getSymbolAtLocation(childExpression);
                            }
                            if (ts.isPropertyAccessExpression(testedExpression) && ts.isPropertyAccessExpression(childExpression)) {
                                if (getSymbolAtLocation(testedExpression.name) !== getSymbolAtLocation(childExpression.name)) {
                                    return false;
                                }
                                childExpression = childExpression.expression;
                                testedExpression = testedExpression.expression;
                            }
                            else {
                                return false;
                            }
                        }
                    }
                }
                return ts.forEachChild(childNode, check);
            });
            if (!functionIsUsedInBody) {
                error(condExpr, ts.Diagnostics.This_condition_will_always_return_true_since_the_function_is_always_defined_Did_you_mean_to_call_it_instead);
            }
        }
        function checkDoStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkSourceElement(node.statement);
            checkTruthinessExpression(node.expression);
        }
        function checkWhileStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkTruthinessExpression(node.expression);
            checkSourceElement(node.statement);
        }
        function checkTruthinessOfType(type, node) {
            if (type.flags & 16384 /* Void */) {
                error(node, ts.Diagnostics.An_expression_of_type_void_cannot_be_tested_for_truthiness);
            }
            return type;
        }
        function checkTruthinessExpression(node, checkMode) {
            return checkTruthinessOfType(checkExpression(node, checkMode), node);
        }
        function checkForStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.initializer && node.initializer.kind === 243 /* VariableDeclarationList */) {
                    checkGrammarVariableDeclarationList(node.initializer);
                }
            }
            if (node.initializer) {
                if (node.initializer.kind === 243 /* VariableDeclarationList */) {
                    ts.forEach(node.initializer.declarations, checkVariableDeclaration);
                }
                else {
                    checkExpression(node.initializer);
                }
            }
            if (node.condition)
                checkTruthinessExpression(node.condition);
            if (node.incrementor)
                checkExpression(node.incrementor);
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForOfStatement(node) {
            checkGrammarForInOrForOfStatement(node);
            if (node.awaitModifier) {
                var functionFlags = ts.getFunctionFlags(ts.getContainingFunction(node));
                if ((functionFlags & (4 /* Invalid */ | 2 /* Async */)) === 2 /* Async */ && languageVersion < 99 /* ESNext */) {
                    // for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper
                    checkExternalEmitHelpers(node, 32768 /* ForAwaitOfIncludes */);
                }
            }
            else if (compilerOptions.downlevelIteration && languageVersion < 2 /* ES2015 */) {
                // for..of prior to ES2015 requires the __values helper when downlevelIteration is enabled
                checkExternalEmitHelpers(node, 256 /* ForOfIncludes */);
            }
            // Check the LHS and RHS
            // If the LHS is a declaration, just check it as a variable declaration, which will in turn check the RHS
            // via checkRightHandSideOfForOf.
            // If the LHS is an expression, check the LHS, as a destructuring assignment or as a reference.
            // Then check that the RHS is assignable to it.
            if (node.initializer.kind === 243 /* VariableDeclarationList */) {
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                var varExpr = node.initializer;
                var iteratedType = checkRightHandSideOfForOf(node);
                // There may be a destructuring assignment on the left side
                if (varExpr.kind === 192 /* ArrayLiteralExpression */ || varExpr.kind === 193 /* ObjectLiteralExpression */) {
                    // iteratedType may be undefined. In this case, we still want to check the structure of
                    // varExpr, in particular making sure it's a valid LeftHandSideExpression. But we'd like
                    // to short circuit the type relation checking as much as possible, so we pass the unknownType.
                    checkDestructuringAssignment(varExpr, iteratedType || errorType);
                }
                else {
                    var leftType = checkExpression(varExpr);
                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_may_not_be_an_optional_property_access);
                    // iteratedType will be undefined if the rightType was missing properties/signatures
                    // required to get its iteratedType (like [Symbol.iterator] or next). This may be
                    // because we accessed properties from anyType, or it may have led to an error inside
                    // getElementTypeOfIterable.
                    if (iteratedType) {
                        checkTypeAssignableToAndOptionallyElaborate(iteratedType, leftType, varExpr, node.expression);
                    }
                }
            }
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForInStatement(node) {
            // Grammar checking
            checkGrammarForInOrForOfStatement(node);
            var rightType = getNonNullableTypeIfNeeded(checkExpression(node.expression));
            // TypeScript 1.0 spec (April 2014): 5.4
            // In a 'for-in' statement of the form
            // for (let VarDecl in Expr) Statement
            //   VarDecl must be a variable declaration without a type annotation that declares a variable of type Any,
            //   and Expr must be an expression of type Any, an object type, or a type parameter type.
            if (node.initializer.kind === 243 /* VariableDeclarationList */) {
                var variable = node.initializer.declarations[0];
                if (variable && ts.isBindingPattern(variable.name)) {
                    error(variable.name, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                checkForInOrForOfVariableDeclaration(node);
            }
            else {
                // In a 'for-in' statement of the form
                // for (Var in Expr) Statement
                //   Var must be an expression classified as a reference of type Any or the String primitive type,
                //   and Expr must be an expression of type Any, an object type, or a type parameter type.
                var varExpr = node.initializer;
                var leftType = checkExpression(varExpr);
                if (varExpr.kind === 192 /* ArrayLiteralExpression */ || varExpr.kind === 193 /* ObjectLiteralExpression */) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern);
                }
                else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) {
                    error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any);
                }
                else {
                    // run check only former check succeeded to avoid cascading errors
                    checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_may_not_be_an_optional_property_access);
                }
            }
            // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
            // in this case error about missing name is already reported - do not report extra one
            if (rightType === neverType || !isTypeAssignableToKind(rightType, 67108864 /* NonPrimitive */ | 58982400 /* InstantiableNonPrimitive */)) {
                error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_but_here_has_type_0, typeToString(rightType));
            }
            checkSourceElement(node.statement);
            if (node.locals) {
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkForInOrForOfVariableDeclaration(iterationStatement) {
            var variableDeclarationList = iterationStatement.initializer;
            // checkGrammarForInOrForOfStatement will check that there is exactly one declaration.
            if (variableDeclarationList.declarations.length >= 1) {
                var decl = variableDeclarationList.declarations[0];
                checkVariableDeclaration(decl);
            }
        }
        function checkRightHandSideOfForOf(statement) {
            var use = statement.awaitModifier ? 15 /* ForAwaitOf */ : 13 /* ForOf */;
            return checkIteratedTypeOrElementType(use, checkNonNullExpression(statement.expression), undefinedType, statement.expression);
        }
        function checkIteratedTypeOrElementType(use, inputType, sentType, errorNode) {
            if (isTypeAny(inputType)) {
                return inputType;
            }
            return getIteratedTypeOrElementType(use, inputType, sentType, errorNode, /*checkAssignability*/ true) || anyType;
        }
        /**
         * When consuming an iterable type in a for..of, spread, or iterator destructuring assignment
         * we want to get the iterated type of an iterable for ES2015 or later, or the iterated type
         * of a iterable (if defined globally) or element type of an array like for ES2015 or earlier.
         */
        function getIteratedTypeOrElementType(use, inputType, sentType, errorNode, checkAssignability) {
            var allowAsyncIterables = (use & 2 /* AllowsAsyncIterablesFlag */) !== 0;
            if (inputType === neverType) {
                reportTypeNotIterableError(errorNode, inputType, allowAsyncIterables); // TODO: GH#18217
                return undefined;
            }
            var uplevelIteration = languageVersion >= 2 /* ES2015 */;
            var downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration;
            // Get the iterated type of an `Iterable<T>` or `IterableIterator<T>` only in ES2015
            // or higher, when inside of an async generator or for-await-if, or when
            // downlevelIteration is requested.
            if (uplevelIteration || downlevelIteration || allowAsyncIterables) {
                // We only report errors for an invalid iterable type in ES2015 or higher.
                var iterationTypes = getIterationTypesOfIterable(inputType, use, uplevelIteration ? errorNode : undefined);
                if (checkAssignability) {
                    if (iterationTypes) {
                        var diagnostic = use & 8 /* ForOfFlag */ ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_for_of_will_always_send_0 :
                            use & 32 /* SpreadFlag */ ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_spread_will_always_send_0 :
                                use & 64 /* DestructuringFlag */ ? ts.Diagnostics.Cannot_iterate_value_because_the_next_method_of_its_iterator_expects_type_1_but_array_destructuring_will_always_send_0 :
                                    use & 16 /* YieldStarFlag */ ? ts.Diagnostics.Cannot_delegate_iteration_to_value_because_the_next_method_of_its_iterator_expects_type_1_but_the_containing_generator_will_always_send_0 :
                                        undefined;
                        if (diagnostic) {
                            checkTypeAssignableTo(sentType, iterationTypes.nextType, errorNode, diagnostic);
                        }
                    }
                }
                if (iterationTypes || uplevelIteration) {
                    return iterationTypes && iterationTypes.yieldType;
                }
            }
            var arrayType = inputType;
            var reportedError = false;
            var hasStringConstituent = false;
            // If strings are permitted, remove any string-like constituents from the array type.
            // This allows us to find other non-string element types from an array unioned with
            // a string.
            if (use & 4 /* AllowsStringInputFlag */) {
                if (arrayType.flags & 1048576 /* Union */) {
                    // After we remove all types that are StringLike, we will know if there was a string constituent
                    // based on whether the result of filter is a new array.
                    var arrayTypes = inputType.types;
                    var filteredTypes = ts.filter(arrayTypes, function (t) { return !(t.flags & 132 /* StringLike */); });
                    if (filteredTypes !== arrayTypes) {
                        arrayType = getUnionType(filteredTypes, 2 /* Subtype */);
                    }
                }
                else if (arrayType.flags & 132 /* StringLike */) {
                    arrayType = neverType;
                }
                hasStringConstituent = arrayType !== inputType;
                if (hasStringConstituent) {
                    if (languageVersion < 1 /* ES5 */) {
                        if (errorNode) {
                            error(errorNode, ts.Diagnostics.Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher);
                            reportedError = true;
                        }
                    }
                    // Now that we've removed all the StringLike types, if no constituents remain, then the entire
                    // arrayOrStringType was a string.
                    if (arrayType.flags & 131072 /* Never */) {
                        return stringType;
                    }
                }
            }
            if (!isArrayLikeType(arrayType)) {
                if (errorNode && !reportedError) {
                    // Which error we report depends on whether we allow strings or if there was a
                    // string constituent. For example, if the input type is number | string, we
                    // want to say that number is not an array type. But if the input was just
                    // number and string input is allowed, we want to say that number is not an
                    // array type or a string type.
                    var yieldType = getIterationTypeOfIterable(use, 0 /* Yield */, inputType, /*errorNode*/ undefined);
                    var _a = !(use & 4 /* AllowsStringInputFlag */) || hasStringConstituent
                        ? downlevelIteration
                            ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]
                            : yieldType
                                ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false]
                                : [ts.Diagnostics.Type_0_is_not_an_array_type, true]
                        : downlevelIteration
                            ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]
                            : yieldType
                                ? [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false]
                                : [ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type, true], defaultDiagnostic = _a[0], maybeMissingAwait = _a[1];
                    errorAndMaybeSuggestAwait(errorNode, maybeMissingAwait && !!getAwaitedTypeOfPromise(arrayType), defaultDiagnostic, typeToString(arrayType));
                }
                return hasStringConstituent ? stringType : undefined;
            }
            var arrayElementType = getIndexTypeOfType(arrayType, 1 /* Number */);
            if (hasStringConstituent && arrayElementType) {
                // This is just an optimization for the case where arrayOrStringType is string | string[]
                if (arrayElementType.flags & 132 /* StringLike */) {
                    return stringType;
                }
                return getUnionType([arrayElementType, stringType], 2 /* Subtype */);
            }
            return arrayElementType;
        }
        /**
         * Gets the requested "iteration type" from an `Iterable`-like or `AsyncIterable`-like type.
         */
        function getIterationTypeOfIterable(use, typeKind, inputType, errorNode) {
            if (isTypeAny(inputType)) {
                return undefined;
            }
            var iterationTypes = getIterationTypesOfIterable(inputType, use, errorNode);
            return iterationTypes && iterationTypes[getIterationTypesKeyFromIterationTypeKind(typeKind)];
        }
        function createIterationTypes(yieldType, returnType, nextType) {
            // `yieldType` and `returnType` are defaulted to `neverType` they each will be combined
            // via `getUnionType` when merging iteration types. `nextType` is defined as `unknownType`
            // as it is combined via `getIntersectionType` when merging iteration types.
            if (yieldType === void 0) { yieldType = neverType; }
            if (returnType === void 0) { returnType = neverType; }
            if (nextType === void 0) { nextType = unknownType; }
            // Use the cache only for intrinsic types to keep it small as they are likely to be
            // more frequently created (i.e. `Iterator<number, void, unknown>`). Iteration types
            // are also cached on the type they are requested for, so we shouldn't need to maintain
            // the cache for less-frequently used types.
            if (yieldType.flags & 67359327 /* Intrinsic */ &&
                returnType.flags & (1 /* Any */ | 131072 /* Never */ | 2 /* Unknown */ | 16384 /* Void */ | 32768 /* Undefined */) &&
                nextType.flags & (1 /* Any */ | 131072 /* Never */ | 2 /* Unknown */ | 16384 /* Void */ | 32768 /* Undefined */)) {
                var id = getTypeListId([yieldType, returnType, nextType]);
                var iterationTypes = iterationTypesCache.get(id);
                if (!iterationTypes) {
                    iterationTypes = { yieldType: yieldType, returnType: returnType, nextType: nextType };
                    iterationTypesCache.set(id, iterationTypes);
                }
                return iterationTypes;
            }
            return { yieldType: yieldType, returnType: returnType, nextType: nextType };
        }
        /**
         * Combines multiple `IterationTypes` records.
         *
         * If `array` is empty or all elements are missing or are references to `noIterationTypes`,
         * then `noIterationTypes` is returned. Otherwise, an `IterationTypes` record is returned
         * for the combined iteration types.
         */
        function combineIterationTypes(array) {
            var yieldTypes;
            var returnTypes;
            var nextTypes;
            for (var _i = 0, array_10 = array; _i < array_10.length; _i++) {
                var iterationTypes = array_10[_i];
                if (iterationTypes === undefined || iterationTypes === noIterationTypes) {
                    continue;
                }
                if (iterationTypes === anyIterationTypes) {
                    return anyIterationTypes;
                }
                yieldTypes = ts.append(yieldTypes, iterationTypes.yieldType);
                returnTypes = ts.append(returnTypes, iterationTypes.returnType);
                nextTypes = ts.append(nextTypes, iterationTypes.nextType);
            }
            if (yieldTypes || returnTypes || nextTypes) {
                return createIterationTypes(yieldTypes && getUnionType(yieldTypes), returnTypes && getUnionType(returnTypes), nextTypes && getIntersectionType(nextTypes));
            }
            return noIterationTypes;
        }
        function getCachedIterationTypes(type, cacheKey) {
            return type[cacheKey];
        }
        function setCachedIterationTypes(type, cacheKey, cachedTypes) {
            return type[cacheKey] = cachedTypes;
        }
        /**
         * Gets the *yield*, *return*, and *next* types from an `Iterable`-like or `AsyncIterable`-like type.
         *
         * At every level that involves analyzing return types of signatures, we union the return types of all the signatures.
         *
         * Another thing to note is that at any step of this process, we could run into a dead end,
         * meaning either the property is missing, or we run into the anyType. If either of these things
         * happens, we return `undefined` to signal that we could not find the iteration type. If a property
         * is missing, and the previous step did not result in `any`, then we also give an error if the
         * caller requested it. Then the caller can decide what to do in the case where there is no iterated
         * type.
         *
         * For a **for-of** statement, `yield*` (in a normal generator), spread, array
         * destructuring, or normal generator we will only ever look for a `[Symbol.iterator]()`
         * method.
         *
         * For an async generator we will only ever look at the `[Symbol.asyncIterator]()` method.
         *
         * For a **for-await-of** statement or a `yield*` in an async generator we will look for
         * the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method.
         */
        function getIterationTypesOfIterable(type, use, errorNode) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            if (!(type.flags & 1048576 /* Union */)) {
                var iterationTypes_1 = getIterationTypesOfIterableWorker(type, use, errorNode);
                if (iterationTypes_1 === noIterationTypes) {
                    if (errorNode) {
                        reportTypeNotIterableError(errorNode, type, !!(use & 2 /* AllowsAsyncIterablesFlag */));
                    }
                    return undefined;
                }
                return iterationTypes_1;
            }
            var cacheKey = use & 2 /* AllowsAsyncIterablesFlag */ ? "iterationTypesOfAsyncIterable" : "iterationTypesOfIterable";
            var cachedTypes = getCachedIterationTypes(type, cacheKey);
            if (cachedTypes)
                return cachedTypes === noIterationTypes ? undefined : cachedTypes;
            var allIterationTypes;
            for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
                var constituent = _a[_i];
                var iterationTypes_2 = getIterationTypesOfIterableWorker(constituent, use, errorNode);
                if (iterationTypes_2 === noIterationTypes) {
                    if (errorNode) {
                        reportTypeNotIterableError(errorNode, type, !!(use & 2 /* AllowsAsyncIterablesFlag */));
                        errorNode = undefined;
                    }
                }
                else {
                    allIterationTypes = ts.append(allIterationTypes, iterationTypes_2);
                }
            }
            var iterationTypes = allIterationTypes ? combineIterationTypes(allIterationTypes) : noIterationTypes;
            setCachedIterationTypes(type, cacheKey, iterationTypes);
            return iterationTypes === noIterationTypes ? undefined : iterationTypes;
        }
        function getAsyncFromSyncIterationTypes(iterationTypes, errorNode) {
            if (iterationTypes === noIterationTypes)
                return noIterationTypes;
            if (iterationTypes === anyIterationTypes)
                return anyIterationTypes;
            var yieldType = iterationTypes.yieldType, returnType = iterationTypes.returnType, nextType = iterationTypes.nextType;
            return createIterationTypes(getAwaitedType(yieldType, errorNode) || anyType, getAwaitedType(returnType, errorNode) || anyType, nextType);
        }
        /**
         * Gets the *yield*, *return*, and *next* types from a non-union type.
         *
         * If we are unable to find the *yield*, *return*, and *next* types, `noIterationTypes` is
         * returned to indicate to the caller that it should report an error. Otherwise, an
         * `IterationTypes` record is returned.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterable` instead.
         */
        function getIterationTypesOfIterableWorker(type, use, errorNode) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            if (use & 2 /* AllowsAsyncIterablesFlag */) {
                var iterationTypes = getIterationTypesOfIterableCached(type, asyncIterationTypesResolver) ||
                    getIterationTypesOfIterableFast(type, asyncIterationTypesResolver);
                if (iterationTypes) {
                    return iterationTypes;
                }
            }
            if (use & 1 /* AllowsSyncIterablesFlag */) {
                var iterationTypes = getIterationTypesOfIterableCached(type, syncIterationTypesResolver) ||
                    getIterationTypesOfIterableFast(type, syncIterationTypesResolver);
                if (iterationTypes) {
                    if (use & 2 /* AllowsAsyncIterablesFlag */) {
                        // for a sync iterable in an async context, only use the cached types if they are valid.
                        if (iterationTypes !== noIterationTypes) {
                            return setCachedIterationTypes(type, "iterationTypesOfAsyncIterable", getAsyncFromSyncIterationTypes(iterationTypes, errorNode));
                        }
                    }
                    else {
                        return iterationTypes;
                    }
                }
            }
            if (use & 2 /* AllowsAsyncIterablesFlag */) {
                var iterationTypes = getIterationTypesOfIterableSlow(type, asyncIterationTypesResolver, errorNode);
                if (iterationTypes !== noIterationTypes) {
                    return iterationTypes;
                }
            }
            if (use & 1 /* AllowsSyncIterablesFlag */) {
                var iterationTypes = getIterationTypesOfIterableSlow(type, syncIterationTypesResolver, errorNode);
                if (iterationTypes !== noIterationTypes) {
                    if (use & 2 /* AllowsAsyncIterablesFlag */) {
                        return setCachedIterationTypes(type, "iterationTypesOfAsyncIterable", iterationTypes
                            ? getAsyncFromSyncIterationTypes(iterationTypes, errorNode)
                            : noIterationTypes);
                    }
                    else {
                        return iterationTypes;
                    }
                }
            }
            return noIterationTypes;
        }
        /**
         * Gets the *yield*, *return*, and *next* types of an `Iterable`-like or
         * `AsyncIterable`-like type from the cache.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterable` instead.
         */
        function getIterationTypesOfIterableCached(type, resolver) {
            return getCachedIterationTypes(type, resolver.iterableCacheKey);
        }
        function getIterationTypesOfGlobalIterableType(globalType, resolver) {
            var globalIterationTypes = getIterationTypesOfIterableCached(globalType, resolver) ||
                getIterationTypesOfIterableSlow(globalType, resolver, /*errorNode*/ undefined);
            return globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes;
        }
        /**
         * Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
         * type from from common heuristics.
         *
         * If we previously analyzed this type and found no iteration types, `noIterationTypes` is
         * returned. If we found iteration types, an `IterationTypes` record is returned.
         * Otherwise, we return `undefined` to indicate to the caller it should perform a more
         * exhaustive analysis.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterable` instead.
         */
        function getIterationTypesOfIterableFast(type, resolver) {
            // As an optimization, if the type is an instantiation of one of the following global types, then
            // just grab its related type argument:
            // - `Iterable<T>` or `AsyncIterable<T>`
            // - `IterableIterator<T>` or `AsyncIterableIterator<T>`
            var globalType;
            if (isReferenceToType(type, globalType = resolver.getGlobalIterableType(/*reportErrors*/ false)) ||
                isReferenceToType(type, globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false))) {
                var yieldType = getTypeArguments(type)[0];
                // The "return" and "next" types of `Iterable` and `IterableIterator` are defined by the
                // iteration types of their `[Symbol.iterator]()` method. The same is true for their async cousins.
                // While we define these as `any` and `undefined` in our libs by default, a custom lib *could* use
                // different definitions.
                var _a = getIterationTypesOfGlobalIterableType(globalType, resolver), returnType = _a.returnType, nextType = _a.nextType;
                return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(yieldType, returnType, nextType));
            }
            // As an optimization, if the type is an instantiation of the following global type, then
            // just grab its related type arguments:
            // - `Generator<T, TReturn, TNext>` or `AsyncGenerator<T, TReturn, TNext>`
            if (isReferenceToType(type, resolver.getGlobalGeneratorType(/*reportErrors*/ false))) {
                var _b = getTypeArguments(type), yieldType = _b[0], returnType = _b[1], nextType = _b[2];
                return setCachedIterationTypes(type, resolver.iterableCacheKey, createIterationTypes(yieldType, returnType, nextType));
            }
        }
        /**
         * Gets the *yield*, *return*, and *next* types of an `Iterable`-like or `AsyncIterable`-like
         * type from its members.
         *
         * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
         * record is returned. Otherwise, `noIterationTypes` is returned.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterable` instead.
         */
        function getIterationTypesOfIterableSlow(type, resolver, errorNode) {
            var _a;
            var method = getPropertyOfType(type, ts.getPropertyNameForKnownSymbolName(resolver.iteratorSymbolName));
            var methodType = method && !(method.flags & 16777216 /* Optional */) ? getTypeOfSymbol(method) : undefined;
            if (isTypeAny(methodType)) {
                return setCachedIterationTypes(type, resolver.iterableCacheKey, anyIterationTypes);
            }
            var signatures = methodType ? getSignaturesOfType(methodType, 0 /* Call */) : undefined;
            if (!ts.some(signatures)) {
                return setCachedIterationTypes(type, resolver.iterableCacheKey, noIterationTypes);
            }
            var iteratorType = getUnionType(ts.map(signatures, getReturnTypeOfSignature), 2 /* Subtype */);
            var iterationTypes = (_a = getIterationTypesOfIterator(iteratorType, resolver, errorNode)) !== null && _a !== void 0 ? _a : noIterationTypes;
            return setCachedIterationTypes(type, resolver.iterableCacheKey, iterationTypes);
        }
        function reportTypeNotIterableError(errorNode, type, allowAsyncIterables) {
            var message = allowAsyncIterables
                ? ts.Diagnostics.Type_0_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator
                : ts.Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator;
            errorAndMaybeSuggestAwait(errorNode, !!getAwaitedTypeOfPromise(type), message, typeToString(type));
        }
        /**
         * Gets the *yield*, *return*, and *next* types from an `Iterator`-like or `AsyncIterator`-like type.
         *
         * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
         * record is returned. Otherwise, `undefined` is returned.
         */
        function getIterationTypesOfIterator(type, resolver, errorNode) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            var iterationTypes = getIterationTypesOfIteratorCached(type, resolver) ||
                getIterationTypesOfIteratorFast(type, resolver) ||
                getIterationTypesOfIteratorSlow(type, resolver, errorNode);
            return iterationTypes === noIterationTypes ? undefined : iterationTypes;
        }
        /**
         * Gets the iteration types of an `Iterator`-like or `AsyncIterator`-like type from the
         * cache.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterator` instead.
         */
        function getIterationTypesOfIteratorCached(type, resolver) {
            return getCachedIterationTypes(type, resolver.iteratorCacheKey);
        }
        /**
         * Gets the iteration types of an `Iterator`-like or `AsyncIterator`-like type from the
         * cache or from common heuristics.
         *
         * If we previously analyzed this type and found no iteration types, `noIterationTypes` is
         * returned. If we found iteration types, an `IterationTypes` record is returned.
         * Otherwise, we return `undefined` to indicate to the caller it should perform a more
         * exhaustive analysis.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterator` instead.
         */
        function getIterationTypesOfIteratorFast(type, resolver) {
            // As an optimization, if the type is an instantiation of one of the following global types,
            // then just grab its related type argument:
            // - `IterableIterator<T>` or `AsyncIterableIterator<T>`
            // - `Iterator<T, TReturn, TNext>` or `AsyncIterator<T, TReturn, TNext>`
            // - `Generator<T, TReturn, TNext>` or `AsyncGenerator<T, TReturn, TNext>`
            var globalType = resolver.getGlobalIterableIteratorType(/*reportErrors*/ false);
            if (isReferenceToType(type, globalType)) {
                var yieldType = getTypeArguments(type)[0];
                // The "return" and "next" types of `IterableIterator` and `AsyncIterableIterator` are defined by the
                // iteration types of their `next`, `return`, and `throw` methods. While we define these as `any`
                // and `undefined` in our libs by default, a custom lib *could* use different definitions.
                var globalIterationTypes = getIterationTypesOfIteratorCached(globalType, resolver) ||
                    getIterationTypesOfIteratorSlow(globalType, resolver, /*errorNode*/ undefined);
                var _a = globalIterationTypes === noIterationTypes ? defaultIterationTypes : globalIterationTypes, returnType = _a.returnType, nextType = _a.nextType;
                return setCachedIterationTypes(type, resolver.iteratorCacheKey, createIterationTypes(yieldType, returnType, nextType));
            }
            if (isReferenceToType(type, resolver.getGlobalIteratorType(/*reportErrors*/ false)) ||
                isReferenceToType(type, resolver.getGlobalGeneratorType(/*reportErrors*/ false))) {
                var _b = getTypeArguments(type), yieldType = _b[0], returnType = _b[1], nextType = _b[2];
                return setCachedIterationTypes(type, resolver.iteratorCacheKey, createIterationTypes(yieldType, returnType, nextType));
            }
        }
        function isIteratorResult(type, kind) {
            // From https://tc39.github.io/ecma262/#sec-iteratorresult-interface:
            // > [done] is the result status of an iterator `next` method call. If the end of the iterator was reached `done` is `true`.
            // > If the end was not reached `done` is `false` and a value is available.
            // > If a `done` property (either own or inherited) does not exist, it is consider to have the value `false`.
            var doneType = getTypeOfPropertyOfType(type, "done") || falseType;
            return isTypeAssignableTo(kind === 0 /* Yield */ ? falseType : trueType, doneType);
        }
        function isYieldIteratorResult(type) {
            return isIteratorResult(type, 0 /* Yield */);
        }
        function isReturnIteratorResult(type) {
            return isIteratorResult(type, 1 /* Return */);
        }
        /**
         * Gets the *yield* and *return* types of an `IteratorResult`-like type.
         *
         * If we are unable to determine a *yield* or a *return* type, `noIterationTypes` is
         * returned to indicate to the caller that it should handle the error. Otherwise, an
         * `IterationTypes` record is returned.
         */
        function getIterationTypesOfIteratorResult(type) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            var cachedTypes = getCachedIterationTypes(type, "iterationTypesOfIteratorResult");
            if (cachedTypes) {
                return cachedTypes;
            }
            // As an optimization, if the type is an instantiation of one of the global `IteratorYieldResult<T>`
            // or `IteratorReturnResult<TReturn>` types, then just grab its type argument.
            if (isReferenceToType(type, getGlobalIteratorYieldResultType(/*reportErrors*/ false))) {
                var yieldType_1 = getTypeArguments(type)[0];
                return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", createIterationTypes(yieldType_1, /*returnType*/ undefined, /*nextType*/ undefined));
            }
            if (isReferenceToType(type, getGlobalIteratorReturnResultType(/*reportErrors*/ false))) {
                var returnType_1 = getTypeArguments(type)[0];
                return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", createIterationTypes(/*yieldType*/ undefined, returnType_1, /*nextType*/ undefined));
            }
            // Choose any constituents that can produce the requested iteration type.
            var yieldIteratorResult = filterType(type, isYieldIteratorResult);
            var yieldType = yieldIteratorResult !== neverType ? getTypeOfPropertyOfType(yieldIteratorResult, "value") : undefined;
            var returnIteratorResult = filterType(type, isReturnIteratorResult);
            var returnType = returnIteratorResult !== neverType ? getTypeOfPropertyOfType(returnIteratorResult, "value") : undefined;
            if (!yieldType && !returnType) {
                return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", noIterationTypes);
            }
            // From https://tc39.github.io/ecma262/#sec-iteratorresult-interface
            // > ... If the iterator does not have a return value, `value` is `undefined`. In that case, the
            // > `value` property may be absent from the conforming object if it does not inherit an explicit
            // > `value` property.
            return setCachedIterationTypes(type, "iterationTypesOfIteratorResult", createIterationTypes(yieldType, returnType || voidType, /*nextType*/ undefined));
        }
        /**
         * Gets the *yield*, *return*, and *next* types of a the `next()`, `return()`, or
         * `throw()` method of an `Iterator`-like or `AsyncIterator`-like type.
         *
         * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
         * record is returned. Otherwise, we return `undefined`.
         */
        function getIterationTypesOfMethod(type, resolver, methodName, errorNode) {
            var method = getPropertyOfType(type, methodName);
            // Ignore 'return' or 'throw' if they are missing.
            if (!method && methodName !== "next") {
                return undefined;
            }
            var methodType = method && !(methodName === "next" && (method.flags & 16777216 /* Optional */))
                ? methodName === "next" ? getTypeOfSymbol(method) : getTypeWithFacts(getTypeOfSymbol(method), 2097152 /* NEUndefinedOrNull */)
                : undefined;
            if (isTypeAny(methodType)) {
                // `return()` and `throw()` don't provide a *next* type.
                return methodName === "next" ? anyIterationTypes : anyIterationTypesExceptNext;
            }
            // Both async and non-async iterators *must* have a `next` method.
            var methodSignatures = methodType ? getSignaturesOfType(methodType, 0 /* Call */) : ts.emptyArray;
            if (methodSignatures.length === 0) {
                if (errorNode) {
                    var diagnostic = methodName === "next"
                        ? resolver.mustHaveANextMethodDiagnostic
                        : resolver.mustBeAMethodDiagnostic;
                    error(errorNode, diagnostic, methodName);
                }
                return methodName === "next" ? anyIterationTypes : undefined;
            }
            // Extract the first parameter and return type of each signature.
            var methodParameterTypes;
            var methodReturnTypes;
            for (var _i = 0, methodSignatures_1 = methodSignatures; _i < methodSignatures_1.length; _i++) {
                var signature = methodSignatures_1[_i];
                if (methodName !== "throw" && ts.some(signature.parameters)) {
                    methodParameterTypes = ts.append(methodParameterTypes, getTypeAtPosition(signature, 0));
                }
                methodReturnTypes = ts.append(methodReturnTypes, getReturnTypeOfSignature(signature));
            }
            // Resolve the *next* or *return* type from the first parameter of a `next()` or
            // `return()` method, respectively.
            var returnTypes;
            var nextType;
            if (methodName !== "throw") {
                var methodParameterType = methodParameterTypes ? getUnionType(methodParameterTypes) : unknownType;
                if (methodName === "next") {
                    // The value of `next(value)` is *not* awaited by async generators
                    nextType = methodParameterType;
                }
                else if (methodName === "return") {
                    // The value of `return(value)` *is* awaited by async generators
                    var resolvedMethodParameterType = resolver.resolveIterationType(methodParameterType, errorNode) || anyType;
                    returnTypes = ts.append(returnTypes, resolvedMethodParameterType);
                }
            }
            // Resolve the *yield* and *return* types from the return type of the method (i.e. `IteratorResult`)
            var yieldType;
            var methodReturnType = methodReturnTypes ? getUnionType(methodReturnTypes, 2 /* Subtype */) : neverType;
            var resolvedMethodReturnType = resolver.resolveIterationType(methodReturnType, errorNode) || anyType;
            var iterationTypes = getIterationTypesOfIteratorResult(resolvedMethodReturnType);
            if (iterationTypes === noIterationTypes) {
                if (errorNode) {
                    error(errorNode, resolver.mustHaveAValueDiagnostic, methodName);
                }
                yieldType = anyType;
                returnTypes = ts.append(returnTypes, anyType);
            }
            else {
                yieldType = iterationTypes.yieldType;
                returnTypes = ts.append(returnTypes, iterationTypes.returnType);
            }
            return createIterationTypes(yieldType, getUnionType(returnTypes), nextType);
        }
        /**
         * Gets the *yield*, *return*, and *next* types of an `Iterator`-like or `AsyncIterator`-like
         * type from its members.
         *
         * If we successfully found the *yield*, *return*, and *next* types, an `IterationTypes`
         * record is returned. Otherwise, `noIterationTypes` is returned.
         *
         * NOTE: You probably don't want to call this directly and should be calling
         * `getIterationTypesOfIterator` instead.
         */
        function getIterationTypesOfIteratorSlow(type, resolver, errorNode) {
            var iterationTypes = combineIterationTypes([
                getIterationTypesOfMethod(type, resolver, "next", errorNode),
                getIterationTypesOfMethod(type, resolver, "return", errorNode),
                getIterationTypesOfMethod(type, resolver, "throw", errorNode),
            ]);
            return setCachedIterationTypes(type, resolver.iteratorCacheKey, iterationTypes);
        }
        /**
         * Gets the requested "iteration type" from a type that is either `Iterable`-like, `Iterator`-like,
         * `IterableIterator`-like, or `Generator`-like (for a non-async generator); or `AsyncIterable`-like,
         * `AsyncIterator`-like, `AsyncIterableIterator`-like, or `AsyncGenerator`-like (for an async generator).
         */
        function getIterationTypeOfGeneratorFunctionReturnType(kind, returnType, isAsyncGenerator) {
            if (isTypeAny(returnType)) {
                return undefined;
            }
            var iterationTypes = getIterationTypesOfGeneratorFunctionReturnType(returnType, isAsyncGenerator);
            return iterationTypes && iterationTypes[getIterationTypesKeyFromIterationTypeKind(kind)];
        }
        function getIterationTypesOfGeneratorFunctionReturnType(type, isAsyncGenerator) {
            if (isTypeAny(type)) {
                return anyIterationTypes;
            }
            var use = isAsyncGenerator ? 2 /* AsyncGeneratorReturnType */ : 1 /* GeneratorReturnType */;
            var resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
            return getIterationTypesOfIterable(type, use, /*errorNode*/ undefined) ||
                getIterationTypesOfIterator(type, resolver, /*errorNode*/ undefined);
        }
        function checkBreakOrContinueStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node))
                checkGrammarBreakOrContinueStatement(node);
            // TODO: Check that target label is valid
        }
        function unwrapReturnType(returnType, functionFlags) {
            var _a, _b;
            var isGenerator = !!(functionFlags & 1 /* Generator */);
            var isAsync = !!(functionFlags & 2 /* Async */);
            return isGenerator ? (_a = getIterationTypeOfGeneratorFunctionReturnType(1 /* Return */, returnType, isAsync)) !== null && _a !== void 0 ? _a : errorType :
                isAsync ? (_b = getAwaitedType(returnType)) !== null && _b !== void 0 ? _b : errorType :
                    returnType;
        }
        function isUnwrappedReturnTypeVoidOrAny(func, returnType) {
            var unwrappedReturnType = unwrapReturnType(returnType, ts.getFunctionFlags(func));
            return !!unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, 16384 /* Void */ | 3 /* AnyOrUnknown */);
        }
        function checkReturnStatement(node) {
            var _a;
            // Grammar checking
            if (checkGrammarStatementInAmbientContext(node)) {
                return;
            }
            var func = ts.getContainingFunction(node);
            if (!func) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.A_return_statement_can_only_be_used_within_a_function_body);
                return;
            }
            var signature = getSignatureFromDeclaration(func);
            var returnType = getReturnTypeOfSignature(signature);
            var functionFlags = ts.getFunctionFlags(func);
            if (strictNullChecks || node.expression || returnType.flags & 131072 /* Never */) {
                var exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType;
                if (func.kind === 164 /* SetAccessor */) {
                    if (node.expression) {
                        error(node, ts.Diagnostics.Setters_cannot_return_a_value);
                    }
                }
                else if (func.kind === 162 /* Constructor */) {
                    if (node.expression && !checkTypeAssignableToAndOptionallyElaborate(exprType, returnType, node, node.expression)) {
                        error(node, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class);
                    }
                }
                else if (getReturnTypeFromAnnotation(func)) {
                    var unwrappedReturnType = (_a = unwrapReturnType(returnType, functionFlags)) !== null && _a !== void 0 ? _a : returnType;
                    var unwrappedExprType = functionFlags & 2 /* Async */
                        ? checkAwaitedType(exprType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member)
                        : exprType;
                    if (unwrappedReturnType) {
                        // If the function has a return type, but promisedType is
                        // undefined, an error will be reported in checkAsyncFunctionReturnType
                        // so we don't need to report one here.
                        checkTypeAssignableToAndOptionallyElaborate(unwrappedExprType, unwrappedReturnType, node, node.expression);
                    }
                }
            }
            else if (func.kind !== 162 /* Constructor */ && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(func, returnType)) {
                // The function has a return type, but the return statement doesn't have an expression.
                error(node, ts.Diagnostics.Not_all_code_paths_return_a_value);
            }
        }
        function checkWithStatement(node) {
            // Grammar checking for withStatement
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.flags & 32768 /* AwaitContext */) {
                    grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_an_async_function_block);
                }
            }
            checkExpression(node.expression);
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var start = ts.getSpanOfTokenAtPosition(sourceFile, node.pos).start;
                var end = node.statement.pos;
                grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any);
            }
        }
        function checkSwitchStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            var firstDefaultClause;
            var hasDuplicateDefaultClause = false;
            var expressionType = checkExpression(node.expression);
            var expressionIsLiteral = isLiteralType(expressionType);
            ts.forEach(node.caseBlock.clauses, function (clause) {
                // Grammar check for duplicate default clauses, skip if we already report duplicate default clause
                if (clause.kind === 278 /* DefaultClause */ && !hasDuplicateDefaultClause) {
                    if (firstDefaultClause === undefined) {
                        firstDefaultClause = clause;
                    }
                    else {
                        grammarErrorOnNode(clause, ts.Diagnostics.A_default_clause_cannot_appear_more_than_once_in_a_switch_statement);
                        hasDuplicateDefaultClause = true;
                    }
                }
                if (produceDiagnostics && clause.kind === 277 /* CaseClause */) {
                    // TypeScript 1.0 spec (April 2014): 5.9
                    // In a 'switch' statement, each 'case' expression must be of a type that is comparable
                    // to or from the type of the 'switch' expression.
                    var caseType = checkExpression(clause.expression);
                    var caseIsLiteral = isLiteralType(caseType);
                    var comparedExpressionType = expressionType;
                    if (!caseIsLiteral || !expressionIsLiteral) {
                        caseType = caseIsLiteral ? getBaseTypeOfLiteralType(caseType) : caseType;
                        comparedExpressionType = getBaseTypeOfLiteralType(expressionType);
                    }
                    if (!isTypeEqualityComparableTo(comparedExpressionType, caseType)) {
                        // expressionType is not comparable to caseType, try the reversed check and report errors if it fails
                        checkTypeComparableTo(caseType, comparedExpressionType, clause.expression, /*headMessage*/ undefined);
                    }
                }
                ts.forEach(clause.statements, checkSourceElement);
                if (compilerOptions.noFallthroughCasesInSwitch && clause.fallthroughFlowNode && isReachableFlowNode(clause.fallthroughFlowNode)) {
                    error(clause, ts.Diagnostics.Fallthrough_case_in_switch);
                }
            });
            if (node.caseBlock.locals) {
                registerForUnusedIdentifiersCheck(node.caseBlock);
            }
        }
        function checkLabeledStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                ts.findAncestor(node.parent, function (current) {
                    if (ts.isFunctionLike(current)) {
                        return "quit";
                    }
                    if (current.kind === 238 /* LabeledStatement */ && current.label.escapedText === node.label.escapedText) {
                        grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, ts.getTextOfNode(node.label));
                        return true;
                    }
                    return false;
                });
            }
            // ensure that label is unique
            checkSourceElement(node.statement);
        }
        function checkThrowStatement(node) {
            // Grammar checking
            if (!checkGrammarStatementInAmbientContext(node)) {
                if (node.expression === undefined) {
                    grammarErrorAfterFirstToken(node, ts.Diagnostics.Line_break_not_permitted_here);
                }
            }
            if (node.expression) {
                checkExpression(node.expression);
            }
        }
        function checkTryStatement(node) {
            // Grammar checking
            checkGrammarStatementInAmbientContext(node);
            checkBlock(node.tryBlock);
            var catchClause = node.catchClause;
            if (catchClause) {
                // Grammar checking
                if (catchClause.variableDeclaration) {
                    if (catchClause.variableDeclaration.type) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.type, ts.Diagnostics.Catch_clause_variable_cannot_have_a_type_annotation);
                    }
                    else if (catchClause.variableDeclaration.initializer) {
                        grammarErrorOnFirstToken(catchClause.variableDeclaration.initializer, ts.Diagnostics.Catch_clause_variable_cannot_have_an_initializer);
                    }
                    else {
                        var blockLocals_1 = catchClause.block.locals;
                        if (blockLocals_1) {
                            ts.forEachKey(catchClause.locals, function (caughtName) {
                                var blockLocal = blockLocals_1.get(caughtName);
                                if (blockLocal && (blockLocal.flags & 2 /* BlockScopedVariable */) !== 0) {
                                    grammarErrorOnNode(blockLocal.valueDeclaration, ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName);
                                }
                            });
                        }
                    }
                }
                checkBlock(catchClause.block);
            }
            if (node.finallyBlock) {
                checkBlock(node.finallyBlock);
            }
        }
        function checkIndexConstraints(type) {
            var declaredNumberIndexer = getIndexDeclarationOfSymbol(type.symbol, 1 /* Number */);
            var declaredStringIndexer = getIndexDeclarationOfSymbol(type.symbol, 0 /* String */);
            var stringIndexType = getIndexTypeOfType(type, 0 /* String */);
            var numberIndexType = getIndexTypeOfType(type, 1 /* Number */);
            if (stringIndexType || numberIndexType) {
                ts.forEach(getPropertiesOfObjectType(type), function (prop) {
                    var propType = getTypeOfSymbol(prop);
                    checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
                    checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                });
                var classDeclaration = type.symbol.valueDeclaration;
                if (ts.getObjectFlags(type) & 1 /* Class */ && ts.isClassLike(classDeclaration)) {
                    for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) {
                        var member = _a[_i];
                        // Only process instance properties with computed names here.
                        // Static properties cannot be in conflict with indexers,
                        // and properties with literal names were already checked.
                        if (!ts.hasModifier(member, 32 /* Static */) && hasNonBindableDynamicName(member)) {
                            var symbol = getSymbolOfNode(member);
                            var propType = getTypeOfSymbol(symbol);
                            checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */);
                            checkIndexConstraintForProperty(symbol, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */);
                        }
                    }
                }
            }
            var errorNode;
            if (stringIndexType && numberIndexType) {
                errorNode = declaredNumberIndexer || declaredStringIndexer;
                // condition 'errorNode === undefined' may appear if types does not declare nor string neither number indexer
                if (!errorNode && (ts.getObjectFlags(type) & 2 /* Interface */)) {
                    var someBaseTypeHasBothIndexers = ts.forEach(getBaseTypes(type), function (base) { return getIndexTypeOfType(base, 0 /* String */) && getIndexTypeOfType(base, 1 /* Number */); });
                    errorNode = someBaseTypeHasBothIndexers ? undefined : type.symbol.declarations[0];
                }
            }
            if (errorNode && !isTypeAssignableTo(numberIndexType, stringIndexType)) { // TODO: GH#18217
                error(errorNode, ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, typeToString(numberIndexType), typeToString(stringIndexType));
            }
            function checkIndexConstraintForProperty(prop, propertyType, containingType, indexDeclaration, indexType, indexKind) {
                // ESSymbol properties apply to neither string nor numeric indexers.
                if (!indexType || ts.isKnownSymbol(prop)) {
                    return;
                }
                var propDeclaration = prop.valueDeclaration;
                var name = propDeclaration && ts.getNameOfDeclaration(propDeclaration);
                if (name && ts.isPrivateIdentifier(name)) {
                    return;
                }
                // index is numeric and property name is not valid numeric literal
                if (indexKind === 1 /* Number */ && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) {
                    return;
                }
                // perform property check if property or indexer is declared in 'type'
                // this allows us to rule out cases when both property and indexer are inherited from the base class
                var errorNode;
                if (propDeclaration && name &&
                    (propDeclaration.kind === 209 /* BinaryExpression */ ||
                        name.kind === 154 /* ComputedPropertyName */ ||
                        prop.parent === containingType.symbol)) {
                    errorNode = propDeclaration;
                }
                else if (indexDeclaration) {
                    errorNode = indexDeclaration;
                }
                else if (ts.getObjectFlags(containingType) & 2 /* Interface */) {
                    // for interfaces property and indexer might be inherited from different bases
                    // check if any base class already has both property and indexer.
                    // check should be performed only if 'type' is the first type that brings property\indexer together
                    var someBaseClassHasBothPropertyAndIndexer = ts.forEach(getBaseTypes(containingType), function (base) { return getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, indexKind); });
                    errorNode = someBaseClassHasBothPropertyAndIndexer ? undefined : containingType.symbol.declarations[0];
                }
                if (errorNode && !isTypeAssignableTo(propertyType, indexType)) {
                    var errorMessage = indexKind === 0 /* String */
                        ? ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2
                        : ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2;
                    error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType));
                }
            }
        }
        function checkTypeNameIsReserved(name, message) {
            // TS 1.0 spec (April 2014): 3.6.1
            // The predefined type keywords are reserved and cannot be used as names of user defined types.
            switch (name.escapedText) {
                case "any":
                case "unknown":
                case "number":
                case "bigint":
                case "boolean":
                case "string":
                case "symbol":
                case "void":
                case "object":
                    error(name, message, name.escapedText);
            }
        }
        /**
         * The name cannot be used as 'Object' of user defined types with special target.
         */
        function checkClassNameCollisionWithObject(name) {
            if (languageVersion === 1 /* ES5 */ && name.escapedText === "Object"
                && moduleKind < ts.ModuleKind.ES2015) {
                error(name, ts.Diagnostics.Class_name_cannot_be_Object_when_targeting_ES5_with_module_0, ts.ModuleKind[moduleKind]); // https://github.com/Microsoft/TypeScript/issues/17494
            }
        }
        /**
         * Check each type parameter and check that type parameters have no duplicate type parameter declarations
         */
        function checkTypeParameters(typeParameterDeclarations) {
            if (typeParameterDeclarations) {
                var seenDefault = false;
                for (var i = 0; i < typeParameterDeclarations.length; i++) {
                    var node = typeParameterDeclarations[i];
                    checkTypeParameter(node);
                    if (produceDiagnostics) {
                        if (node.default) {
                            seenDefault = true;
                            checkTypeParametersNotReferenced(node.default, typeParameterDeclarations, i);
                        }
                        else if (seenDefault) {
                            error(node, ts.Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters);
                        }
                        for (var j = 0; j < i; j++) {
                            if (typeParameterDeclarations[j].symbol === node.symbol) {
                                error(node.name, ts.Diagnostics.Duplicate_identifier_0, ts.declarationNameToString(node.name));
                            }
                        }
                    }
                }
            }
        }
        /** Check that type parameter defaults only reference previously declared type parameters */
        function checkTypeParametersNotReferenced(root, typeParameters, index) {
            visit(root);
            function visit(node) {
                if (node.kind === 169 /* TypeReference */) {
                    var type = getTypeFromTypeReference(node);
                    if (type.flags & 262144 /* TypeParameter */) {
                        for (var i = index; i < typeParameters.length; i++) {
                            if (type.symbol === getSymbolOfNode(typeParameters[i])) {
                                error(node, ts.Diagnostics.Type_parameter_defaults_can_only_reference_previously_declared_type_parameters);
                            }
                        }
                    }
                }
                ts.forEachChild(node, visit);
            }
        }
        /** Check that type parameter lists are identical across multiple declarations */
        function checkTypeParameterListsIdentical(symbol) {
            if (symbol.declarations.length === 1) {
                return;
            }
            var links = getSymbolLinks(symbol);
            if (!links.typeParametersChecked) {
                links.typeParametersChecked = true;
                var declarations = getClassOrInterfaceDeclarationsOfSymbol(symbol);
                if (declarations.length <= 1) {
                    return;
                }
                var type = getDeclaredTypeOfSymbol(symbol);
                if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) {
                    // Report an error on every conflicting declaration.
                    var name = symbolToString(symbol);
                    for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) {
                        var declaration = declarations_6[_i];
                        error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name);
                    }
                }
            }
        }
        function areTypeParametersIdentical(declarations, targetParameters) {
            var maxTypeArgumentCount = ts.length(targetParameters);
            var minTypeArgumentCount = getMinTypeArgumentCount(targetParameters);
            for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) {
                var declaration = declarations_7[_i];
                // If this declaration has too few or too many type parameters, we report an error
                var sourceParameters = ts.getEffectiveTypeParameterDeclarations(declaration);
                var numTypeParameters = sourceParameters.length;
                if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) {
                    return false;
                }
                for (var i = 0; i < numTypeParameters; i++) {
                    var source = sourceParameters[i];
                    var target = targetParameters[i];
                    // If the type parameter node does not have the same as the resolved type
                    // parameter at this position, we report an error.
                    if (source.name.escapedText !== target.symbol.escapedName) {
                        return false;
                    }
                    // If the type parameter node does not have an identical constraint as the resolved
                    // type parameter at this position, we report an error.
                    var constraint = ts.getEffectiveConstraintOfTypeParameter(source);
                    var sourceConstraint = constraint && getTypeFromTypeNode(constraint);
                    var targetConstraint = getConstraintOfTypeParameter(target);
                    // relax check if later interface augmentation has no constraint, it's more broad and is OK to merge with
                    // a more constrained interface (this could be generalized to a full hierarchy check, but that's maybe overkill)
                    if (sourceConstraint && targetConstraint && !isTypeIdenticalTo(sourceConstraint, targetConstraint)) {
                        return false;
                    }
                    // If the type parameter node has a default and it is not identical to the default
                    // for the type parameter at this position, we report an error.
                    var sourceDefault = source.default && getTypeFromTypeNode(source.default);
                    var targetDefault = getDefaultFromTypeParameter(target);
                    if (sourceDefault && targetDefault && !isTypeIdenticalTo(sourceDefault, targetDefault)) {
                        return false;
                    }
                }
            }
            return true;
        }
        function checkClassExpression(node) {
            checkClassLikeDeclaration(node);
            checkNodeDeferred(node);
            return getTypeOfSymbol(getSymbolOfNode(node));
        }
        function checkClassExpressionDeferred(node) {
            ts.forEach(node.members, checkSourceElement);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkClassDeclaration(node) {
            if (!node.name && !ts.hasModifier(node, 512 /* Default */)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
            }
            checkClassLikeDeclaration(node);
            ts.forEach(node.members, checkSourceElement);
            registerForUnusedIdentifiersCheck(node);
        }
        function checkClassLikeDeclaration(node) {
            checkGrammarClassLikeDeclaration(node);
            checkDecorators(node);
            if (node.name) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Class_name_cannot_be_0);
                checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                if (!(node.flags & 8388608 /* Ambient */)) {
                    checkClassNameCollisionWithObject(node.name);
                }
            }
            checkTypeParameters(ts.getEffectiveTypeParameterDeclarations(node));
            checkExportsOnMergedDeclarations(node);
            var symbol = getSymbolOfNode(node);
            var type = getDeclaredTypeOfSymbol(symbol);
            var typeWithThis = getTypeWithThisArgument(type);
            var staticType = getTypeOfSymbol(symbol);
            checkTypeParameterListsIdentical(symbol);
            checkClassForDuplicateDeclarations(node);
            // Only check for reserved static identifiers on non-ambient context.
            if (!(node.flags & 8388608 /* Ambient */)) {
                checkClassForStaticPropertyNameConflicts(node);
            }
            var baseTypeNode = ts.getEffectiveBaseTypeNode(node);
            if (baseTypeNode) {
                ts.forEach(baseTypeNode.typeArguments, checkSourceElement);
                if (languageVersion < 2 /* ES2015 */) {
                    checkExternalEmitHelpers(baseTypeNode.parent, 1 /* Extends */);
                }
                // check both @extends and extends if both are specified.
                var extendsNode = ts.getClassExtendsHeritageElement(node);
                if (extendsNode && extendsNode !== baseTypeNode) {
                    checkExpression(extendsNode.expression);
                }
                var baseTypes = getBaseTypes(type);
                if (baseTypes.length && produceDiagnostics) {
                    var baseType_1 = baseTypes[0];
                    var baseConstructorType = getBaseConstructorTypeOfClass(type);
                    var staticBaseType = getApparentType(baseConstructorType);
                    checkBaseTypeAccessibility(staticBaseType, baseTypeNode);
                    checkSourceElement(baseTypeNode.expression);
                    if (ts.some(baseTypeNode.typeArguments)) {
                        ts.forEach(baseTypeNode.typeArguments, checkSourceElement);
                        for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); _i < _a.length; _i++) {
                            var constructor = _a[_i];
                            if (!checkTypeArgumentConstraints(baseTypeNode, constructor.typeParameters)) {
                                break;
                            }
                        }
                    }
                    var baseWithThis = getTypeWithThisArgument(baseType_1, type.thisType);
                    if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) {
                        issueMemberSpecificError(node, typeWithThis, baseWithThis, ts.Diagnostics.Class_0_incorrectly_extends_base_class_1);
                    }
                    else {
                        // Report static side error only when instance type is assignable
                        checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, ts.Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
                    }
                    if (baseConstructorType.flags & 8650752 /* TypeVariable */ && !isMixinConstructorType(staticType)) {
                        error(node.name || node, ts.Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any);
                    }
                    if (!(staticBaseType.symbol && staticBaseType.symbol.flags & 32 /* Class */) && !(baseConstructorType.flags & 8650752 /* TypeVariable */)) {
                        // When the static base type is a "class-like" constructor function (but not actually a class), we verify
                        // that all instantiated base constructor signatures return the same type.
                        var constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode);
                        if (ts.forEach(constructors, function (sig) { return !isJSConstructor(sig.declaration) && !isTypeIdenticalTo(getReturnTypeOfSignature(sig), baseType_1); })) {
                            error(baseTypeNode.expression, ts.Diagnostics.Base_constructors_must_all_have_the_same_return_type);
                        }
                    }
                    checkKindsOfPropertyMemberOverrides(type, baseType_1);
                }
            }
            var implementedTypeNodes = ts.getEffectiveImplementsTypeNodes(node);
            if (implementedTypeNodes) {
                for (var _b = 0, implementedTypeNodes_1 = implementedTypeNodes; _b < implementedTypeNodes_1.length; _b++) {
                    var typeRefNode = implementedTypeNodes_1[_b];
                    if (!ts.isEntityNameExpression(typeRefNode.expression)) {
                        error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments);
                    }
                    checkTypeReferenceNode(typeRefNode);
                    if (produceDiagnostics) {
                        var t = getReducedType(getTypeFromTypeNode(typeRefNode));
                        if (t !== errorType) {
                            if (isValidBaseType(t)) {
                                var genericDiag = t.symbol && t.symbol.flags & 32 /* Class */ ?
                                    ts.Diagnostics.Class_0_incorrectly_implements_class_1_Did_you_mean_to_extend_1_and_inherit_its_members_as_a_subclass :
                                    ts.Diagnostics.Class_0_incorrectly_implements_interface_1;
                                var baseWithThis = getTypeWithThisArgument(t, type.thisType);
                                if (!checkTypeAssignableTo(typeWithThis, baseWithThis, /*errorNode*/ undefined)) {
                                    issueMemberSpecificError(node, typeWithThis, baseWithThis, genericDiag);
                                }
                            }
                            else {
                                error(typeRefNode, ts.Diagnostics.A_class_can_only_implement_an_object_type_or_intersection_of_object_types_with_statically_known_members);
                            }
                        }
                    }
                }
            }
            if (produceDiagnostics) {
                checkIndexConstraints(type);
                checkTypeForDuplicateIndexSignatures(node);
                checkPropertyInitialization(node);
            }
        }
        function issueMemberSpecificError(node, typeWithThis, baseWithThis, broadDiag) {
            // iterate over all implemented properties and issue errors on each one which isn't compatible, rather than the class as a whole, if possible
            var issuedMemberError = false;
            var _loop_19 = function (member) {
                if (ts.hasStaticModifier(member)) {
                    return "continue";
                }
                var declaredProp = member.name && getSymbolAtLocation(member.name) || getSymbolAtLocation(member);
                if (declaredProp) {
                    var prop = getPropertyOfType(typeWithThis, declaredProp.escapedName);
                    var baseProp = getPropertyOfType(baseWithThis, declaredProp.escapedName);
                    if (prop && baseProp) {
                        var rootChain = function () { return ts.chainDiagnosticMessages(
                        /*details*/ undefined, ts.Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2, symbolToString(declaredProp), typeToString(typeWithThis), typeToString(baseWithThis)); };
                        if (!checkTypeAssignableTo(getTypeOfSymbol(prop), getTypeOfSymbol(baseProp), member.name || member, /*message*/ undefined, rootChain)) {
                            issuedMemberError = true;
                        }
                    }
                }
            };
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                _loop_19(member);
            }
            if (!issuedMemberError) {
                // check again with diagnostics to generate a less-specific error
                checkTypeAssignableTo(typeWithThis, baseWithThis, node.name || node, broadDiag);
            }
        }
        function checkBaseTypeAccessibility(type, node) {
            var signatures = getSignaturesOfType(type, 1 /* Construct */);
            if (signatures.length) {
                var declaration = signatures[0].declaration;
                if (declaration && ts.hasModifier(declaration, 8 /* Private */)) {
                    var typeClassDeclaration = ts.getClassLikeDeclarationOfSymbol(type.symbol);
                    if (!isNodeWithinClass(node, typeClassDeclaration)) {
                        error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol));
                    }
                }
            }
        }
        function getTargetSymbol(s) {
            // if symbol is instantiated its flags are not copied from the 'target'
            // so we'll need to get back original 'target' symbol to work with correct set of flags
            return ts.getCheckFlags(s) & 1 /* Instantiated */ ? s.target : s;
        }
        function getClassOrInterfaceDeclarationsOfSymbol(symbol) {
            return ts.filter(symbol.declarations, function (d) {
                return d.kind === 245 /* ClassDeclaration */ || d.kind === 246 /* InterfaceDeclaration */;
            });
        }
        function checkKindsOfPropertyMemberOverrides(type, baseType) {
            // TypeScript 1.0 spec (April 2014): 8.2.3
            // A derived class inherits all members from its base class it doesn't override.
            // Inheritance means that a derived class implicitly contains all non - overridden members of the base class.
            // Both public and private property members are inherited, but only public property members can be overridden.
            // A property member in a derived class is said to override a property member in a base class
            // when the derived class property member has the same name and kind(instance or static)
            // as the base class property member.
            // The type of an overriding property member must be assignable(section 3.8.4)
            // to the type of the overridden property member, or otherwise a compile - time error occurs.
            // Base class instance member functions can be overridden by derived class instance member functions,
            // but not by other kinds of members.
            // Base class instance member variables and accessors can be overridden by
            // derived class instance member variables and accessors, but not by other kinds of members.
            // NOTE: assignability is checked in checkClassDeclaration
            var baseProperties = getPropertiesOfType(baseType);
            basePropertyCheck: for (var _i = 0, baseProperties_1 = baseProperties; _i < baseProperties_1.length; _i++) {
                var baseProperty = baseProperties_1[_i];
                var base = getTargetSymbol(baseProperty);
                if (base.flags & 4194304 /* Prototype */) {
                    continue;
                }
                var baseSymbol = getPropertyOfObjectType(type, base.escapedName);
                if (!baseSymbol) {
                    continue;
                }
                var derived = getTargetSymbol(baseSymbol);
                var baseDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(base);
                ts.Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration.");
                // In order to resolve whether the inherited method was overridden in the base class or not,
                // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated*
                // type declaration, derived and base resolve to the same symbol even in the case of generic classes.
                if (derived === base) {
                    // derived class inherits base without override/redeclaration
                    var derivedClassDecl = ts.getClassLikeDeclarationOfSymbol(type.symbol);
                    // It is an error to inherit an abstract member without implementing it or being declared abstract.
                    // If there is no declaration for the derived class (as in the case of class expressions),
                    // then the class cannot be declared abstract.
                    if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128 /* Abstract */))) {
                        // Searches other base types for a declaration that would satisfy the inherited abstract member.
                        // (The class may have more than one base type via declaration merging with an interface with the
                        // same name.)
                        for (var _a = 0, _b = getBaseTypes(type); _a < _b.length; _a++) {
                            var otherBaseType = _b[_a];
                            if (otherBaseType === baseType)
                                continue;
                            var baseSymbol_1 = getPropertyOfObjectType(otherBaseType, base.escapedName);
                            var derivedElsewhere = baseSymbol_1 && getTargetSymbol(baseSymbol_1);
                            if (derivedElsewhere && derivedElsewhere !== base) {
                                continue basePropertyCheck;
                            }
                        }
                        if (derivedClassDecl.kind === 214 /* ClassExpression */) {
                            error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType));
                        }
                        else {
                            error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, typeToString(type), symbolToString(baseProperty), typeToString(baseType));
                        }
                    }
                }
                else {
                    // derived overrides base.
                    var derivedDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(derived);
                    if (baseDeclarationFlags & 8 /* Private */ || derivedDeclarationFlags & 8 /* Private */) {
                        // either base or derived property is private - not override, skip it
                        continue;
                    }
                    var errorMessage = void 0;
                    var basePropertyFlags = base.flags & 98308 /* PropertyOrAccessor */;
                    var derivedPropertyFlags = derived.flags & 98308 /* PropertyOrAccessor */;
                    if (basePropertyFlags && derivedPropertyFlags) {
                        // property/accessor is overridden with property/accessor
                        if (!compilerOptions.useDefineForClassFields
                            || baseDeclarationFlags & 128 /* Abstract */ && !(base.valueDeclaration && ts.isPropertyDeclaration(base.valueDeclaration) && base.valueDeclaration.initializer)
                            || base.valueDeclaration && base.valueDeclaration.parent.kind === 246 /* InterfaceDeclaration */
                            || derived.valueDeclaration && ts.isBinaryExpression(derived.valueDeclaration)) {
                            // when the base property is abstract or from an interface, base/derived flags don't need to match
                            // same when the derived property is from an assignment
                            continue;
                        }
                        var overriddenInstanceProperty = basePropertyFlags !== 4 /* Property */ && derivedPropertyFlags === 4 /* Property */;
                        var overriddenInstanceAccessor = basePropertyFlags === 4 /* Property */ && derivedPropertyFlags !== 4 /* Property */;
                        if (overriddenInstanceProperty || overriddenInstanceAccessor) {
                            var errorMessage_1 = overriddenInstanceProperty ?
                                ts.Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property :
                                ts.Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor;
                            error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage_1, symbolToString(base), typeToString(baseType), typeToString(type));
                        }
                        else {
                            var uninitialized = ts.find(derived.declarations, function (d) { return d.kind === 159 /* PropertyDeclaration */ && !d.initializer; });
                            if (uninitialized
                                && !(derived.flags & 33554432 /* Transient */)
                                && !(baseDeclarationFlags & 128 /* Abstract */)
                                && !(derivedDeclarationFlags & 128 /* Abstract */)
                                && !derived.declarations.some(function (d) { return !!(d.flags & 8388608 /* Ambient */); })) {
                                var constructor = findConstructorDeclaration(ts.getClassLikeDeclarationOfSymbol(type.symbol));
                                var propName = uninitialized.name;
                                if (uninitialized.exclamationToken
                                    || !constructor
                                    || !ts.isIdentifier(propName)
                                    || !strictNullChecks
                                    || !isPropertyInitializedInConstructor(propName, type, constructor)) {
                                    var errorMessage_2 = ts.Diagnostics.Property_0_will_overwrite_the_base_property_in_1_If_this_is_intentional_add_an_initializer_Otherwise_add_a_declare_modifier_or_remove_the_redundant_declaration;
                                    error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage_2, symbolToString(base), typeToString(baseType));
                                }
                            }
                        }
                        // correct case
                        continue;
                    }
                    else if (isPrototypeProperty(base)) {
                        if (isPrototypeProperty(derived) || derived.flags & 4 /* Property */) {
                            // method is overridden with method or property -- correct case
                            continue;
                        }
                        else {
                            ts.Debug.assert(!!(derived.flags & 98304 /* Accessor */));
                            errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor;
                        }
                    }
                    else if (base.flags & 98304 /* Accessor */) {
                        errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function;
                    }
                    else {
                        errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function;
                    }
                    error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type));
                }
            }
        }
        function getNonInterhitedProperties(type, baseTypes, properties) {
            if (!ts.length(baseTypes)) {
                return properties;
            }
            var seen = ts.createUnderscoreEscapedMap();
            ts.forEach(properties, function (p) { seen.set(p.escapedName, p); });
            for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) {
                var base = baseTypes_2[_i];
                var properties_5 = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType));
                for (var _a = 0, properties_4 = properties_5; _a < properties_4.length; _a++) {
                    var prop = properties_4[_a];
                    var existing = seen.get(prop.escapedName);
                    if (existing && !isPropertyIdenticalTo(existing, prop)) {
                        seen.delete(prop.escapedName);
                    }
                }
            }
            return ts.arrayFrom(seen.values());
        }
        function checkInheritedPropertiesAreIdentical(type, typeNode) {
            var baseTypes = getBaseTypes(type);
            if (baseTypes.length < 2) {
                return true;
            }
            var seen = ts.createUnderscoreEscapedMap();
            ts.forEach(resolveDeclaredMembers(type).declaredProperties, function (p) { seen.set(p.escapedName, { prop: p, containingType: type }); });
            var ok = true;
            for (var _i = 0, baseTypes_3 = baseTypes; _i < baseTypes_3.length; _i++) {
                var base = baseTypes_3[_i];
                var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType));
                for (var _a = 0, properties_6 = properties; _a < properties_6.length; _a++) {
                    var prop = properties_6[_a];
                    var existing = seen.get(prop.escapedName);
                    if (!existing) {
                        seen.set(prop.escapedName, { prop: prop, containingType: base });
                    }
                    else {
                        var isInheritedProperty = existing.containingType !== type;
                        if (isInheritedProperty && !isPropertyIdenticalTo(existing.prop, prop)) {
                            ok = false;
                            var typeName1 = typeToString(existing.containingType);
                            var typeName2 = typeToString(base);
                            var errorInfo = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2);
                            errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2);
                            diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(typeNode, errorInfo));
                        }
                    }
                }
            }
            return ok;
        }
        function checkPropertyInitialization(node) {
            if (!strictNullChecks || !strictPropertyInitialization || node.flags & 8388608 /* Ambient */) {
                return;
            }
            var constructor = findConstructorDeclaration(node);
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                if (ts.getModifierFlags(member) & 2 /* Ambient */) {
                    continue;
                }
                if (isInstancePropertyWithoutInitializer(member)) {
                    var propName = member.name;
                    if (ts.isIdentifier(propName) || ts.isPrivateIdentifier(propName)) {
                        var type = getTypeOfSymbol(getSymbolOfNode(member));
                        if (!(type.flags & 3 /* AnyOrUnknown */ || getFalsyFlags(type) & 32768 /* Undefined */)) {
                            if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) {
                                error(member.name, ts.Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, ts.declarationNameToString(propName));
                            }
                        }
                    }
                }
            }
        }
        function isInstancePropertyWithoutInitializer(node) {
            return node.kind === 159 /* PropertyDeclaration */ &&
                !ts.hasModifier(node, 32 /* Static */ | 128 /* Abstract */) &&
                !node.exclamationToken &&
                !node.initializer;
        }
        function isPropertyInitializedInConstructor(propName, propType, constructor) {
            var reference = ts.createPropertyAccess(ts.createThis(), propName);
            reference.expression.parent = reference;
            reference.parent = constructor;
            reference.flowNode = constructor.returnFlowNode;
            var flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType));
            return !(getFalsyFlags(flowType) & 32768 /* Undefined */);
        }
        function checkInterfaceDeclaration(node) {
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node))
                checkGrammarInterfaceDeclaration(node);
            checkTypeParameters(node.typeParameters);
            if (produceDiagnostics) {
                checkTypeNameIsReserved(node.name, ts.Diagnostics.Interface_name_cannot_be_0);
                checkExportsOnMergedDeclarations(node);
                var symbol = getSymbolOfNode(node);
                checkTypeParameterListsIdentical(symbol);
                // Only check this symbol once
                var firstInterfaceDecl = ts.getDeclarationOfKind(symbol, 246 /* InterfaceDeclaration */);
                if (node === firstInterfaceDecl) {
                    var type = getDeclaredTypeOfSymbol(symbol);
                    var typeWithThis = getTypeWithThisArgument(type);
                    // run subsequent checks only if first set succeeded
                    if (checkInheritedPropertiesAreIdentical(type, node.name)) {
                        for (var _i = 0, _a = getBaseTypes(type); _i < _a.length; _i++) {
                            var baseType = _a[_i];
                            checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, ts.Diagnostics.Interface_0_incorrectly_extends_interface_1);
                        }
                        checkIndexConstraints(type);
                    }
                }
                checkObjectTypeForDuplicateDeclarations(node);
            }
            ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) {
                if (!ts.isEntityNameExpression(heritageElement.expression)) {
                    error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments);
                }
                checkTypeReferenceNode(heritageElement);
            });
            ts.forEach(node.members, checkSourceElement);
            if (produceDiagnostics) {
                checkTypeForDuplicateIndexSignatures(node);
                registerForUnusedIdentifiersCheck(node);
            }
        }
        function checkTypeAliasDeclaration(node) {
            // Grammar checking
            checkGrammarDecoratorsAndModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0);
            checkExportsOnMergedDeclarations(node);
            checkTypeParameters(node.typeParameters);
            checkSourceElement(node.type);
            registerForUnusedIdentifiersCheck(node);
        }
        function computeEnumMemberValues(node) {
            var nodeLinks = getNodeLinks(node);
            if (!(nodeLinks.flags & 16384 /* EnumValuesComputed */)) {
                nodeLinks.flags |= 16384 /* EnumValuesComputed */;
                var autoValue = 0;
                for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    var value = computeMemberValue(member, autoValue);
                    getNodeLinks(member).enumMemberValue = value;
                    autoValue = typeof value === "number" ? value + 1 : undefined;
                }
            }
        }
        function computeMemberValue(member, autoValue) {
            if (ts.isComputedNonLiteralName(member.name)) {
                error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums);
            }
            else {
                var text = ts.getTextOfPropertyName(member.name);
                if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) {
                    error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name);
                }
            }
            if (member.initializer) {
                return computeConstantValue(member);
            }
            // In ambient non-const numeric enum declarations, enum members without initializers are
            // considered computed members (as opposed to having auto-incremented values).
            if (member.parent.flags & 8388608 /* Ambient */ && !ts.isEnumConst(member.parent) && getEnumKind(getSymbolOfNode(member.parent)) === 0 /* Numeric */) {
                return undefined;
            }
            // If the member declaration specifies no value, the member is considered a constant enum member.
            // If the member is the first member in the enum declaration, it is assigned the value zero.
            // Otherwise, it is assigned the value of the immediately preceding member plus one, and an error
            // occurs if the immediately preceding member is not a constant enum member.
            if (autoValue !== undefined) {
                return autoValue;
            }
            error(member.name, ts.Diagnostics.Enum_member_must_have_initializer);
            return undefined;
        }
        function computeConstantValue(member) {
            var enumKind = getEnumKind(getSymbolOfNode(member.parent));
            var isConstEnum = ts.isEnumConst(member.parent);
            var initializer = member.initializer;
            var value = enumKind === 1 /* Literal */ && !isLiteralEnumMember(member) ? undefined : evaluate(initializer);
            if (value !== undefined) {
                if (isConstEnum && typeof value === "number" && !isFinite(value)) {
                    error(initializer, isNaN(value) ?
                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN :
                        ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value);
                }
            }
            else if (enumKind === 1 /* Literal */) {
                error(initializer, ts.Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members);
                return 0;
            }
            else if (isConstEnum) {
                error(initializer, ts.Diagnostics.const_enum_member_initializers_can_only_contain_literal_values_and_other_computed_enum_values);
            }
            else if (member.parent.flags & 8388608 /* Ambient */) {
                error(initializer, ts.Diagnostics.In_ambient_enum_declarations_member_initializer_must_be_constant_expression);
            }
            else {
                // Only here do we need to check that the initializer is assignable to the enum type.
                var source = checkExpression(initializer);
                if (!isTypeAssignableToKind(source, 296 /* NumberLike */)) {
                    error(initializer, ts.Diagnostics.Only_numeric_enums_can_have_computed_members_but_this_expression_has_type_0_If_you_do_not_need_exhaustiveness_checks_consider_using_an_object_literal_instead, typeToString(source));
                }
                else {
                    checkTypeAssignableTo(source, getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined);
                }
            }
            return value;
            function evaluate(expr) {
                switch (expr.kind) {
                    case 207 /* PrefixUnaryExpression */:
                        var value_2 = evaluate(expr.operand);
                        if (typeof value_2 === "number") {
                            switch (expr.operator) {
                                case 39 /* PlusToken */: return value_2;
                                case 40 /* MinusToken */: return -value_2;
                                case 54 /* TildeToken */: return ~value_2;
                            }
                        }
                        break;
                    case 209 /* BinaryExpression */:
                        var left = evaluate(expr.left);
                        var right = evaluate(expr.right);
                        if (typeof left === "number" && typeof right === "number") {
                            switch (expr.operatorToken.kind) {
                                case 51 /* BarToken */: return left | right;
                                case 50 /* AmpersandToken */: return left & right;
                                case 48 /* GreaterThanGreaterThanToken */: return left >> right;
                                case 49 /* GreaterThanGreaterThanGreaterThanToken */: return left >>> right;
                                case 47 /* LessThanLessThanToken */: return left << right;
                                case 52 /* CaretToken */: return left ^ right;
                                case 41 /* AsteriskToken */: return left * right;
                                case 43 /* SlashToken */: return left / right;
                                case 39 /* PlusToken */: return left + right;
                                case 40 /* MinusToken */: return left - right;
                                case 44 /* PercentToken */: return left % right;
                                case 42 /* AsteriskAsteriskToken */: return Math.pow(left, right);
                            }
                        }
                        else if (typeof left === "string" && typeof right === "string" && expr.operatorToken.kind === 39 /* PlusToken */) {
                            return left + right;
                        }
                        break;
                    case 10 /* StringLiteral */:
                    case 14 /* NoSubstitutionTemplateLiteral */:
                        return expr.text;
                    case 8 /* NumericLiteral */:
                        checkGrammarNumericLiteral(expr);
                        return +expr.text;
                    case 200 /* ParenthesizedExpression */:
                        return evaluate(expr.expression);
                    case 75 /* Identifier */:
                        var identifier = expr;
                        if (isInfinityOrNaNString(identifier.escapedText)) {
                            return +(identifier.escapedText);
                        }
                        return ts.nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), identifier.escapedText);
                    case 195 /* ElementAccessExpression */:
                    case 194 /* PropertyAccessExpression */:
                        var ex = expr;
                        if (isConstantMemberAccess(ex)) {
                            var type = getTypeOfExpression(ex.expression);
                            if (type.symbol && type.symbol.flags & 384 /* Enum */) {
                                var name = void 0;
                                if (ex.kind === 194 /* PropertyAccessExpression */) {
                                    name = ex.name.escapedText;
                                }
                                else {
                                    name = ts.escapeLeadingUnderscores(ts.cast(ex.argumentExpression, ts.isLiteralExpression).text);
                                }
                                return evaluateEnumMember(expr, type.symbol, name);
                            }
                        }
                        break;
                }
                return undefined;
            }
            function evaluateEnumMember(expr, enumSymbol, name) {
                var memberSymbol = enumSymbol.exports.get(name);
                if (memberSymbol) {
                    var declaration = memberSymbol.valueDeclaration;
                    if (declaration !== member) {
                        if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) {
                            return getEnumMemberValue(declaration);
                        }
                        error(expr, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums);
                        return 0;
                    }
                    else {
                        error(expr, ts.Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(memberSymbol));
                    }
                }
                return undefined;
            }
        }
        function isConstantMemberAccess(node) {
            return node.kind === 75 /* Identifier */ ||
                node.kind === 194 /* PropertyAccessExpression */ && isConstantMemberAccess(node.expression) ||
                node.kind === 195 /* ElementAccessExpression */ && isConstantMemberAccess(node.expression) &&
                    ts.isStringLiteralLike(node.argumentExpression);
        }
        function checkEnumDeclaration(node) {
            if (!produceDiagnostics) {
                return;
            }
            // Grammar checking
            checkGrammarDecoratorsAndModifiers(node);
            checkTypeNameIsReserved(node.name, ts.Diagnostics.Enum_name_cannot_be_0);
            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            checkExportsOnMergedDeclarations(node);
            node.members.forEach(checkEnumMember);
            computeEnumMemberValues(node);
            // Spec 2014 - Section 9.3:
            // It isn't possible for one enum declaration to continue the automatic numbering sequence of another,
            // and when an enum type has multiple declarations, only one declaration is permitted to omit a value
            // for the first member.
            //
            // Only perform this check once per symbol
            var enumSymbol = getSymbolOfNode(node);
            var firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind);
            if (node === firstDeclaration) {
                if (enumSymbol.declarations.length > 1) {
                    var enumIsConst_1 = ts.isEnumConst(node);
                    // check that const is placed\omitted on all enum declarations
                    ts.forEach(enumSymbol.declarations, function (decl) {
                        if (ts.isEnumDeclaration(decl) && ts.isEnumConst(decl) !== enumIsConst_1) {
                            error(ts.getNameOfDeclaration(decl), ts.Diagnostics.Enum_declarations_must_all_be_const_or_non_const);
                        }
                    });
                }
                var seenEnumMissingInitialInitializer_1 = false;
                ts.forEach(enumSymbol.declarations, function (declaration) {
                    // return true if we hit a violation of the rule, false otherwise
                    if (declaration.kind !== 248 /* EnumDeclaration */) {
                        return false;
                    }
                    var enumDeclaration = declaration;
                    if (!enumDeclaration.members.length) {
                        return false;
                    }
                    var firstEnumMember = enumDeclaration.members[0];
                    if (!firstEnumMember.initializer) {
                        if (seenEnumMissingInitialInitializer_1) {
                            error(firstEnumMember.name, ts.Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element);
                        }
                        else {
                            seenEnumMissingInitialInitializer_1 = true;
                        }
                    }
                });
            }
        }
        function checkEnumMember(node) {
            if (ts.isPrivateIdentifier(node.name)) {
                error(node, ts.Diagnostics.An_enum_member_cannot_be_named_with_a_private_identifier);
            }
        }
        function getFirstNonAmbientClassOrFunctionDeclaration(symbol) {
            var declarations = symbol.declarations;
            for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) {
                var declaration = declarations_8[_i];
                if ((declaration.kind === 245 /* ClassDeclaration */ ||
                    (declaration.kind === 244 /* FunctionDeclaration */ && ts.nodeIsPresent(declaration.body))) &&
                    !(declaration.flags & 8388608 /* Ambient */)) {
                    return declaration;
                }
            }
            return undefined;
        }
        function inSameLexicalScope(node1, node2) {
            var container1 = ts.getEnclosingBlockScopeContainer(node1);
            var container2 = ts.getEnclosingBlockScopeContainer(node2);
            if (isGlobalSourceFile(container1)) {
                return isGlobalSourceFile(container2);
            }
            else if (isGlobalSourceFile(container2)) {
                return false;
            }
            else {
                return container1 === container2;
            }
        }
        function checkModuleDeclaration(node) {
            if (produceDiagnostics) {
                // Grammar checking
                var isGlobalAugmentation = ts.isGlobalScopeAugmentation(node);
                var inAmbientContext = node.flags & 8388608 /* Ambient */;
                if (isGlobalAugmentation && !inAmbientContext) {
                    error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context);
                }
                var isAmbientExternalModule = ts.isAmbientModule(node);
                var contextErrorMessage = isAmbientExternalModule
                    ? ts.Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file
                    : ts.Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module;
                if (checkGrammarModuleElementContext(node, contextErrorMessage)) {
                    // If we hit a module declaration in an illegal context, just bail out to avoid cascading errors.
                    return;
                }
                if (!checkGrammarDecoratorsAndModifiers(node)) {
                    if (!inAmbientContext && node.name.kind === 10 /* StringLiteral */) {
                        grammarErrorOnNode(node.name, ts.Diagnostics.Only_ambient_modules_can_use_quoted_names);
                    }
                }
                if (ts.isIdentifier(node.name)) {
                    checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
                    checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
                }
                checkExportsOnMergedDeclarations(node);
                var symbol = getSymbolOfNode(node);
                // The following checks only apply on a non-ambient instantiated module declaration.
                if (symbol.flags & 512 /* ValueModule */
                    && !inAmbientContext
                    && symbol.declarations.length > 1
                    && isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules)) {
                    var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
                    if (firstNonAmbientClassOrFunc) {
                        if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) {
                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged);
                        }
                        else if (node.pos < firstNonAmbientClassOrFunc.pos) {
                            error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged);
                        }
                    }
                    // if the module merges with a class declaration in the same lexical scope,
                    // we need to track this to ensure the correct emit.
                    var mergedClass = ts.getDeclarationOfKind(symbol, 245 /* ClassDeclaration */);
                    if (mergedClass &&
                        inSameLexicalScope(node, mergedClass)) {
                        getNodeLinks(node).flags |= 32768 /* LexicalModuleMergesWithClass */;
                    }
                }
                if (isAmbientExternalModule) {
                    if (ts.isExternalModuleAugmentation(node)) {
                        // body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module)
                        // otherwise we'll be swamped in cascading errors.
                        // We can detect if augmentation was applied using following rules:
                        // - augmentation for a global scope is always applied
                        // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module).
                        var checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & 33554432 /* Transient */);
                        if (checkBody && node.body) {
                            for (var _i = 0, _a = node.body.statements; _i < _a.length; _i++) {
                                var statement = _a[_i];
                                checkModuleAugmentationElement(statement, isGlobalAugmentation);
                            }
                        }
                    }
                    else if (isGlobalSourceFile(node.parent)) {
                        if (isGlobalAugmentation) {
                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
                        }
                        else if (ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(node.name))) {
                            error(node.name, ts.Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name);
                        }
                    }
                    else {
                        if (isGlobalAugmentation) {
                            error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
                        }
                        else {
                            // Node is not an augmentation and is not located on the script level.
                            // This means that this is declaration of ambient module that is located in other module or namespace which is prohibited.
                            error(node.name, ts.Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces);
                        }
                    }
                }
            }
            if (node.body) {
                checkSourceElement(node.body);
                if (!ts.isGlobalScopeAugmentation(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
            }
        }
        function checkModuleAugmentationElement(node, isGlobalAugmentation) {
            switch (node.kind) {
                case 225 /* VariableStatement */:
                    // error each individual name in variable statement instead of marking the entire variable statement
                    for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                        var decl = _a[_i];
                        checkModuleAugmentationElement(decl, isGlobalAugmentation);
                    }
                    break;
                case 259 /* ExportAssignment */:
                case 260 /* ExportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations);
                    break;
                case 253 /* ImportEqualsDeclaration */:
                case 254 /* ImportDeclaration */:
                    grammarErrorOnFirstToken(node, ts.Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module);
                    break;
                case 191 /* BindingElement */:
                case 242 /* VariableDeclaration */:
                    var name = node.name;
                    if (ts.isBindingPattern(name)) {
                        for (var _b = 0, _c = name.elements; _b < _c.length; _b++) {
                            var el = _c[_b];
                            // mark individual names in binding pattern
                            checkModuleAugmentationElement(el, isGlobalAugmentation);
                        }
                        break;
                    }
                // falls through
                case 245 /* ClassDeclaration */:
                case 248 /* EnumDeclaration */:
                case 244 /* FunctionDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                    if (isGlobalAugmentation) {
                        return;
                    }
                    var symbol = getSymbolOfNode(node);
                    if (symbol) {
                        // module augmentations cannot introduce new names on the top level scope of the module
                        // this is done it two steps
                        // 1. quick check - if symbol for node is not merged - this is local symbol to this augmentation - report error
                        // 2. main check - report error if value declaration of the parent symbol is module augmentation)
                        var reportError = !(symbol.flags & 33554432 /* Transient */);
                        if (!reportError) {
                            // symbol should not originate in augmentation
                            reportError = !!symbol.parent && ts.isExternalModuleAugmentation(symbol.parent.declarations[0]);
                        }
                    }
                    break;
            }
        }
        function getFirstNonModuleExportsIdentifier(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return node;
                case 153 /* QualifiedName */:
                    do {
                        node = node.left;
                    } while (node.kind !== 75 /* Identifier */);
                    return node;
                case 194 /* PropertyAccessExpression */:
                    do {
                        if (ts.isModuleExportsAccessExpression(node.expression) && !ts.isPrivateIdentifier(node.name)) {
                            return node.name;
                        }
                        node = node.expression;
                    } while (node.kind !== 75 /* Identifier */);
                    return node;
            }
        }
        function checkExternalImportOrExportDeclaration(node) {
            var moduleName = ts.getExternalModuleName(node);
            if (!moduleName || ts.nodeIsMissing(moduleName)) {
                // Should be a parse error.
                return false;
            }
            if (!ts.isStringLiteral(moduleName)) {
                error(moduleName, ts.Diagnostics.String_literal_expected);
                return false;
            }
            var inAmbientExternalModule = node.parent.kind === 250 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
            if (node.parent.kind !== 290 /* SourceFile */ && !inAmbientExternalModule) {
                error(moduleName, node.kind === 260 /* ExportDeclaration */ ?
                    ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace :
                    ts.Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module);
                return false;
            }
            if (inAmbientExternalModule && ts.isExternalModuleNameRelative(moduleName.text)) {
                // we have already reported errors on top level imports/exports in external module augmentations in checkModuleDeclaration
                // no need to do this again.
                if (!isTopLevelInExternalModuleAugmentation(node)) {
                    // TypeScript 1.0 spec (April 2013): 12.1.6
                    // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference
                    // other external modules only through top - level external module names.
                    // Relative external module names are not permitted.
                    error(node, ts.Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name);
                    return false;
                }
            }
            return true;
        }
        function checkAliasSymbol(node) {
            var symbol = getSymbolOfNode(node);
            var target = resolveAlias(symbol);
            var shouldSkipWithJSExpandoTargets = symbol.flags & 67108864 /* Assignment */;
            if (!shouldSkipWithJSExpandoTargets && target !== unknownSymbol) {
                // For external modules symbol represents local symbol for an alias.
                // This local symbol will merge any other local declarations (excluding other aliases)
                // and symbol.flags will contains combined representation for all merged declaration.
                // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have,
                // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export*
                // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names).
                symbol = getMergedSymbol(symbol.exportSymbol || symbol);
                var excludedMeanings = (symbol.flags & (111551 /* Value */ | 1048576 /* ExportValue */) ? 111551 /* Value */ : 0) |
                    (symbol.flags & 788968 /* Type */ ? 788968 /* Type */ : 0) |
                    (symbol.flags & 1920 /* Namespace */ ? 1920 /* Namespace */ : 0);
                if (target.flags & excludedMeanings) {
                    var message = node.kind === 263 /* ExportSpecifier */ ?
                        ts.Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 :
                        ts.Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0;
                    error(node, message, symbolToString(symbol));
                }
                // Don't allow to re-export something with no value side when `--isolatedModules` is set.
                if (compilerOptions.isolatedModules
                    && node.kind === 263 /* ExportSpecifier */
                    && !node.parent.parent.isTypeOnly
                    && !(target.flags & 111551 /* Value */)
                    && !(node.flags & 8388608 /* Ambient */)) {
                    error(node, ts.Diagnostics.Re_exporting_a_type_when_the_isolatedModules_flag_is_provided_requires_using_export_type);
                }
            }
        }
        function checkImportBinding(node) {
            checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
            checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name);
            checkAliasSymbol(node);
        }
        function checkImportDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers);
            }
            if (checkExternalImportOrExportDeclaration(node)) {
                var importClause = node.importClause;
                if (importClause && !checkGrammarImportClause(importClause)) {
                    if (importClause.name) {
                        checkImportBinding(importClause);
                    }
                    if (importClause.namedBindings) {
                        if (importClause.namedBindings.kind === 256 /* NamespaceImport */) {
                            checkImportBinding(importClause.namedBindings);
                        }
                        else {
                            var moduleExisted = resolveExternalModuleName(node, node.moduleSpecifier);
                            if (moduleExisted) {
                                ts.forEach(importClause.namedBindings.elements, checkImportBinding);
                            }
                        }
                    }
                }
            }
        }
        function checkImportEqualsDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) {
                // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            checkGrammarDecoratorsAndModifiers(node);
            if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
                checkImportBinding(node);
                if (ts.hasModifier(node, 1 /* Export */)) {
                    markExportAsReferenced(node);
                }
                if (node.moduleReference.kind !== 265 /* ExternalModuleReference */) {
                    var target = resolveAlias(getSymbolOfNode(node));
                    if (target !== unknownSymbol) {
                        if (target.flags & 111551 /* Value */) {
                            // Target is a value symbol, check that it is not hidden by a local declaration with the same name
                            var moduleName = ts.getFirstIdentifier(node.moduleReference);
                            if (!(resolveEntityName(moduleName, 111551 /* Value */ | 1920 /* Namespace */).flags & 1920 /* Namespace */)) {
                                error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName));
                            }
                        }
                        if (target.flags & 788968 /* Type */) {
                            checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0);
                        }
                    }
                }
                else {
                    if (moduleKind >= ts.ModuleKind.ES2015 && !(node.flags & 8388608 /* Ambient */)) {
                        // Import equals declaration is deprecated in es6 or above
                        grammarErrorOnNode(node, ts.Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead);
                    }
                }
            }
        }
        function checkExportDeclaration(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) {
                // If we hit an export in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers);
            }
            if (node.moduleSpecifier && node.exportClause && ts.isNamedExports(node.exportClause) && ts.length(node.exportClause.elements) && languageVersion === 0 /* ES3 */) {
                checkExternalEmitHelpers(node, 1048576 /* CreateBinding */);
            }
            checkGrammarExportDeclaration(node);
            if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) {
                if (node.exportClause && !ts.isNamespaceExport(node.exportClause)) {
                    // export { x, y }
                    // export { x, y } from "foo"
                    ts.forEach(node.exportClause.elements, checkExportSpecifier);
                    var inAmbientExternalModule = node.parent.kind === 250 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent);
                    var inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === 250 /* ModuleBlock */ &&
                        !node.moduleSpecifier && node.flags & 8388608 /* Ambient */;
                    if (node.parent.kind !== 290 /* SourceFile */ && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) {
                        error(node, ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace);
                    }
                }
                else {
                    // export * from "foo"
                    var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier);
                    if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) {
                        error(node.moduleSpecifier, ts.Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol));
                    }
                    else if (node.exportClause) {
                        checkAliasSymbol(node.exportClause);
                    }
                    if (moduleKind !== ts.ModuleKind.System && moduleKind < ts.ModuleKind.ES2015) {
                        checkExternalEmitHelpers(node, 65536 /* ExportStar */);
                    }
                }
            }
        }
        function checkGrammarExportDeclaration(node) {
            var _a;
            var isTypeOnlyExportStar = node.isTypeOnly && ((_a = node.exportClause) === null || _a === void 0 ? void 0 : _a.kind) !== 261 /* NamedExports */;
            if (isTypeOnlyExportStar) {
                grammarErrorOnNode(node, ts.Diagnostics.Only_named_exports_may_use_export_type);
            }
            return !isTypeOnlyExportStar;
        }
        function checkGrammarModuleElementContext(node, errorMessage) {
            var isInAppropriateContext = node.parent.kind === 290 /* SourceFile */ || node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 249 /* ModuleDeclaration */;
            if (!isInAppropriateContext) {
                grammarErrorOnFirstToken(node, errorMessage);
            }
            return !isInAppropriateContext;
        }
        function importClauseContainsReferencedImport(importClause) {
            return ts.forEachImportClauseDeclaration(importClause, function (declaration) {
                return !!getSymbolOfNode(declaration).isReferenced;
            });
        }
        function importClauseContainsConstEnumUsedAsValue(importClause) {
            return ts.forEachImportClauseDeclaration(importClause, function (declaration) {
                return !!getSymbolLinks(getSymbolOfNode(declaration)).constEnumReferenced;
            });
        }
        function checkImportsForTypeOnlyConversion(sourceFile) {
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (ts.isImportDeclaration(statement) &&
                    statement.importClause &&
                    !statement.importClause.isTypeOnly &&
                    importClauseContainsReferencedImport(statement.importClause) &&
                    !isReferencedAliasDeclaration(statement.importClause, /*checkChildren*/ true) &&
                    !importClauseContainsConstEnumUsedAsValue(statement.importClause)) {
                    error(statement, ts.Diagnostics.This_import_is_never_used_as_a_value_and_must_use_import_type_because_the_importsNotUsedAsValues_is_set_to_error);
                }
            }
        }
        function checkExportSpecifier(node) {
            checkAliasSymbol(node);
            if (ts.getEmitDeclarations(compilerOptions)) {
                collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true);
            }
            if (!node.parent.parent.moduleSpecifier) {
                var exportedName = node.propertyName || node.name;
                // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases)
                var symbol = resolveName(exportedName, exportedName.escapedText, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, 
                /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
                if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {
                    error(exportedName, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, ts.idText(exportedName));
                }
                else {
                    markExportAsReferenced(node);
                    var target = symbol && (symbol.flags & 2097152 /* Alias */ ? resolveAlias(symbol) : symbol);
                    if (!target || target === unknownSymbol || target.flags & 111551 /* Value */) {
                        checkExpressionCached(node.propertyName || node.name);
                    }
                }
            }
        }
        function checkExportAssignment(node) {
            if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) {
                // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors.
                return;
            }
            var container = node.parent.kind === 290 /* SourceFile */ ? node.parent : node.parent.parent;
            if (container.kind === 249 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                if (node.isExportEquals) {
                    error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace);
                }
                else {
                    error(node, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
                }
                return;
            }
            // Grammar checking
            if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) {
                grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers);
            }
            if (node.expression.kind === 75 /* Identifier */) {
                var id = node.expression;
                var sym = resolveEntityName(id, 67108863 /* All */, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node);
                if (sym) {
                    markAliasReferenced(sym, id);
                    // If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`)
                    var target = sym.flags & 2097152 /* Alias */ ? resolveAlias(sym) : sym;
                    if (target === unknownSymbol || target.flags & 111551 /* Value */) {
                        // However if it is a value, we need to check it's being used correctly
                        checkExpressionCached(node.expression);
                    }
                }
                if (ts.getEmitDeclarations(compilerOptions)) {
                    collectLinkedAliases(node.expression, /*setVisibility*/ true);
                }
            }
            else {
                checkExpressionCached(node.expression);
            }
            checkExternalModuleExports(container);
            if ((node.flags & 8388608 /* Ambient */) && !ts.isEntityNameExpression(node.expression)) {
                grammarErrorOnNode(node.expression, ts.Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context);
            }
            if (node.isExportEquals && !(node.flags & 8388608 /* Ambient */)) {
                if (moduleKind >= ts.ModuleKind.ES2015) {
                    // export assignment is not supported in es6 modules
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead);
                }
                else if (moduleKind === ts.ModuleKind.System) {
                    // system modules does not support export assignment
                    grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system);
                }
            }
        }
        function hasExportedMembers(moduleSymbol) {
            return ts.forEachEntry(moduleSymbol.exports, function (_, id) { return id !== "export="; });
        }
        function checkExternalModuleExports(node) {
            var moduleSymbol = getSymbolOfNode(node);
            var links = getSymbolLinks(moduleSymbol);
            if (!links.exportsChecked) {
                var exportEqualsSymbol = moduleSymbol.exports.get("export=");
                if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) {
                    var declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration;
                    if (!isTopLevelInExternalModuleAugmentation(declaration) && !ts.isInJSFile(declaration)) {
                        error(declaration, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
                    }
                }
                // Checks for export * conflicts
                var exports_2 = getExportsOfModule(moduleSymbol);
                if (exports_2) {
                    exports_2.forEach(function (_a, id) {
                        var declarations = _a.declarations, flags = _a.flags;
                        if (id === "__export") {
                            return;
                        }
                        // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
                        // (TS Exceptions: namespaces, function overloads, enums, and interfaces)
                        if (flags & (1920 /* Namespace */ | 64 /* Interface */ | 384 /* Enum */)) {
                            return;
                        }
                        var exportedDeclarationsCount = ts.countWhere(declarations, isNotOverloadAndNotAccessor);
                        if (flags & 524288 /* TypeAlias */ && exportedDeclarationsCount <= 2) {
                            // it is legal to merge type alias with other values
                            // so count should be either 1 (just type alias) or 2 (type alias + merged value)
                            return;
                        }
                        if (exportedDeclarationsCount > 1) {
                            for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) {
                                var declaration = declarations_9[_i];
                                if (isNotOverload(declaration)) {
                                    diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id)));
                                }
                            }
                        }
                    });
                }
                links.exportsChecked = true;
            }
        }
        function checkSourceElement(node) {
            if (node) {
                var saveCurrentNode = currentNode;
                currentNode = node;
                instantiationCount = 0;
                checkSourceElementWorker(node);
                currentNode = saveCurrentNode;
            }
        }
        function checkSourceElementWorker(node) {
            if (ts.isInJSFile(node)) {
                ts.forEach(node.jsDoc, function (_a) {
                    var tags = _a.tags;
                    return ts.forEach(tags, checkSourceElement);
                });
            }
            var kind = node.kind;
            if (cancellationToken) {
                // Only bother checking on a few construct kinds.  We don't want to be excessively
                // hitting the cancellation token on every node we check.
                switch (kind) {
                    case 249 /* ModuleDeclaration */:
                    case 245 /* ClassDeclaration */:
                    case 246 /* InterfaceDeclaration */:
                    case 244 /* FunctionDeclaration */:
                        cancellationToken.throwIfCancellationRequested();
                }
            }
            if (kind >= 225 /* FirstStatement */ && kind <= 241 /* LastStatement */ && node.flowNode && !isReachableFlowNode(node.flowNode)) {
                errorOrSuggestion(compilerOptions.allowUnreachableCode === false, node, ts.Diagnostics.Unreachable_code_detected);
            }
            switch (kind) {
                case 155 /* TypeParameter */:
                    return checkTypeParameter(node);
                case 156 /* Parameter */:
                    return checkParameter(node);
                case 159 /* PropertyDeclaration */:
                    return checkPropertyDeclaration(node);
                case 158 /* PropertySignature */:
                    return checkPropertySignature(node);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */:
                case 165 /* CallSignature */:
                case 166 /* ConstructSignature */:
                case 167 /* IndexSignature */:
                    return checkSignatureDeclaration(node);
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    return checkMethodDeclaration(node);
                case 162 /* Constructor */:
                    return checkConstructorDeclaration(node);
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return checkAccessorDeclaration(node);
                case 169 /* TypeReference */:
                    return checkTypeReferenceNode(node);
                case 168 /* TypePredicate */:
                    return checkTypePredicate(node);
                case 172 /* TypeQuery */:
                    return checkTypeQuery(node);
                case 173 /* TypeLiteral */:
                    return checkTypeLiteral(node);
                case 174 /* ArrayType */:
                    return checkArrayType(node);
                case 175 /* TupleType */:
                    return checkTupleType(node);
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                    return checkUnionOrIntersectionType(node);
                case 182 /* ParenthesizedType */:
                case 176 /* OptionalType */:
                case 177 /* RestType */:
                    return checkSourceElement(node.type);
                case 183 /* ThisType */:
                    return checkThisType(node);
                case 184 /* TypeOperator */:
                    return checkTypeOperator(node);
                case 180 /* ConditionalType */:
                    return checkConditionalType(node);
                case 181 /* InferType */:
                    return checkInferType(node);
                case 188 /* ImportType */:
                    return checkImportType(node);
                case 307 /* JSDocAugmentsTag */:
                    return checkJSDocAugmentsTag(node);
                case 308 /* JSDocImplementsTag */:
                    return checkJSDocImplementsTag(node);
                case 322 /* JSDocTypedefTag */:
                case 315 /* JSDocCallbackTag */:
                case 316 /* JSDocEnumTag */:
                    return checkJSDocTypeAliasTag(node);
                case 321 /* JSDocTemplateTag */:
                    return checkJSDocTemplateTag(node);
                case 320 /* JSDocTypeTag */:
                    return checkJSDocTypeTag(node);
                case 317 /* JSDocParameterTag */:
                    return checkJSDocParameterTag(node);
                case 323 /* JSDocPropertyTag */:
                    return checkJSDocPropertyTag(node);
                case 300 /* JSDocFunctionType */:
                    checkJSDocFunctionType(node);
                // falls through
                case 298 /* JSDocNonNullableType */:
                case 297 /* JSDocNullableType */:
                case 295 /* JSDocAllType */:
                case 296 /* JSDocUnknownType */:
                case 304 /* JSDocTypeLiteral */:
                    checkJSDocTypeIsInJsFile(node);
                    ts.forEachChild(node, checkSourceElement);
                    return;
                case 301 /* JSDocVariadicType */:
                    checkJSDocVariadicType(node);
                    return;
                case 294 /* JSDocTypeExpression */:
                    return checkSourceElement(node.type);
                case 185 /* IndexedAccessType */:
                    return checkIndexedAccessType(node);
                case 186 /* MappedType */:
                    return checkMappedType(node);
                case 244 /* FunctionDeclaration */:
                    return checkFunctionDeclaration(node);
                case 223 /* Block */:
                case 250 /* ModuleBlock */:
                    return checkBlock(node);
                case 225 /* VariableStatement */:
                    return checkVariableStatement(node);
                case 226 /* ExpressionStatement */:
                    return checkExpressionStatement(node);
                case 227 /* IfStatement */:
                    return checkIfStatement(node);
                case 228 /* DoStatement */:
                    return checkDoStatement(node);
                case 229 /* WhileStatement */:
                    return checkWhileStatement(node);
                case 230 /* ForStatement */:
                    return checkForStatement(node);
                case 231 /* ForInStatement */:
                    return checkForInStatement(node);
                case 232 /* ForOfStatement */:
                    return checkForOfStatement(node);
                case 233 /* ContinueStatement */:
                case 234 /* BreakStatement */:
                    return checkBreakOrContinueStatement(node);
                case 235 /* ReturnStatement */:
                    return checkReturnStatement(node);
                case 236 /* WithStatement */:
                    return checkWithStatement(node);
                case 237 /* SwitchStatement */:
                    return checkSwitchStatement(node);
                case 238 /* LabeledStatement */:
                    return checkLabeledStatement(node);
                case 239 /* ThrowStatement */:
                    return checkThrowStatement(node);
                case 240 /* TryStatement */:
                    return checkTryStatement(node);
                case 242 /* VariableDeclaration */:
                    return checkVariableDeclaration(node);
                case 191 /* BindingElement */:
                    return checkBindingElement(node);
                case 245 /* ClassDeclaration */:
                    return checkClassDeclaration(node);
                case 246 /* InterfaceDeclaration */:
                    return checkInterfaceDeclaration(node);
                case 247 /* TypeAliasDeclaration */:
                    return checkTypeAliasDeclaration(node);
                case 248 /* EnumDeclaration */:
                    return checkEnumDeclaration(node);
                case 249 /* ModuleDeclaration */:
                    return checkModuleDeclaration(node);
                case 254 /* ImportDeclaration */:
                    return checkImportDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    return checkImportEqualsDeclaration(node);
                case 260 /* ExportDeclaration */:
                    return checkExportDeclaration(node);
                case 259 /* ExportAssignment */:
                    return checkExportAssignment(node);
                case 224 /* EmptyStatement */:
                case 241 /* DebuggerStatement */:
                    checkGrammarStatementInAmbientContext(node);
                    return;
                case 264 /* MissingDeclaration */:
                    return checkMissingDeclaration(node);
            }
        }
        function checkJSDocTypeIsInJsFile(node) {
            if (!ts.isInJSFile(node)) {
                grammarErrorOnNode(node, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments);
            }
        }
        function checkJSDocVariadicType(node) {
            checkJSDocTypeIsInJsFile(node);
            checkSourceElement(node.type);
            // Only legal location is in the *last* parameter tag or last parameter of a JSDoc function.
            var parent = node.parent;
            if (ts.isParameter(parent) && ts.isJSDocFunctionType(parent.parent)) {
                if (ts.last(parent.parent.parameters) !== parent) {
                    error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
                }
                return;
            }
            if (!ts.isJSDocTypeExpression(parent)) {
                error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature);
            }
            var paramTag = node.parent.parent;
            if (!ts.isJSDocParameterTag(paramTag)) {
                error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature);
                return;
            }
            var param = ts.getParameterSymbolFromJSDoc(paramTag);
            if (!param) {
                // We will error in `checkJSDocParameterTag`.
                return;
            }
            var host = ts.getHostSignatureFromJSDoc(paramTag);
            if (!host || ts.last(host.parameters).symbol !== param) {
                error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
            }
        }
        function getTypeFromJSDocVariadicType(node) {
            var type = getTypeFromTypeNode(node.type);
            var parent = node.parent;
            var paramTag = node.parent.parent;
            if (ts.isJSDocTypeExpression(node.parent) && ts.isJSDocParameterTag(paramTag)) {
                // Else we will add a diagnostic, see `checkJSDocVariadicType`.
                var host_1 = ts.getHostSignatureFromJSDoc(paramTag);
                if (host_1) {
                    /*
                    Only return an array type if the corresponding parameter is marked as a rest parameter, or if there are no parameters.
                    So in the following situation we will not create an array type:
                        /** @param {...number} a * /
                        function f(a) {}
                    Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type.
                    */
                    var lastParamDeclaration = ts.lastOrUndefined(host_1.parameters);
                    var symbol = ts.getParameterSymbolFromJSDoc(paramTag);
                    if (!lastParamDeclaration ||
                        symbol && lastParamDeclaration.symbol === symbol && ts.isRestParameter(lastParamDeclaration)) {
                        return createArrayType(type);
                    }
                }
            }
            if (ts.isParameter(parent) && ts.isJSDocFunctionType(parent.parent)) {
                return createArrayType(type);
            }
            return addOptionality(type);
        }
        // Function and class expression bodies are checked after all statements in the enclosing body. This is
        // to ensure constructs like the following are permitted:
        //     const foo = function () {
        //        const s = foo();
        //        return "hello";
        //     }
        // Here, performing a full type check of the body of the function expression whilst in the process of
        // determining the type of foo would cause foo to be given type any because of the recursive reference.
        // Delaying the type check of the body ensures foo has been assigned a type.
        function checkNodeDeferred(node) {
            var enclosingFile = ts.getSourceFileOfNode(node);
            var links = getNodeLinks(enclosingFile);
            if (!(links.flags & 1 /* TypeChecked */)) {
                links.deferredNodes = links.deferredNodes || ts.createMap();
                var id = "" + getNodeId(node);
                links.deferredNodes.set(id, node);
            }
        }
        function checkDeferredNodes(context) {
            var links = getNodeLinks(context);
            if (links.deferredNodes) {
                links.deferredNodes.forEach(checkDeferredNode);
            }
        }
        function checkDeferredNode(node) {
            var saveCurrentNode = currentNode;
            currentNode = node;
            instantiationCount = 0;
            switch (node.kind) {
                case 196 /* CallExpression */:
                case 197 /* NewExpression */:
                case 198 /* TaggedTemplateExpression */:
                case 157 /* Decorator */:
                case 268 /* JsxOpeningElement */:
                    // These node kinds are deferred checked when overload resolution fails
                    // To save on work, we ensure the arguments are checked just once, in
                    // a deferred way
                    resolveUntypedCall(node);
                    break;
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    checkFunctionExpressionOrObjectLiteralMethodDeferred(node);
                    break;
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    checkAccessorDeclaration(node);
                    break;
                case 214 /* ClassExpression */:
                    checkClassExpressionDeferred(node);
                    break;
                case 267 /* JsxSelfClosingElement */:
                    checkJsxSelfClosingElementDeferred(node);
                    break;
                case 266 /* JsxElement */:
                    checkJsxElementDeferred(node);
                    break;
            }
            currentNode = saveCurrentNode;
        }
        function checkSourceFile(node) {
            ts.performance.mark("beforeCheck");
            checkSourceFileWorker(node);
            ts.performance.mark("afterCheck");
            ts.performance.measure("Check", "beforeCheck", "afterCheck");
        }
        function unusedIsError(kind, isAmbient) {
            if (isAmbient) {
                return false;
            }
            switch (kind) {
                case 0 /* Local */:
                    return !!compilerOptions.noUnusedLocals;
                case 1 /* Parameter */:
                    return !!compilerOptions.noUnusedParameters;
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function getPotentiallyUnusedIdentifiers(sourceFile) {
            return allPotentiallyUnusedIdentifiers.get(sourceFile.path) || ts.emptyArray;
        }
        // Fully type check a source file and collect the relevant diagnostics.
        function checkSourceFileWorker(node) {
            var links = getNodeLinks(node);
            if (!(links.flags & 1 /* TypeChecked */)) {
                if (ts.skipTypeChecking(node, compilerOptions, host)) {
                    return;
                }
                // Grammar checking
                checkGrammarSourceFile(node);
                ts.clear(potentialThisCollisions);
                ts.clear(potentialNewTargetCollisions);
                ts.clear(potentialWeakMapCollisions);
                ts.forEach(node.statements, checkSourceElement);
                checkSourceElement(node.endOfFileToken);
                checkDeferredNodes(node);
                if (ts.isExternalOrCommonJsModule(node)) {
                    registerForUnusedIdentifiersCheck(node);
                }
                if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
                    checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), function (containingNode, kind, diag) {
                        if (!ts.containsParseError(containingNode) && unusedIsError(kind, !!(containingNode.flags & 8388608 /* Ambient */))) {
                            diagnostics.add(diag);
                        }
                    });
                }
                if (compilerOptions.importsNotUsedAsValues === 2 /* Error */ &&
                    !node.isDeclarationFile &&
                    ts.isExternalModule(node)) {
                    checkImportsForTypeOnlyConversion(node);
                }
                if (ts.isExternalOrCommonJsModule(node)) {
                    checkExternalModuleExports(node);
                }
                if (potentialThisCollisions.length) {
                    ts.forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
                    ts.clear(potentialThisCollisions);
                }
                if (potentialNewTargetCollisions.length) {
                    ts.forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope);
                    ts.clear(potentialNewTargetCollisions);
                }
                if (potentialWeakMapCollisions.length) {
                    ts.forEach(potentialWeakMapCollisions, checkWeakMapCollision);
                    ts.clear(potentialWeakMapCollisions);
                }
                links.flags |= 1 /* TypeChecked */;
            }
        }
        function getDiagnostics(sourceFile, ct) {
            try {
                // Record the cancellation token so it can be checked later on during checkSourceElement.
                // Do this in a finally block so we can ensure that it gets reset back to nothing after
                // this call is done.
                cancellationToken = ct;
                return getDiagnosticsWorker(sourceFile);
            }
            finally {
                cancellationToken = undefined;
            }
        }
        function getDiagnosticsWorker(sourceFile) {
            throwIfNonDiagnosticsProducing();
            if (sourceFile) {
                // Some global diagnostics are deferred until they are needed and
                // may not be reported in the first call to getGlobalDiagnostics.
                // We should catch these changes and report them.
                var previousGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
                var previousGlobalDiagnosticsSize = previousGlobalDiagnostics.length;
                checkSourceFile(sourceFile);
                var semanticDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
                var currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
                if (currentGlobalDiagnostics !== previousGlobalDiagnostics) {
                    // If the arrays are not the same reference, new diagnostics were added.
                    var deferredGlobalDiagnostics = ts.relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, ts.compareDiagnostics);
                    return ts.concatenate(deferredGlobalDiagnostics, semanticDiagnostics);
                }
                else if (previousGlobalDiagnosticsSize === 0 && currentGlobalDiagnostics.length > 0) {
                    // If the arrays are the same reference, but the length has changed, a single
                    // new diagnostic was added as DiagnosticCollection attempts to reuse the
                    // same array.
                    return ts.concatenate(currentGlobalDiagnostics, semanticDiagnostics);
                }
                return semanticDiagnostics;
            }
            // Global diagnostics are always added when a file is not provided to
            // getDiagnostics
            ts.forEach(host.getSourceFiles(), checkSourceFile);
            return diagnostics.getDiagnostics();
        }
        function getGlobalDiagnostics() {
            throwIfNonDiagnosticsProducing();
            return diagnostics.getGlobalDiagnostics();
        }
        function throwIfNonDiagnosticsProducing() {
            if (!produceDiagnostics) {
                throw new Error("Trying to get diagnostics from a type checker that does not produce them.");
            }
        }
        // Language service support
        function getSymbolsInScope(location, meaning) {
            if (location.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return [];
            }
            var symbols = ts.createSymbolTable();
            var isStatic = false;
            populateSymbols();
            symbols.delete("this" /* This */); // Not a symbol, a keyword
            return symbolsToArray(symbols);
            function populateSymbols() {
                while (location) {
                    if (location.locals && !isGlobalSourceFile(location)) {
                        copySymbols(location.locals, meaning);
                    }
                    switch (location.kind) {
                        case 290 /* SourceFile */:
                            if (!ts.isExternalOrCommonJsModule(location))
                                break;
                        // falls through
                        case 249 /* ModuleDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 2623475 /* ModuleMember */);
                            break;
                        case 248 /* EnumDeclaration */:
                            copySymbols(getSymbolOfNode(location).exports, meaning & 8 /* EnumMember */);
                            break;
                        case 214 /* ClassExpression */:
                            var className = location.name;
                            if (className) {
                                copySymbol(location.symbol, meaning);
                            }
                        // this fall-through is necessary because we would like to handle
                        // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration.
                        // falls through
                        case 245 /* ClassDeclaration */:
                        case 246 /* InterfaceDeclaration */:
                            // If we didn't come from static member of class or interface,
                            // add the type parameters into the symbol table
                            // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol.
                            // Note: that the memberFlags come from previous iteration.
                            if (!isStatic) {
                                copySymbols(getMembersOfSymbol(getSymbolOfNode(location)), meaning & 788968 /* Type */);
                            }
                            break;
                        case 201 /* FunctionExpression */:
                            var funcName = location.name;
                            if (funcName) {
                                copySymbol(location.symbol, meaning);
                            }
                            break;
                    }
                    if (ts.introducesArgumentsExoticObject(location)) {
                        copySymbol(argumentsSymbol, meaning);
                    }
                    isStatic = ts.hasModifier(location, 32 /* Static */);
                    location = location.parent;
                }
                copySymbols(globals, meaning);
            }
            /**
             * Copy the given symbol into symbol tables if the symbol has the given meaning
             * and it doesn't already existed in the symbol table
             * @param key a key for storing in symbol table; if undefined, use symbol.name
             * @param symbol the symbol to be added into symbol table
             * @param meaning meaning of symbol to filter by before adding to symbol table
             */
            function copySymbol(symbol, meaning) {
                if (ts.getCombinedLocalAndExportSymbolFlags(symbol) & meaning) {
                    var id = symbol.escapedName;
                    // We will copy all symbol regardless of its reserved name because
                    // symbolsToArray will check whether the key is a reserved name and
                    // it will not copy symbol with reserved name to the array
                    if (!symbols.has(id)) {
                        symbols.set(id, symbol);
                    }
                }
            }
            function copySymbols(source, meaning) {
                if (meaning) {
                    source.forEach(function (symbol) {
                        copySymbol(symbol, meaning);
                    });
                }
            }
        }
        function isTypeDeclarationName(name) {
            return name.kind === 75 /* Identifier */ &&
                isTypeDeclaration(name.parent) &&
                name.parent.name === name;
        }
        function isTypeDeclaration(node) {
            switch (node.kind) {
                case 155 /* TypeParameter */:
                case 245 /* ClassDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 248 /* EnumDeclaration */:
                    return true;
                case 255 /* ImportClause */:
                    return node.isTypeOnly;
                case 258 /* ImportSpecifier */:
                case 263 /* ExportSpecifier */:
                    return node.parent.parent.isTypeOnly;
                default:
                    return false;
            }
        }
        // True if the given identifier is part of a type reference
        function isTypeReferenceIdentifier(node) {
            while (node.parent.kind === 153 /* QualifiedName */) {
                node = node.parent;
            }
            return node.parent.kind === 169 /* TypeReference */;
        }
        function isHeritageClauseElementIdentifier(node) {
            while (node.parent.kind === 194 /* PropertyAccessExpression */) {
                node = node.parent;
            }
            return node.parent.kind === 216 /* ExpressionWithTypeArguments */;
        }
        function forEachEnclosingClass(node, callback) {
            var result;
            while (true) {
                node = ts.getContainingClass(node);
                if (!node)
                    break;
                if (result = callback(node))
                    break;
            }
            return result;
        }
        function isNodeUsedDuringClassInitialization(node) {
            return !!ts.findAncestor(node, function (element) {
                if (ts.isConstructorDeclaration(element) && ts.nodeIsPresent(element.body) || ts.isPropertyDeclaration(element)) {
                    return true;
                }
                else if (ts.isClassLike(element) || ts.isFunctionLikeDeclaration(element)) {
                    return "quit";
                }
                return false;
            });
        }
        function isNodeWithinClass(node, classDeclaration) {
            return !!forEachEnclosingClass(node, function (n) { return n === classDeclaration; });
        }
        function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) {
            while (nodeOnRightSide.parent.kind === 153 /* QualifiedName */) {
                nodeOnRightSide = nodeOnRightSide.parent;
            }
            if (nodeOnRightSide.parent.kind === 253 /* ImportEqualsDeclaration */) {
                return nodeOnRightSide.parent.moduleReference === nodeOnRightSide ? nodeOnRightSide.parent : undefined;
            }
            if (nodeOnRightSide.parent.kind === 259 /* ExportAssignment */) {
                return nodeOnRightSide.parent.expression === nodeOnRightSide ? nodeOnRightSide.parent : undefined;
            }
            return undefined;
        }
        function isInRightSideOfImportOrExportAssignment(node) {
            return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined;
        }
        function getSpecialPropertyAssignmentSymbolFromEntityName(entityName) {
            var specialPropertyAssignmentKind = ts.getAssignmentDeclarationKind(entityName.parent.parent);
            switch (specialPropertyAssignmentKind) {
                case 1 /* ExportsProperty */:
                case 3 /* PrototypeProperty */:
                    return getSymbolOfNode(entityName.parent);
                case 4 /* ThisProperty */:
                case 2 /* ModuleExports */:
                case 5 /* Property */:
                    return getSymbolOfNode(entityName.parent.parent);
            }
        }
        function isImportTypeQualifierPart(node) {
            var parent = node.parent;
            while (ts.isQualifiedName(parent)) {
                node = parent;
                parent = parent.parent;
            }
            if (parent && parent.kind === 188 /* ImportType */ && parent.qualifier === node) {
                return parent;
            }
            return undefined;
        }
        function getSymbolOfNameOrPropertyAccessExpression(name) {
            if (ts.isDeclarationName(name)) {
                return getSymbolOfNode(name.parent);
            }
            if (ts.isInJSFile(name) &&
                name.parent.kind === 194 /* PropertyAccessExpression */ &&
                name.parent === name.parent.parent.left) {
                // Check if this is a special property assignment
                if (!ts.isPrivateIdentifier(name)) {
                    var specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(name);
                    if (specialPropertyAssignmentSymbol) {
                        return specialPropertyAssignmentSymbol;
                    }
                }
            }
            if (name.parent.kind === 259 /* ExportAssignment */ && ts.isEntityNameExpression(name)) {
                // Even an entity name expression that doesn't resolve as an entityname may still typecheck as a property access expression
                var success = resolveEntityName(name, 
                /*all meanings*/ 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, /*ignoreErrors*/ true);
                if (success && success !== unknownSymbol) {
                    return success;
                }
            }
            else if (!ts.isPropertyAccessExpression(name) && !ts.isPrivateIdentifier(name) && isInRightSideOfImportOrExportAssignment(name)) {
                // Since we already checked for ExportAssignment, this really could only be an Import
                var importEqualsDeclaration = ts.getAncestor(name, 253 /* ImportEqualsDeclaration */);
                ts.Debug.assert(importEqualsDeclaration !== undefined);
                return getSymbolOfPartOfRightHandSideOfImportEquals(name, /*dontResolveAlias*/ true);
            }
            if (!ts.isPropertyAccessExpression(name) && !ts.isPrivateIdentifier(name)) {
                var possibleImportNode = isImportTypeQualifierPart(name);
                if (possibleImportNode) {
                    getTypeFromTypeNode(possibleImportNode);
                    var sym = getNodeLinks(name).resolvedSymbol;
                    return sym === unknownSymbol ? undefined : sym;
                }
            }
            while (ts.isRightSideOfQualifiedNameOrPropertyAccess(name)) {
                name = name.parent;
            }
            if (isHeritageClauseElementIdentifier(name)) {
                var meaning = 0 /* None */;
                // In an interface or class, we're definitely interested in a type.
                if (name.parent.kind === 216 /* ExpressionWithTypeArguments */) {
                    meaning = 788968 /* Type */;
                    // In a class 'extends' clause we are also looking for a value.
                    if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(name.parent)) {
                        meaning |= 111551 /* Value */;
                    }
                }
                else {
                    meaning = 1920 /* Namespace */;
                }
                meaning |= 2097152 /* Alias */;
                var entityNameSymbol = ts.isEntityNameExpression(name) ? resolveEntityName(name, meaning) : undefined;
                if (entityNameSymbol) {
                    return entityNameSymbol;
                }
            }
            if (name.parent.kind === 317 /* JSDocParameterTag */) {
                return ts.getParameterSymbolFromJSDoc(name.parent);
            }
            if (name.parent.kind === 155 /* TypeParameter */ && name.parent.parent.kind === 321 /* JSDocTemplateTag */) {
                ts.Debug.assert(!ts.isInJSFile(name)); // Otherwise `isDeclarationName` would have been true.
                var typeParameter = ts.getTypeParameterFromJsDoc(name.parent);
                return typeParameter && typeParameter.symbol;
            }
            if (ts.isExpressionNode(name)) {
                if (ts.nodeIsMissing(name)) {
                    // Missing entity name.
                    return undefined;
                }
                if (name.kind === 75 /* Identifier */) {
                    if (ts.isJSXTagName(name) && isJsxIntrinsicIdentifier(name)) {
                        var symbol = getIntrinsicTagSymbol(name.parent);
                        return symbol === unknownSymbol ? undefined : symbol;
                    }
                    return resolveEntityName(name, 111551 /* Value */, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
                }
                else if (name.kind === 194 /* PropertyAccessExpression */ || name.kind === 153 /* QualifiedName */) {
                    var links = getNodeLinks(name);
                    if (links.resolvedSymbol) {
                        return links.resolvedSymbol;
                    }
                    if (name.kind === 194 /* PropertyAccessExpression */) {
                        checkPropertyAccessExpression(name);
                    }
                    else {
                        checkQualifiedName(name);
                    }
                    return links.resolvedSymbol;
                }
            }
            else if (isTypeReferenceIdentifier(name)) {
                var meaning = name.parent.kind === 169 /* TypeReference */ ? 788968 /* Type */ : 1920 /* Namespace */;
                return resolveEntityName(name, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true);
            }
            if (name.parent.kind === 168 /* TypePredicate */) {
                return resolveEntityName(name, /*meaning*/ 1 /* FunctionScopedVariable */);
            }
            // Do we want to return undefined here?
            return undefined;
        }
        function getSymbolAtLocation(node, ignoreErrors) {
            if (node.kind === 290 /* SourceFile */) {
                return ts.isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined;
            }
            var parent = node.parent;
            var grandParent = parent.parent;
            if (node.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return undefined;
            }
            if (isDeclarationNameOrImportPropertyName(node)) {
                // This is a declaration, call getSymbolOfNode
                var parentSymbol = getSymbolOfNode(parent);
                return ts.isImportOrExportSpecifier(node.parent) && node.parent.propertyName === node
                    ? getImmediateAliasedSymbol(parentSymbol)
                    : parentSymbol;
            }
            else if (ts.isLiteralComputedPropertyDeclarationName(node)) {
                return getSymbolOfNode(parent.parent);
            }
            if (node.kind === 75 /* Identifier */) {
                if (isInRightSideOfImportOrExportAssignment(node)) {
                    return getSymbolOfNameOrPropertyAccessExpression(node);
                }
                else if (parent.kind === 191 /* BindingElement */ &&
                    grandParent.kind === 189 /* ObjectBindingPattern */ &&
                    node === parent.propertyName) {
                    var typeOfPattern = getTypeOfNode(grandParent);
                    var propertyDeclaration = getPropertyOfType(typeOfPattern, node.escapedText);
                    if (propertyDeclaration) {
                        return propertyDeclaration;
                    }
                }
            }
            switch (node.kind) {
                case 75 /* Identifier */:
                case 76 /* PrivateIdentifier */:
                case 194 /* PropertyAccessExpression */:
                case 153 /* QualifiedName */:
                    return getSymbolOfNameOrPropertyAccessExpression(node);
                case 104 /* ThisKeyword */:
                    var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false);
                    if (ts.isFunctionLike(container)) {
                        var sig = getSignatureFromDeclaration(container);
                        if (sig.thisParameter) {
                            return sig.thisParameter;
                        }
                    }
                    if (ts.isInExpressionContext(node)) {
                        return checkExpression(node).symbol;
                    }
                // falls through
                case 183 /* ThisType */:
                    return getTypeFromThisTypeNode(node).symbol;
                case 102 /* SuperKeyword */:
                    return checkExpression(node).symbol;
                case 129 /* ConstructorKeyword */:
                    // constructor keyword for an overload, should take us to the definition if it exist
                    var constructorDeclaration = node.parent;
                    if (constructorDeclaration && constructorDeclaration.kind === 162 /* Constructor */) {
                        return constructorDeclaration.parent.symbol;
                    }
                    return undefined;
                case 10 /* StringLiteral */:
                case 14 /* NoSubstitutionTemplateLiteral */:
                    // 1). import x = require("./mo/*gotToDefinitionHere*/d")
                    // 2). External module name in an import declaration
                    // 3). Dynamic import call or require in javascript
                    // 4). type A = import("./f/*gotToDefinitionHere*/oo")
                    if ((ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
                        ((node.parent.kind === 254 /* ImportDeclaration */ || node.parent.kind === 260 /* ExportDeclaration */) && node.parent.moduleSpecifier === node) ||
                        ((ts.isInJSFile(node) && ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteralLike*/ false)) || ts.isImportCall(node.parent)) ||
                        (ts.isLiteralTypeNode(node.parent) && ts.isLiteralImportTypeNode(node.parent.parent) && node.parent.parent.argument === node.parent)) {
                        return resolveExternalModuleName(node, node, ignoreErrors);
                    }
                    if (ts.isCallExpression(parent) && ts.isBindableObjectDefinePropertyCall(parent) && parent.arguments[1] === node) {
                        return getSymbolOfNode(parent);
                    }
                // falls through
                case 8 /* NumericLiteral */:
                    // index access
                    var objectType = ts.isElementAccessExpression(parent)
                        ? parent.argumentExpression === node ? getTypeOfExpression(parent.expression) : undefined
                        : ts.isLiteralTypeNode(parent) && ts.isIndexedAccessTypeNode(grandParent)
                            ? getTypeFromTypeNode(grandParent.objectType)
                            : undefined;
                    return objectType && getPropertyOfType(objectType, ts.escapeLeadingUnderscores(node.text));
                case 84 /* DefaultKeyword */:
                case 94 /* FunctionKeyword */:
                case 38 /* EqualsGreaterThanToken */:
                case 80 /* ClassKeyword */:
                    return getSymbolOfNode(node.parent);
                case 188 /* ImportType */:
                    return ts.isLiteralImportTypeNode(node) ? getSymbolAtLocation(node.argument.literal, ignoreErrors) : undefined;
                case 89 /* ExportKeyword */:
                    return ts.isExportAssignment(node.parent) ? ts.Debug.checkDefined(node.parent.symbol) : undefined;
                default:
                    return undefined;
            }
        }
        function getShorthandAssignmentValueSymbol(location) {
            if (location && location.kind === 282 /* ShorthandPropertyAssignment */) {
                return resolveEntityName(location.name, 111551 /* Value */ | 2097152 /* Alias */);
            }
            return undefined;
        }
        /** Returns the target of an export specifier without following aliases */
        function getExportSpecifierLocalTargetSymbol(node) {
            return node.parent.parent.moduleSpecifier ?
                getExternalModuleMember(node.parent.parent, node) :
                resolveEntityName(node.propertyName || node.name, 111551 /* Value */ | 788968 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */);
        }
        function getTypeOfNode(node) {
            if (node.flags & 16777216 /* InWithStatement */) {
                // We cannot answer semantic questions within a with block, do not proceed any further
                return errorType;
            }
            var classDecl = ts.tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node);
            var classType = classDecl && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(classDecl.class));
            if (ts.isPartOfTypeNode(node)) {
                var typeFromTypeNode = getTypeFromTypeNode(node);
                return classType ? getTypeWithThisArgument(typeFromTypeNode, classType.thisType) : typeFromTypeNode;
            }
            if (ts.isExpressionNode(node)) {
                return getRegularTypeOfExpression(node);
            }
            if (classType && !classDecl.isImplements) {
                // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the
                // extends clause of a class. We handle that case here.
                var baseType = ts.firstOrUndefined(getBaseTypes(classType));
                return baseType ? getTypeWithThisArgument(baseType, classType.thisType) : errorType;
            }
            if (isTypeDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                var symbol = getSymbolOfNode(node);
                return getDeclaredTypeOfSymbol(symbol);
            }
            if (isTypeDeclarationName(node)) {
                var symbol = getSymbolAtLocation(node);
                return symbol ? getDeclaredTypeOfSymbol(symbol) : errorType;
            }
            if (ts.isDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                var symbol = getSymbolOfNode(node);
                return getTypeOfSymbol(symbol);
            }
            if (isDeclarationNameOrImportPropertyName(node)) {
                var symbol = getSymbolAtLocation(node);
                if (symbol) {
                    return getTypeOfSymbol(symbol);
                }
                return errorType;
            }
            if (ts.isBindingPattern(node)) {
                return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true) || errorType;
            }
            if (isInRightSideOfImportOrExportAssignment(node)) {
                var symbol = getSymbolAtLocation(node);
                if (symbol) {
                    var declaredType = getDeclaredTypeOfSymbol(symbol);
                    return declaredType !== errorType ? declaredType : getTypeOfSymbol(symbol);
                }
            }
            return errorType;
        }
        // Gets the type of object literal or array literal of destructuring assignment.
        // { a } from
        //     for ( { a } of elems) {
        //     }
        // [ a ] from
        //     [a] = [ some array ...]
        function getTypeOfAssignmentPattern(expr) {
            ts.Debug.assert(expr.kind === 193 /* ObjectLiteralExpression */ || expr.kind === 192 /* ArrayLiteralExpression */);
            // If this is from "for of"
            //     for ( { a } of elems) {
            //     }
            if (expr.parent.kind === 232 /* ForOfStatement */) {
                var iteratedType = checkRightHandSideOfForOf(expr.parent);
                return checkDestructuringAssignment(expr, iteratedType || errorType);
            }
            // If this is from "for" initializer
            //     for ({a } = elems[0];.....) { }
            if (expr.parent.kind === 209 /* BinaryExpression */) {
                var iteratedType = getTypeOfExpression(expr.parent.right);
                return checkDestructuringAssignment(expr, iteratedType || errorType);
            }
            // If this is from nested object binding pattern
            //     for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) {
            if (expr.parent.kind === 281 /* PropertyAssignment */) {
                var node_4 = ts.cast(expr.parent.parent, ts.isObjectLiteralExpression);
                var typeOfParentObjectLiteral = getTypeOfAssignmentPattern(node_4) || errorType;
                var propertyIndex = ts.indexOfNode(node_4.properties, expr.parent);
                return checkObjectLiteralDestructuringPropertyAssignment(node_4, typeOfParentObjectLiteral, propertyIndex);
            }
            // Array literal assignment - array destructuring pattern
            var node = ts.cast(expr.parent, ts.isArrayLiteralExpression);
            //    [{ property1: p1, property2 }] = elems;
            var typeOfArrayLiteral = getTypeOfAssignmentPattern(node) || errorType;
            var elementType = checkIteratedTypeOrElementType(65 /* Destructuring */, typeOfArrayLiteral, undefinedType, expr.parent) || errorType;
            return checkArrayLiteralDestructuringElementAssignment(node, typeOfArrayLiteral, node.elements.indexOf(expr), elementType);
        }
        // Gets the property symbol corresponding to the property in destructuring assignment
        // 'property1' from
        //     for ( { property1: a } of elems) {
        //     }
        // 'property1' at location 'a' from:
        //     [a] = [ property1, property2 ]
        function getPropertySymbolOfDestructuringAssignment(location) {
            // Get the type of the object or array literal and then look for property of given name in the type
            var typeOfObjectLiteral = getTypeOfAssignmentPattern(ts.cast(location.parent.parent, ts.isAssignmentPattern));
            return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.escapedText);
        }
        function getRegularTypeOfExpression(expr) {
            if (ts.isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
                expr = expr.parent;
            }
            return getRegularTypeOfLiteralType(getTypeOfExpression(expr));
        }
        /**
         * Gets either the static or instance type of a class element, based on
         * whether the element is declared as "static".
         */
        function getParentTypeOfClassElement(node) {
            var classSymbol = getSymbolOfNode(node.parent);
            return ts.hasModifier(node, 32 /* Static */)
                ? getTypeOfSymbol(classSymbol)
                : getDeclaredTypeOfSymbol(classSymbol);
        }
        function getClassElementPropertyKeyType(element) {
            var name = element.name;
            switch (name.kind) {
                case 75 /* Identifier */:
                    return getLiteralType(ts.idText(name));
                case 8 /* NumericLiteral */:
                case 10 /* StringLiteral */:
                    return getLiteralType(name.text);
                case 154 /* ComputedPropertyName */:
                    var nameType = checkComputedPropertyName(name);
                    return isTypeAssignableToKind(nameType, 12288 /* ESSymbolLike */) ? nameType : stringType;
                default:
                    return ts.Debug.fail("Unsupported property name.");
            }
        }
        // Return the list of properties of the given type, augmented with properties from Function
        // if the type has call or construct signatures
        function getAugmentedPropertiesOfType(type) {
            type = getApparentType(type);
            var propsByName = ts.createSymbolTable(getPropertiesOfType(type));
            var functionType = getSignaturesOfType(type, 0 /* Call */).length ? globalCallableFunctionType :
                getSignaturesOfType(type, 1 /* Construct */).length ? globalNewableFunctionType :
                    undefined;
            if (functionType) {
                ts.forEach(getPropertiesOfType(functionType), function (p) {
                    if (!propsByName.has(p.escapedName)) {
                        propsByName.set(p.escapedName, p);
                    }
                });
            }
            return getNamedMembers(propsByName);
        }
        function typeHasCallOrConstructSignatures(type) {
            return ts.typeHasCallOrConstructSignatures(type, checker);
        }
        function getRootSymbols(symbol) {
            var roots = getImmediateRootSymbols(symbol);
            return roots ? ts.flatMap(roots, getRootSymbols) : [symbol];
        }
        function getImmediateRootSymbols(symbol) {
            if (ts.getCheckFlags(symbol) & 6 /* Synthetic */) {
                return ts.mapDefined(getSymbolLinks(symbol).containingType.types, function (type) { return getPropertyOfType(type, symbol.escapedName); });
            }
            else if (symbol.flags & 33554432 /* Transient */) {
                var _a = symbol, leftSpread = _a.leftSpread, rightSpread = _a.rightSpread, syntheticOrigin = _a.syntheticOrigin;
                return leftSpread ? [leftSpread, rightSpread]
                    : syntheticOrigin ? [syntheticOrigin]
                        : ts.singleElementArray(tryGetAliasTarget(symbol));
            }
            return undefined;
        }
        function tryGetAliasTarget(symbol) {
            var target;
            var next = symbol;
            while (next = getSymbolLinks(next).target) {
                target = next;
            }
            return target;
        }
        // Emitter support
        function isArgumentsLocalBinding(nodeIn) {
            if (!ts.isGeneratedIdentifier(nodeIn)) {
                var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
                if (node) {
                    var isPropertyName_1 = node.parent.kind === 194 /* PropertyAccessExpression */ && node.parent.name === node;
                    return !isPropertyName_1 && getReferencedValueSymbol(node) === argumentsSymbol;
                }
            }
            return false;
        }
        function moduleExportsSomeValue(moduleReferenceExpression) {
            var moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression);
            if (!moduleSymbol || ts.isShorthandAmbientModuleSymbol(moduleSymbol)) {
                // If the module is not found or is shorthand, assume that it may export a value.
                return true;
            }
            var hasExportAssignment = hasExportAssignmentSymbol(moduleSymbol);
            // if module has export assignment then 'resolveExternalModuleSymbol' will return resolved symbol for export assignment
            // otherwise it will return moduleSymbol itself
            moduleSymbol = resolveExternalModuleSymbol(moduleSymbol);
            var symbolLinks = getSymbolLinks(moduleSymbol);
            if (symbolLinks.exportsSomeValue === undefined) {
                // for export assignments - check if resolved symbol for RHS is itself a value
                // otherwise - check if at least one export is value
                symbolLinks.exportsSomeValue = hasExportAssignment
                    ? !!(moduleSymbol.flags & 111551 /* Value */)
                    : ts.forEachEntry(getExportsOfModule(moduleSymbol), isValue);
            }
            return symbolLinks.exportsSomeValue;
            function isValue(s) {
                s = resolveSymbol(s);
                return s && !!(s.flags & 111551 /* Value */);
            }
        }
        function isNameOfModuleOrEnumDeclaration(node) {
            return ts.isModuleOrEnumDeclaration(node.parent) && node === node.parent.name;
        }
        // When resolved as an expression identifier, if the given node references an exported entity, return the declaration
        // node of the exported entity's container. Otherwise, return undefined.
        function getReferencedExportContainer(nodeIn, prefixLocals) {
            var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
            if (node) {
                // When resolving the export container for the name of a module or enum
                // declaration, we need to start resolution at the declaration's container.
                // Otherwise, we could incorrectly resolve the export container as the
                // declaration if it contains an exported member with the same name.
                var symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node));
                if (symbol) {
                    if (symbol.flags & 1048576 /* ExportValue */) {
                        // If we reference an exported entity within the same module declaration, then whether
                        // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the
                        // kinds that we do NOT prefix.
                        var exportSymbol = getMergedSymbol(symbol.exportSymbol);
                        if (!prefixLocals && exportSymbol.flags & 944 /* ExportHasLocal */ && !(exportSymbol.flags & 3 /* Variable */)) {
                            return undefined;
                        }
                        symbol = exportSymbol;
                    }
                    var parentSymbol_1 = getParentOfSymbol(symbol);
                    if (parentSymbol_1) {
                        if (parentSymbol_1.flags & 512 /* ValueModule */ && parentSymbol_1.valueDeclaration.kind === 290 /* SourceFile */) {
                            var symbolFile = parentSymbol_1.valueDeclaration;
                            var referenceFile = ts.getSourceFileOfNode(node);
                            // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined.
                            var symbolIsUmdExport = symbolFile !== referenceFile;
                            return symbolIsUmdExport ? undefined : symbolFile;
                        }
                        return ts.findAncestor(node.parent, function (n) { return ts.isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol_1; });
                    }
                }
            }
        }
        // When resolved as an expression identifier, if the given node references an import, return the declaration of
        // that import. Otherwise, return undefined.
        function getReferencedImportDeclaration(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
            if (node) {
                var symbol = getReferencedValueSymbol(node);
                // We should only get the declaration of an alias if there isn't a local value
                // declaration for the symbol
                if (isNonLocalAlias(symbol, /*excludes*/ 111551 /* Value */) && !getTypeOnlyAliasDeclaration(symbol)) {
                    return getDeclarationOfAliasSymbol(symbol);
                }
            }
            return undefined;
        }
        function isSymbolOfDestructuredElementOfCatchBinding(symbol) {
            return ts.isBindingElement(symbol.valueDeclaration)
                && ts.walkUpBindingElementsAndPatterns(symbol.valueDeclaration).parent.kind === 280 /* CatchClause */;
        }
        function isSymbolOfDeclarationWithCollidingName(symbol) {
            if (symbol.flags & 418 /* BlockScoped */ && !ts.isSourceFile(symbol.valueDeclaration)) {
                var links = getSymbolLinks(symbol);
                if (links.isDeclarationWithCollidingName === undefined) {
                    var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration);
                    if (ts.isStatementWithLocals(container) || isSymbolOfDestructuredElementOfCatchBinding(symbol)) {
                        var nodeLinks_1 = getNodeLinks(symbol.valueDeclaration);
                        if (resolveName(container.parent, symbol.escapedName, 111551 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) {
                            // redeclaration - always should be renamed
                            links.isDeclarationWithCollidingName = true;
                        }
                        else if (nodeLinks_1.flags & 262144 /* CapturedBlockScopedBinding */) {
                            // binding is captured in the function
                            // should be renamed if:
                            // - binding is not top level - top level bindings never collide with anything
                            // AND
                            //   - binding is not declared in loop, should be renamed to avoid name reuse across siblings
                            //     let a, b
                            //     { let x = 1; a = () => x; }
                            //     { let x = 100; b = () => x; }
                            //     console.log(a()); // should print '1'
                            //     console.log(b()); // should print '100'
                            //     OR
                            //   - binding is declared inside loop but not in inside initializer of iteration statement or directly inside loop body
                            //     * variables from initializer are passed to rewritten loop body as parameters so they are not captured directly
                            //     * variables that are declared immediately in loop body will become top level variable after loop is rewritten and thus
                            //       they will not collide with anything
                            var isDeclaredInLoop = nodeLinks_1.flags & 524288 /* BlockScopedBindingInLoop */;
                            var inLoopInitializer = ts.isIterationStatement(container, /*lookInLabeledStatements*/ false);
                            var inLoopBodyBlock = container.kind === 223 /* Block */ && ts.isIterationStatement(container.parent, /*lookInLabeledStatements*/ false);
                            links.isDeclarationWithCollidingName = !ts.isBlockScopedContainerTopLevel(container) && (!isDeclaredInLoop || (!inLoopInitializer && !inLoopBodyBlock));
                        }
                        else {
                            links.isDeclarationWithCollidingName = false;
                        }
                    }
                }
                return links.isDeclarationWithCollidingName;
            }
            return false;
        }
        // When resolved as an expression identifier, if the given node references a nested block scoped entity with
        // a name that either hides an existing name or might hide it when compiled downlevel,
        // return the declaration of that entity. Otherwise, return undefined.
        function getReferencedDeclarationWithCollidingName(nodeIn) {
            if (!ts.isGeneratedIdentifier(nodeIn)) {
                var node = ts.getParseTreeNode(nodeIn, ts.isIdentifier);
                if (node) {
                    var symbol = getReferencedValueSymbol(node);
                    if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) {
                        return symbol.valueDeclaration;
                    }
                }
            }
            return undefined;
        }
        // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an
        // existing name or might hide a name when compiled downlevel
        function isDeclarationWithCollidingName(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isDeclaration);
            if (node) {
                var symbol = getSymbolOfNode(node);
                if (symbol) {
                    return isSymbolOfDeclarationWithCollidingName(symbol);
                }
            }
            return false;
        }
        function isValueAliasDeclaration(node) {
            switch (node.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol);
                case 255 /* ImportClause */:
                case 256 /* NamespaceImport */:
                case 258 /* ImportSpecifier */:
                case 263 /* ExportSpecifier */:
                    var symbol = getSymbolOfNode(node) || unknownSymbol;
                    return isAliasResolvedToValue(symbol) && !getTypeOnlyAliasDeclaration(symbol);
                case 260 /* ExportDeclaration */:
                    var exportClause = node.exportClause;
                    return !!exportClause && (ts.isNamespaceExport(exportClause) ||
                        ts.some(exportClause.elements, isValueAliasDeclaration));
                case 259 /* ExportAssignment */:
                    return node.expression && node.expression.kind === 75 /* Identifier */ ?
                        isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) :
                        true;
            }
            return false;
        }
        function isTopLevelValueImportEqualsWithEntityName(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isImportEqualsDeclaration);
            if (node === undefined || node.parent.kind !== 290 /* SourceFile */ || !ts.isInternalModuleImportEqualsDeclaration(node)) {
                // parent is not source file or it is not reference to internal module
                return false;
            }
            var isValue = isAliasResolvedToValue(getSymbolOfNode(node));
            return isValue && node.moduleReference && !ts.nodeIsMissing(node.moduleReference);
        }
        function isAliasResolvedToValue(symbol) {
            var target = resolveAlias(symbol);
            if (target === unknownSymbol) {
                return true;
            }
            // const enums and modules that contain only const enums are not considered values from the emit perspective
            // unless 'preserveConstEnums' option is set to true
            return !!(target.flags & 111551 /* Value */) &&
                (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target));
        }
        function isConstEnumOrConstEnumOnlyModule(s) {
            return isConstEnumSymbol(s) || !!s.constEnumOnlyModule;
        }
        function isReferencedAliasDeclaration(node, checkChildren) {
            if (isAliasSymbolDeclaration(node)) {
                var symbol = getSymbolOfNode(node);
                if (symbol && getSymbolLinks(symbol).referenced) {
                    return true;
                }
                var target = getSymbolLinks(symbol).target; // TODO: GH#18217
                if (target && ts.getModifierFlags(node) & 1 /* Export */ &&
                    target.flags & 111551 /* Value */ &&
                    (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target))) {
                    // An `export import ... =` of a value symbol is always considered referenced
                    return true;
                }
            }
            if (checkChildren) {
                return !!ts.forEachChild(node, function (node) { return isReferencedAliasDeclaration(node, checkChildren); });
            }
            return false;
        }
        function isImplementationOfOverload(node) {
            if (ts.nodeIsPresent(node.body)) {
                if (ts.isGetAccessor(node) || ts.isSetAccessor(node))
                    return false; // Get or set accessors can never be overload implementations, but can have up to 2 signatures
                var symbol = getSymbolOfNode(node);
                var signaturesOfSymbol = getSignaturesOfSymbol(symbol);
                // If this function body corresponds to function with multiple signature, it is implementation of overload
                // e.g.: function foo(a: string): string;
                //       function foo(a: number): number;
                //       function foo(a: any) { // This is implementation of the overloads
                //           return a;
                //       }
                return signaturesOfSymbol.length > 1 ||
                    // If there is single signature for the symbol, it is overload if that signature isn't coming from the node
                    // e.g.: function foo(a: string): string;
                    //       function foo(a: any) { // This is implementation of the overloads
                    //           return a;
                    //       }
                    (signaturesOfSymbol.length === 1 && signaturesOfSymbol[0].declaration !== node);
            }
            return false;
        }
        function isRequiredInitializedParameter(parameter) {
            return !!strictNullChecks &&
                !isOptionalParameter(parameter) &&
                !ts.isJSDocParameterTag(parameter) &&
                !!parameter.initializer &&
                !ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
        }
        function isOptionalUninitializedParameterProperty(parameter) {
            return strictNullChecks &&
                isOptionalParameter(parameter) &&
                !parameter.initializer &&
                ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */);
        }
        function isExpandoFunctionDeclaration(node) {
            var declaration = ts.getParseTreeNode(node, ts.isFunctionDeclaration);
            if (!declaration) {
                return false;
            }
            var symbol = getSymbolOfNode(declaration);
            if (!symbol || !(symbol.flags & 16 /* Function */)) {
                return false;
            }
            return !!ts.forEachEntry(getExportsOfSymbol(symbol), function (p) { return p.flags & 111551 /* Value */ && p.valueDeclaration && ts.isPropertyAccessExpression(p.valueDeclaration); });
        }
        function getPropertiesOfContainerFunction(node) {
            var declaration = ts.getParseTreeNode(node, ts.isFunctionDeclaration);
            if (!declaration) {
                return ts.emptyArray;
            }
            var symbol = getSymbolOfNode(declaration);
            return symbol && getPropertiesOfType(getTypeOfSymbol(symbol)) || ts.emptyArray;
        }
        function getNodeCheckFlags(node) {
            return getNodeLinks(node).flags || 0;
        }
        function getEnumMemberValue(node) {
            computeEnumMemberValues(node.parent);
            return getNodeLinks(node).enumMemberValue;
        }
        function canHaveConstantValue(node) {
            switch (node.kind) {
                case 284 /* EnumMember */:
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                    return true;
            }
            return false;
        }
        function getConstantValue(node) {
            if (node.kind === 284 /* EnumMember */) {
                return getEnumMemberValue(node);
            }
            var symbol = getNodeLinks(node).resolvedSymbol;
            if (symbol && (symbol.flags & 8 /* EnumMember */)) {
                // inline property\index accesses only for const enums
                var member = symbol.valueDeclaration;
                if (ts.isEnumConst(member.parent)) {
                    return getEnumMemberValue(member);
                }
            }
            return undefined;
        }
        function isFunctionType(type) {
            return !!(type.flags & 524288 /* Object */) && getSignaturesOfType(type, 0 /* Call */).length > 0;
        }
        function getTypeReferenceSerializationKind(typeNameIn, location) {
            // ensure both `typeName` and `location` are parse tree nodes.
            var typeName = ts.getParseTreeNode(typeNameIn, ts.isEntityName);
            if (!typeName)
                return ts.TypeReferenceSerializationKind.Unknown;
            if (location) {
                location = ts.getParseTreeNode(location);
                if (!location)
                    return ts.TypeReferenceSerializationKind.Unknown;
            }
            // Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
            var valueSymbol = resolveEntityName(typeName, 111551 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
            // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
            var typeSymbol = resolveEntityName(typeName, 788968 /* Type */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
            if (valueSymbol && valueSymbol === typeSymbol) {
                var globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false);
                if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) {
                    return ts.TypeReferenceSerializationKind.Promise;
                }
                var constructorType = getTypeOfSymbol(valueSymbol);
                if (constructorType && isConstructorType(constructorType)) {
                    return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
                }
            }
            // We might not be able to resolve type symbol so use unknown type in that case (eg error case)
            if (!typeSymbol) {
                return ts.TypeReferenceSerializationKind.Unknown;
            }
            var type = getDeclaredTypeOfSymbol(typeSymbol);
            if (type === errorType) {
                return ts.TypeReferenceSerializationKind.Unknown;
            }
            else if (type.flags & 3 /* AnyOrUnknown */) {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
            else if (isTypeAssignableToKind(type, 16384 /* Void */ | 98304 /* Nullable */ | 131072 /* Never */)) {
                return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType;
            }
            else if (isTypeAssignableToKind(type, 528 /* BooleanLike */)) {
                return ts.TypeReferenceSerializationKind.BooleanType;
            }
            else if (isTypeAssignableToKind(type, 296 /* NumberLike */)) {
                return ts.TypeReferenceSerializationKind.NumberLikeType;
            }
            else if (isTypeAssignableToKind(type, 2112 /* BigIntLike */)) {
                return ts.TypeReferenceSerializationKind.BigIntLikeType;
            }
            else if (isTypeAssignableToKind(type, 132 /* StringLike */)) {
                return ts.TypeReferenceSerializationKind.StringLikeType;
            }
            else if (isTupleType(type)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else if (isTypeAssignableToKind(type, 12288 /* ESSymbolLike */)) {
                return ts.TypeReferenceSerializationKind.ESSymbolType;
            }
            else if (isFunctionType(type)) {
                return ts.TypeReferenceSerializationKind.TypeWithCallSignature;
            }
            else if (isArrayType(type)) {
                return ts.TypeReferenceSerializationKind.ArrayLikeType;
            }
            else {
                return ts.TypeReferenceSerializationKind.ObjectType;
            }
        }
        function createTypeOfDeclaration(declarationIn, enclosingDeclaration, flags, tracker, addUndefined) {
            var declaration = ts.getParseTreeNode(declarationIn, ts.isVariableLikeOrAccessor);
            if (!declaration) {
                return ts.createToken(125 /* AnyKeyword */);
            }
            // Get type of the symbol if this is the valid symbol otherwise get type at location
            var symbol = getSymbolOfNode(declaration);
            var type = symbol && !(symbol.flags & (2048 /* TypeLiteral */ | 131072 /* Signature */))
                ? getWidenedLiteralType(getTypeOfSymbol(symbol))
                : errorType;
            if (type.flags & 8192 /* UniqueESSymbol */ &&
                type.symbol === symbol) {
                flags |= 1048576 /* AllowUniqueESSymbolType */;
            }
            if (addUndefined) {
                type = getOptionalType(type);
            }
            return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function createReturnTypeOfSignatureDeclaration(signatureDeclarationIn, enclosingDeclaration, flags, tracker) {
            var signatureDeclaration = ts.getParseTreeNode(signatureDeclarationIn, ts.isFunctionLike);
            if (!signatureDeclaration) {
                return ts.createToken(125 /* AnyKeyword */);
            }
            var signature = getSignatureFromDeclaration(signatureDeclaration);
            return nodeBuilder.typeToTypeNode(getReturnTypeOfSignature(signature), enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function createTypeOfExpression(exprIn, enclosingDeclaration, flags, tracker) {
            var expr = ts.getParseTreeNode(exprIn, ts.isExpression);
            if (!expr) {
                return ts.createToken(125 /* AnyKeyword */);
            }
            var type = getWidenedType(getRegularTypeOfExpression(expr));
            return nodeBuilder.typeToTypeNode(type, enclosingDeclaration, flags | 1024 /* MultilineObjectLiterals */, tracker);
        }
        function hasGlobalName(name) {
            return globals.has(ts.escapeLeadingUnderscores(name));
        }
        function getReferencedValueSymbol(reference, startInDeclarationContainer) {
            var resolvedSymbol = getNodeLinks(reference).resolvedSymbol;
            if (resolvedSymbol) {
                return resolvedSymbol;
            }
            var location = reference;
            if (startInDeclarationContainer) {
                // When resolving the name of a declaration as a value, we need to start resolution
                // at a point outside of the declaration.
                var parent = reference.parent;
                if (ts.isDeclaration(parent) && reference === parent.name) {
                    location = getDeclarationContainer(parent);
                }
            }
            return resolveName(location, reference.escapedText, 111551 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
        }
        function getReferencedValueDeclaration(referenceIn) {
            if (!ts.isGeneratedIdentifier(referenceIn)) {
                var reference = ts.getParseTreeNode(referenceIn, ts.isIdentifier);
                if (reference) {
                    var symbol = getReferencedValueSymbol(reference);
                    if (symbol) {
                        return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration;
                    }
                }
            }
            return undefined;
        }
        function isLiteralConstDeclaration(node) {
            if (ts.isDeclarationReadonly(node) || ts.isVariableDeclaration(node) && ts.isVarConst(node)) {
                return isFreshLiteralType(getTypeOfSymbol(getSymbolOfNode(node)));
            }
            return false;
        }
        function literalTypeToNode(type, enclosing, tracker) {
            var enumResult = type.flags & 1024 /* EnumLiteral */ ? nodeBuilder.symbolToExpression(type.symbol, 111551 /* Value */, enclosing, /*flags*/ undefined, tracker)
                : type === trueType ? ts.createTrue() : type === falseType && ts.createFalse();
            return enumResult || ts.createLiteral(type.value);
        }
        function createLiteralConstValue(node, tracker) {
            var type = getTypeOfSymbol(getSymbolOfNode(node));
            return literalTypeToNode(type, node, tracker);
        }
        function getJsxFactoryEntity(location) {
            return location ? (getJsxNamespace(location), (ts.getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity;
        }
        function createResolver() {
            // this variable and functions that use it are deliberately moved here from the outer scope
            // to avoid scope pollution
            var resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives();
            var fileToDirective;
            if (resolvedTypeReferenceDirectives) {
                // populate reverse mapping: file path -> type reference directive that was resolved to this file
                fileToDirective = ts.createMap();
                resolvedTypeReferenceDirectives.forEach(function (resolvedDirective, key) {
                    if (!resolvedDirective || !resolvedDirective.resolvedFileName) {
                        return;
                    }
                    var file = host.getSourceFile(resolvedDirective.resolvedFileName);
                    if (file) {
                        // Add the transitive closure of path references loaded by this file (as long as they are not)
                        // part of an existing type reference.
                        addReferencedFilesToTypeDirective(file, key);
                    }
                });
            }
            return {
                getReferencedExportContainer: getReferencedExportContainer,
                getReferencedImportDeclaration: getReferencedImportDeclaration,
                getReferencedDeclarationWithCollidingName: getReferencedDeclarationWithCollidingName,
                isDeclarationWithCollidingName: isDeclarationWithCollidingName,
                isValueAliasDeclaration: function (node) {
                    node = ts.getParseTreeNode(node);
                    // Synthesized nodes are always treated like values.
                    return node ? isValueAliasDeclaration(node) : true;
                },
                hasGlobalName: hasGlobalName,
                isReferencedAliasDeclaration: function (node, checkChildren) {
                    node = ts.getParseTreeNode(node);
                    // Synthesized nodes are always treated as referenced.
                    return node ? isReferencedAliasDeclaration(node, checkChildren) : true;
                },
                getNodeCheckFlags: function (node) {
                    node = ts.getParseTreeNode(node);
                    return node ? getNodeCheckFlags(node) : 0;
                },
                isTopLevelValueImportEqualsWithEntityName: isTopLevelValueImportEqualsWithEntityName,
                isDeclarationVisible: isDeclarationVisible,
                isImplementationOfOverload: isImplementationOfOverload,
                isRequiredInitializedParameter: isRequiredInitializedParameter,
                isOptionalUninitializedParameterProperty: isOptionalUninitializedParameterProperty,
                isExpandoFunctionDeclaration: isExpandoFunctionDeclaration,
                getPropertiesOfContainerFunction: getPropertiesOfContainerFunction,
                createTypeOfDeclaration: createTypeOfDeclaration,
                createReturnTypeOfSignatureDeclaration: createReturnTypeOfSignatureDeclaration,
                createTypeOfExpression: createTypeOfExpression,
                createLiteralConstValue: createLiteralConstValue,
                isSymbolAccessible: isSymbolAccessible,
                isEntityNameVisible: isEntityNameVisible,
                getConstantValue: function (nodeIn) {
                    var node = ts.getParseTreeNode(nodeIn, canHaveConstantValue);
                    return node ? getConstantValue(node) : undefined;
                },
                collectLinkedAliases: collectLinkedAliases,
                getReferencedValueDeclaration: getReferencedValueDeclaration,
                getTypeReferenceSerializationKind: getTypeReferenceSerializationKind,
                isOptionalParameter: isOptionalParameter,
                moduleExportsSomeValue: moduleExportsSomeValue,
                isArgumentsLocalBinding: isArgumentsLocalBinding,
                getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration,
                getTypeReferenceDirectivesForEntityName: getTypeReferenceDirectivesForEntityName,
                getTypeReferenceDirectivesForSymbol: getTypeReferenceDirectivesForSymbol,
                isLiteralConstDeclaration: isLiteralConstDeclaration,
                isLateBound: function (nodeIn) {
                    var node = ts.getParseTreeNode(nodeIn, ts.isDeclaration);
                    var symbol = node && getSymbolOfNode(node);
                    return !!(symbol && ts.getCheckFlags(symbol) & 4096 /* Late */);
                },
                getJsxFactoryEntity: getJsxFactoryEntity,
                getAllAccessorDeclarations: function (accessor) {
                    accessor = ts.getParseTreeNode(accessor, ts.isGetOrSetAccessorDeclaration); // TODO: GH#18217
                    var otherKind = accessor.kind === 164 /* SetAccessor */ ? 163 /* GetAccessor */ : 164 /* SetAccessor */;
                    var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(accessor), otherKind);
                    var firstAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? otherAccessor : accessor;
                    var secondAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? accessor : otherAccessor;
                    var setAccessor = accessor.kind === 164 /* SetAccessor */ ? accessor : otherAccessor;
                    var getAccessor = accessor.kind === 163 /* GetAccessor */ ? accessor : otherAccessor;
                    return {
                        firstAccessor: firstAccessor,
                        secondAccessor: secondAccessor,
                        setAccessor: setAccessor,
                        getAccessor: getAccessor
                    };
                },
                getSymbolOfExternalModuleSpecifier: function (moduleName) { return resolveExternalModuleNameWorker(moduleName, moduleName, /*moduleNotFoundError*/ undefined); },
                isBindingCapturedByNode: function (node, decl) {
                    var parseNode = ts.getParseTreeNode(node);
                    var parseDecl = ts.getParseTreeNode(decl);
                    return !!parseNode && !!parseDecl && (ts.isVariableDeclaration(parseDecl) || ts.isBindingElement(parseDecl)) && isBindingCapturedByNode(parseNode, parseDecl);
                },
                getDeclarationStatementsForSourceFile: function (node, flags, tracker, bundled) {
                    var n = ts.getParseTreeNode(node);
                    ts.Debug.assert(n && n.kind === 290 /* SourceFile */, "Non-sourcefile node passed into getDeclarationsForSourceFile");
                    var sym = getSymbolOfNode(node);
                    if (!sym) {
                        return !node.locals ? [] : nodeBuilder.symbolTableToDeclarationStatements(node.locals, node, flags, tracker, bundled);
                    }
                    return !sym.exports ? [] : nodeBuilder.symbolTableToDeclarationStatements(sym.exports, node, flags, tracker, bundled);
                },
                isImportRequiredByAugmentation: isImportRequiredByAugmentation,
            };
            function isImportRequiredByAugmentation(node) {
                var file = ts.getSourceFileOfNode(node);
                if (!file.symbol)
                    return false;
                var importTarget = getExternalModuleFileFromDeclaration(node);
                if (!importTarget)
                    return false;
                if (importTarget === file)
                    return false;
                var exports = getExportsOfModule(file.symbol);
                for (var _i = 0, _a = ts.arrayFrom(exports.values()); _i < _a.length; _i++) {
                    var s = _a[_i];
                    if (s.mergeId) {
                        var merged = getMergedSymbol(s);
                        for (var _b = 0, _c = merged.declarations; _b < _c.length; _b++) {
                            var d = _c[_b];
                            var declFile = ts.getSourceFileOfNode(d);
                            if (declFile === importTarget) {
                                return true;
                            }
                        }
                    }
                }
                return false;
            }
            function isInHeritageClause(node) {
                return node.parent && node.parent.kind === 216 /* ExpressionWithTypeArguments */ && node.parent.parent && node.parent.parent.kind === 279 /* HeritageClause */;
            }
            // defined here to avoid outer scope pollution
            function getTypeReferenceDirectivesForEntityName(node) {
                // program does not have any files with type reference directives - bail out
                if (!fileToDirective) {
                    return undefined;
                }
                // property access can only be used as values, or types when within an expression with type arguments inside a heritage clause
                // qualified names can only be used as types\namespaces
                // identifiers are treated as values only if they appear in type queries
                var meaning = 788968 /* Type */ | 1920 /* Namespace */;
                if ((node.kind === 75 /* Identifier */ && isInTypeQuery(node)) || (node.kind === 194 /* PropertyAccessExpression */ && !isInHeritageClause(node))) {
                    meaning = 111551 /* Value */ | 1048576 /* ExportValue */;
                }
                var symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true);
                return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined;
            }
            // defined here to avoid outer scope pollution
            function getTypeReferenceDirectivesForSymbol(symbol, meaning) {
                // program does not have any files with type reference directives - bail out
                if (!fileToDirective) {
                    return undefined;
                }
                if (!isSymbolFromTypeDeclarationFile(symbol)) {
                    return undefined;
                }
                // check what declarations in the symbol can contribute to the target meaning
                var typeReferenceDirectives;
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    // check meaning of the local symbol to see if declaration needs to be analyzed further
                    if (decl.symbol && decl.symbol.flags & meaning) {
                        var file = ts.getSourceFileOfNode(decl);
                        var typeReferenceDirective = fileToDirective.get(file.path);
                        if (typeReferenceDirective) {
                            (typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective);
                        }
                        else {
                            // found at least one entry that does not originate from type reference directive
                            return undefined;
                        }
                    }
                }
                return typeReferenceDirectives;
            }
            function isSymbolFromTypeDeclarationFile(symbol) {
                // bail out if symbol does not have associated declarations (i.e. this is transient symbol created for property in binding pattern)
                if (!symbol.declarations) {
                    return false;
                }
                // walk the parent chain for symbols to make sure that top level parent symbol is in the global scope
                // external modules cannot define or contribute to type declaration files
                var current = symbol;
                while (true) {
                    var parent = getParentOfSymbol(current);
                    if (parent) {
                        current = parent;
                    }
                    else {
                        break;
                    }
                }
                if (current.valueDeclaration && current.valueDeclaration.kind === 290 /* SourceFile */ && current.flags & 512 /* ValueModule */) {
                    return false;
                }
                // check that at least one declaration of top level symbol originates from type declaration file
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    var file = ts.getSourceFileOfNode(decl);
                    if (fileToDirective.has(file.path)) {
                        return true;
                    }
                }
                return false;
            }
            function addReferencedFilesToTypeDirective(file, key) {
                if (fileToDirective.has(file.path))
                    return;
                fileToDirective.set(file.path, key);
                for (var _i = 0, _a = file.referencedFiles; _i < _a.length; _i++) {
                    var fileName = _a[_i].fileName;
                    var resolvedFile = ts.resolveTripleslashReference(fileName, file.originalFileName);
                    var referencedFile = host.getSourceFile(resolvedFile);
                    if (referencedFile) {
                        addReferencedFilesToTypeDirective(referencedFile, key);
                    }
                }
            }
        }
        function getExternalModuleFileFromDeclaration(declaration) {
            var specifier = declaration.kind === 249 /* ModuleDeclaration */ ? ts.tryCast(declaration.name, ts.isStringLiteral) : ts.getExternalModuleName(declaration);
            var moduleSymbol = resolveExternalModuleNameWorker(specifier, specifier, /*moduleNotFoundError*/ undefined); // TODO: GH#18217
            if (!moduleSymbol) {
                return undefined;
            }
            return ts.getDeclarationOfKind(moduleSymbol, 290 /* SourceFile */);
        }
        function initializeTypeChecker() {
            // Bind all source files and propagate errors
            for (var _i = 0, _a = host.getSourceFiles(); _i < _a.length; _i++) {
                var file = _a[_i];
                ts.bindSourceFile(file, compilerOptions);
            }
            amalgamatedDuplicates = ts.createMap();
            // Initialize global symbol table
            var augmentations;
            for (var _b = 0, _c = host.getSourceFiles(); _b < _c.length; _b++) {
                var file = _c[_b];
                if (file.redirectInfo) {
                    continue;
                }
                if (!ts.isExternalOrCommonJsModule(file)) {
                    // It is an error for a non-external-module (i.e. script) to declare its own `globalThis`.
                    // We can't use `builtinGlobals` for this due to synthetic expando-namespace generation in JS files.
                    var fileGlobalThisSymbol = file.locals.get("globalThis");
                    if (fileGlobalThisSymbol) {
                        for (var _d = 0, _e = fileGlobalThisSymbol.declarations; _d < _e.length; _d++) {
                            var declaration = _e[_d];
                            diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, "globalThis"));
                        }
                    }
                    mergeSymbolTable(globals, file.locals);
                }
                if (file.jsGlobalAugmentations) {
                    mergeSymbolTable(globals, file.jsGlobalAugmentations);
                }
                if (file.patternAmbientModules && file.patternAmbientModules.length) {
                    patternAmbientModules = ts.concatenate(patternAmbientModules, file.patternAmbientModules);
                }
                if (file.moduleAugmentations.length) {
                    (augmentations || (augmentations = [])).push(file.moduleAugmentations);
                }
                if (file.symbol && file.symbol.globalExports) {
                    // Merge in UMD exports with first-in-wins semantics (see #9771)
                    var source = file.symbol.globalExports;
                    source.forEach(function (sourceSymbol, id) {
                        if (!globals.has(id)) {
                            globals.set(id, sourceSymbol);
                        }
                    });
                }
            }
            // We do global augmentations separately from module augmentations (and before creating global types) because they
            //  1. Affect global types. We won't have the correct global types until global augmentations are merged. Also,
            //  2. Module augmentation instantiation requires creating the type of a module, which, in turn, can require
            //       checking for an export or property on the module (if export=) which, in turn, can fall back to the
            //       apparent type of the module - either globalObjectType or globalFunctionType - which wouldn't exist if we
            //       did module augmentations prior to finalizing the global types.
            if (augmentations) {
                // merge _global_ module augmentations.
                // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
                for (var _f = 0, augmentations_1 = augmentations; _f < augmentations_1.length; _f++) {
                    var list = augmentations_1[_f];
                    for (var _g = 0, list_1 = list; _g < list_1.length; _g++) {
                        var augmentation = list_1[_g];
                        if (!ts.isGlobalScopeAugmentation(augmentation.parent))
                            continue;
                        mergeModuleAugmentation(augmentation);
                    }
                }
            }
            // Setup global builtins
            addToSymbolTable(globals, builtinGlobals, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0);
            getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
            getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments", /*arity*/ 0, /*reportErrors*/ true);
            getSymbolLinks(unknownSymbol).type = errorType;
            getSymbolLinks(globalThisSymbol).type = createObjectType(16 /* Anonymous */, globalThisSymbol);
            // Initialize special types
            globalArrayType = getGlobalType("Array", /*arity*/ 1, /*reportErrors*/ true);
            globalObjectType = getGlobalType("Object", /*arity*/ 0, /*reportErrors*/ true);
            globalFunctionType = getGlobalType("Function", /*arity*/ 0, /*reportErrors*/ true);
            globalCallableFunctionType = strictBindCallApply && getGlobalType("CallableFunction", /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
            globalNewableFunctionType = strictBindCallApply && getGlobalType("NewableFunction", /*arity*/ 0, /*reportErrors*/ true) || globalFunctionType;
            globalStringType = getGlobalType("String", /*arity*/ 0, /*reportErrors*/ true);
            globalNumberType = getGlobalType("Number", /*arity*/ 0, /*reportErrors*/ true);
            globalBooleanType = getGlobalType("Boolean", /*arity*/ 0, /*reportErrors*/ true);
            globalRegExpType = getGlobalType("RegExp", /*arity*/ 0, /*reportErrors*/ true);
            anyArrayType = createArrayType(anyType);
            autoArrayType = createArrayType(autoType);
            if (autoArrayType === emptyObjectType) {
                // autoArrayType is used as a marker, so even if global Array type is not defined, it needs to be a unique type
                autoArrayType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined);
            }
            globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1) || globalArrayType;
            anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType;
            globalThisType = getGlobalTypeOrUndefined("ThisType", /*arity*/ 1);
            if (augmentations) {
                // merge _nonglobal_ module augmentations.
                // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
                for (var _h = 0, augmentations_2 = augmentations; _h < augmentations_2.length; _h++) {
                    var list = augmentations_2[_h];
                    for (var _j = 0, list_2 = list; _j < list_2.length; _j++) {
                        var augmentation = list_2[_j];
                        if (ts.isGlobalScopeAugmentation(augmentation.parent))
                            continue;
                        mergeModuleAugmentation(augmentation);
                    }
                }
            }
            amalgamatedDuplicates.forEach(function (_a) {
                var firstFile = _a.firstFile, secondFile = _a.secondFile, conflictingSymbols = _a.conflictingSymbols;
                // If not many things conflict, issue individual errors
                if (conflictingSymbols.size < 8) {
                    conflictingSymbols.forEach(function (_a, symbolName) {
                        var isBlockScoped = _a.isBlockScoped, firstFileLocations = _a.firstFileLocations, secondFileLocations = _a.secondFileLocations;
                        var message = isBlockScoped ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0;
                        for (var _i = 0, firstFileLocations_1 = firstFileLocations; _i < firstFileLocations_1.length; _i++) {
                            var node = firstFileLocations_1[_i];
                            addDuplicateDeclarationError(node, message, symbolName, secondFileLocations);
                        }
                        for (var _b = 0, secondFileLocations_1 = secondFileLocations; _b < secondFileLocations_1.length; _b++) {
                            var node = secondFileLocations_1[_b];
                            addDuplicateDeclarationError(node, message, symbolName, firstFileLocations);
                        }
                    });
                }
                else {
                    // Otherwise issue top-level error since the files appear very identical in terms of what they contain
                    var list = ts.arrayFrom(conflictingSymbols.keys()).join(", ");
                    diagnostics.add(ts.addRelatedInfo(ts.createDiagnosticForNode(firstFile, ts.Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), ts.createDiagnosticForNode(secondFile, ts.Diagnostics.Conflicts_are_in_this_file)));
                    diagnostics.add(ts.addRelatedInfo(ts.createDiagnosticForNode(secondFile, ts.Diagnostics.Definitions_of_the_following_identifiers_conflict_with_those_in_another_file_Colon_0, list), ts.createDiagnosticForNode(firstFile, ts.Diagnostics.Conflicts_are_in_this_file)));
                }
            });
            amalgamatedDuplicates = undefined;
        }
        function checkExternalEmitHelpers(location, helpers) {
            if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
                var sourceFile = ts.getSourceFileOfNode(location);
                if (ts.isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & 8388608 /* Ambient */)) {
                    var helpersModule = resolveHelpersModule(sourceFile, location);
                    if (helpersModule !== unknownSymbol) {
                        var uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
                        for (var helper = 1 /* FirstEmitHelper */; helper <= 1048576 /* LastEmitHelper */; helper <<= 1) {
                            if (uncheckedHelpers & helper) {
                                var name = getHelperName(helper);
                                var symbol = getSymbol(helpersModule.exports, ts.escapeLeadingUnderscores(name), 111551 /* Value */);
                                if (!symbol) {
                                    error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, ts.externalHelpersModuleNameText, name);
                                }
                            }
                        }
                    }
                    requestedExternalEmitHelpers |= helpers;
                }
            }
        }
        function getHelperName(helper) {
            switch (helper) {
                case 1 /* Extends */: return "__extends";
                case 2 /* Assign */: return "__assign";
                case 4 /* Rest */: return "__rest";
                case 8 /* Decorate */: return "__decorate";
                case 16 /* Metadata */: return "__metadata";
                case 32 /* Param */: return "__param";
                case 64 /* Awaiter */: return "__awaiter";
                case 128 /* Generator */: return "__generator";
                case 256 /* Values */: return "__values";
                case 512 /* Read */: return "__read";
                case 1024 /* Spread */: return "__spread";
                case 2048 /* SpreadArrays */: return "__spreadArrays";
                case 4096 /* Await */: return "__await";
                case 8192 /* AsyncGenerator */: return "__asyncGenerator";
                case 16384 /* AsyncDelegator */: return "__asyncDelegator";
                case 32768 /* AsyncValues */: return "__asyncValues";
                case 65536 /* ExportStar */: return "__exportStar";
                case 131072 /* MakeTemplateObject */: return "__makeTemplateObject";
                case 262144 /* ClassPrivateFieldGet */: return "__classPrivateFieldGet";
                case 524288 /* ClassPrivateFieldSet */: return "__classPrivateFieldSet";
                case 1048576 /* CreateBinding */: return "__createBinding";
                default: return ts.Debug.fail("Unrecognized helper");
            }
        }
        function resolveHelpersModule(node, errorNode) {
            if (!externalHelpersModule) {
                externalHelpersModule = resolveExternalModule(node, ts.externalHelpersModuleNameText, ts.Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
            }
            return externalHelpersModule;
        }
        // GRAMMAR CHECKING
        function checkGrammarDecoratorsAndModifiers(node) {
            return checkGrammarDecorators(node) || checkGrammarModifiers(node);
        }
        function checkGrammarDecorators(node) {
            if (!node.decorators) {
                return false;
            }
            if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) {
                if (node.kind === 161 /* MethodDeclaration */ && !ts.nodeIsPresent(node.body)) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload);
                }
                else {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_are_not_valid_here);
                }
            }
            else if (node.kind === 163 /* GetAccessor */ || node.kind === 164 /* SetAccessor */) {
                var accessors = ts.getAllAccessorDeclarations(node.parent.members, node);
                if (accessors.firstAccessor.decorators && node === accessors.secondAccessor) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name);
                }
            }
            return false;
        }
        function checkGrammarModifiers(node) {
            var quickResult = reportObviousModifierErrors(node);
            if (quickResult !== undefined) {
                return quickResult;
            }
            var lastStatic, lastDeclare, lastAsync, lastReadonly;
            var flags = 0 /* None */;
            for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) {
                var modifier = _a[_i];
                if (modifier.kind !== 138 /* ReadonlyKeyword */) {
                    if (node.kind === 158 /* PropertySignature */ || node.kind === 160 /* MethodSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_member, ts.tokenToString(modifier.kind));
                    }
                    if (node.kind === 167 /* IndexSignature */) {
                        return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_an_index_signature, ts.tokenToString(modifier.kind));
                    }
                }
                switch (modifier.kind) {
                    case 81 /* ConstKeyword */:
                        if (node.kind !== 248 /* EnumDeclaration */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.A_class_member_cannot_have_the_0_keyword, ts.tokenToString(81 /* ConstKeyword */));
                        }
                        break;
                    case 119 /* PublicKeyword */:
                    case 118 /* ProtectedKeyword */:
                    case 117 /* PrivateKeyword */:
                        var text = visibilityToString(ts.modifierToFlag(modifier.kind));
                        if (flags & 28 /* AccessibilityModifier */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.Accessibility_modifier_already_seen);
                        }
                        else if (flags & 32 /* Static */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
                        }
                        else if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
                        }
                        else if (node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 290 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text);
                        }
                        else if (flags & 128 /* Abstract */) {
                            if (modifier.kind === 117 /* PrivateKeyword */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract");
                            }
                            else {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract");
                            }
                        }
                        else if (ts.isPrivateIdentifierPropertyDeclaration(node)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.An_accessibility_modifier_cannot_be_used_with_a_private_identifier);
                        }
                        flags |= ts.modifierToFlag(modifier.kind);
                        break;
                    case 120 /* StaticKeyword */:
                        if (flags & 32 /* Static */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "static");
                        }
                        else if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
                        }
                        else if (node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 290 /* SourceFile */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static");
                        }
                        else if (node.kind === 156 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static");
                        }
                        else if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
                        }
                        else if (ts.isPrivateIdentifierPropertyDeclaration(node)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "static");
                        }
                        flags |= 32 /* Static */;
                        lastStatic = modifier;
                        break;
                    case 138 /* ReadonlyKeyword */:
                        if (flags & 64 /* Readonly */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "readonly");
                        }
                        else if (node.kind !== 159 /* PropertyDeclaration */ && node.kind !== 158 /* PropertySignature */ && node.kind !== 167 /* IndexSignature */ && node.kind !== 156 /* Parameter */) {
                            // If node.kind === SyntaxKind.Parameter, checkParameter report an error if it's not a parameter property.
                            return grammarErrorOnNode(modifier, ts.Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature);
                        }
                        flags |= 64 /* Readonly */;
                        lastReadonly = modifier;
                        break;
                    case 89 /* ExportKeyword */:
                        if (flags & 1 /* Export */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "export");
                        }
                        else if (flags & 2 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
                        }
                        else if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
                        }
                        else if (ts.isClassLike(node.parent)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
                        }
                        else if (node.kind === 156 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export");
                        }
                        flags |= 1 /* Export */;
                        break;
                    case 84 /* DefaultKeyword */:
                        var container = node.parent.kind === 290 /* SourceFile */ ? node.parent : node.parent.parent;
                        if (container.kind === 249 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module);
                        }
                        flags |= 512 /* Default */;
                        break;
                    case 130 /* DeclareKeyword */:
                        if (flags & 2 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "declare");
                        }
                        else if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
                        }
                        else if (ts.isClassLike(node.parent) && !ts.isPropertyDeclaration(node)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
                        }
                        else if (node.kind === 156 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare");
                        }
                        else if ((node.parent.flags & 8388608 /* Ambient */) && node.parent.kind === 250 /* ModuleBlock */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context);
                        }
                        else if (ts.isPrivateIdentifierPropertyDeclaration(node)) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "declare");
                        }
                        flags |= 2 /* Ambient */;
                        lastDeclare = modifier;
                        break;
                    case 122 /* AbstractKeyword */:
                        if (flags & 128 /* Abstract */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "abstract");
                        }
                        if (node.kind !== 245 /* ClassDeclaration */) {
                            if (node.kind !== 161 /* MethodDeclaration */ &&
                                node.kind !== 159 /* PropertyDeclaration */ &&
                                node.kind !== 163 /* GetAccessor */ &&
                                node.kind !== 164 /* SetAccessor */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration);
                            }
                            if (!(node.parent.kind === 245 /* ClassDeclaration */ && ts.hasModifier(node.parent, 128 /* Abstract */))) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class);
                            }
                            if (flags & 32 /* Static */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract");
                            }
                            if (flags & 8 /* Private */) {
                                return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract");
                            }
                        }
                        if (ts.isNamedDeclaration(node) && node.name.kind === 76 /* PrivateIdentifier */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_a_private_identifier, "abstract");
                        }
                        flags |= 128 /* Abstract */;
                        break;
                    case 126 /* AsyncKeyword */:
                        if (flags & 256 /* Async */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "async");
                        }
                        else if (flags & 2 /* Ambient */ || node.parent.flags & 8388608 /* Ambient */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
                        }
                        else if (node.kind === 156 /* Parameter */) {
                            return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
                        }
                        flags |= 256 /* Async */;
                        lastAsync = modifier;
                        break;
                }
            }
            if (node.kind === 162 /* Constructor */) {
                if (flags & 32 /* Static */) {
                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "static");
                }
                if (flags & 128 /* Abstract */) {
                    return grammarErrorOnNode(lastStatic, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "abstract"); // TODO: GH#18217
                }
                else if (flags & 256 /* Async */) {
                    return grammarErrorOnNode(lastAsync, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
                }
                else if (flags & 64 /* Readonly */) {
                    return grammarErrorOnNode(lastReadonly, ts.Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "readonly");
                }
                return false;
            }
            else if ((node.kind === 254 /* ImportDeclaration */ || node.kind === 253 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) {
                return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
            }
            else if (node.kind === 156 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && ts.isBindingPattern(node.name)) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_may_not_be_declared_using_a_binding_pattern);
            }
            else if (node.kind === 156 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && node.dotDotDotToken) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter);
            }
            if (flags & 256 /* Async */) {
                return checkGrammarAsyncModifier(node, lastAsync);
            }
            return false;
        }
        /**
         * true | false: Early return this value from checkGrammarModifiers.
         * undefined: Need to do full checking on the modifiers.
         */
        function reportObviousModifierErrors(node) {
            return !node.modifiers
                ? false
                : shouldReportBadModifier(node)
                    ? grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here)
                    : undefined;
        }
        function shouldReportBadModifier(node) {
            switch (node.kind) {
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 162 /* Constructor */:
                case 159 /* PropertyDeclaration */:
                case 158 /* PropertySignature */:
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                case 167 /* IndexSignature */:
                case 249 /* ModuleDeclaration */:
                case 254 /* ImportDeclaration */:
                case 253 /* ImportEqualsDeclaration */:
                case 260 /* ExportDeclaration */:
                case 259 /* ExportAssignment */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                case 156 /* Parameter */:
                    return false;
                default:
                    if (node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 290 /* SourceFile */) {
                        return false;
                    }
                    switch (node.kind) {
                        case 244 /* FunctionDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 126 /* AsyncKeyword */);
                        case 245 /* ClassDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 122 /* AbstractKeyword */);
                        case 246 /* InterfaceDeclaration */:
                        case 225 /* VariableStatement */:
                        case 247 /* TypeAliasDeclaration */:
                            return true;
                        case 248 /* EnumDeclaration */:
                            return nodeHasAnyModifiersExcept(node, 81 /* ConstKeyword */);
                        default:
                            ts.Debug.fail();
                            return false;
                    }
            }
        }
        function nodeHasAnyModifiersExcept(node, allowedModifier) {
            return node.modifiers.length > 1 || node.modifiers[0].kind !== allowedModifier;
        }
        function checkGrammarAsyncModifier(node, asyncModifier) {
            switch (node.kind) {
                case 161 /* MethodDeclaration */:
                case 244 /* FunctionDeclaration */:
                case 201 /* FunctionExpression */:
                case 202 /* ArrowFunction */:
                    return false;
            }
            return grammarErrorOnNode(asyncModifier, ts.Diagnostics._0_modifier_cannot_be_used_here, "async");
        }
        function checkGrammarForDisallowedTrailingComma(list, diag) {
            if (diag === void 0) { diag = ts.Diagnostics.Trailing_comma_not_allowed; }
            if (list && list.hasTrailingComma) {
                return grammarErrorAtPos(list[0], list.end - ",".length, ",".length, diag);
            }
            return false;
        }
        function checkGrammarTypeParameterList(typeParameters, file) {
            if (typeParameters && typeParameters.length === 0) {
                var start = typeParameters.pos - "<".length;
                var end = ts.skipTrivia(file.text, typeParameters.end) + ">".length;
                return grammarErrorAtPos(file, start, end - start, ts.Diagnostics.Type_parameter_list_cannot_be_empty);
            }
            return false;
        }
        function checkGrammarParameterList(parameters) {
            var seenOptionalParameter = false;
            var parameterCount = parameters.length;
            for (var i = 0; i < parameterCount; i++) {
                var parameter = parameters[i];
                if (parameter.dotDotDotToken) {
                    if (i !== (parameterCount - 1)) {
                        return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
                    }
                    if (!(parameter.flags & 8388608 /* Ambient */)) { // Allow `...foo,` in ambient declarations; see GH#23070
                        checkGrammarForDisallowedTrailingComma(parameters, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                    }
                    if (parameter.questionToken) {
                        return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_rest_parameter_cannot_be_optional);
                    }
                    if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer);
                    }
                }
                else if (parameter.questionToken) {
                    seenOptionalParameter = true;
                    if (parameter.initializer) {
                        return grammarErrorOnNode(parameter.name, ts.Diagnostics.Parameter_cannot_have_question_mark_and_initializer);
                    }
                }
                else if (seenOptionalParameter && !parameter.initializer) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter);
                }
            }
        }
        function getNonSimpleParameters(parameters) {
            return ts.filter(parameters, function (parameter) { return !!parameter.initializer || ts.isBindingPattern(parameter.name) || ts.isRestParameter(parameter); });
        }
        function checkGrammarForUseStrictSimpleParameterList(node) {
            if (languageVersion >= 3 /* ES2016 */) {
                var useStrictDirective_1 = node.body && ts.isBlock(node.body) && ts.findUseStrictPrologue(node.body.statements);
                if (useStrictDirective_1) {
                    var nonSimpleParameters = getNonSimpleParameters(node.parameters);
                    if (ts.length(nonSimpleParameters)) {
                        ts.forEach(nonSimpleParameters, function (parameter) {
                            ts.addRelatedInfo(error(parameter, ts.Diagnostics.This_parameter_is_not_allowed_with_use_strict_directive), ts.createDiagnosticForNode(useStrictDirective_1, ts.Diagnostics.use_strict_directive_used_here));
                        });
                        var diagnostics_1 = nonSimpleParameters.map(function (parameter, index) { return (index === 0 ? ts.createDiagnosticForNode(parameter, ts.Diagnostics.Non_simple_parameter_declared_here) : ts.createDiagnosticForNode(parameter, ts.Diagnostics.and_here)); });
                        ts.addRelatedInfo.apply(void 0, __spreadArrays([error(useStrictDirective_1, ts.Diagnostics.use_strict_directive_cannot_be_used_with_non_simple_parameter_list)], diagnostics_1));
                        return true;
                    }
                }
            }
            return false;
        }
        function checkGrammarFunctionLikeDeclaration(node) {
            // Prevent cascading error by short-circuit
            var file = ts.getSourceFileOfNode(node);
            return checkGrammarDecoratorsAndModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) ||
                checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file) ||
                (ts.isFunctionLikeDeclaration(node) && checkGrammarForUseStrictSimpleParameterList(node));
        }
        function checkGrammarClassLikeDeclaration(node) {
            var file = ts.getSourceFileOfNode(node);
            return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file);
        }
        function checkGrammarArrowFunction(node, file) {
            if (!ts.isArrowFunction(node)) {
                return false;
            }
            var equalsGreaterThanToken = node.equalsGreaterThanToken;
            var startLine = ts.getLineAndCharacterOfPosition(file, equalsGreaterThanToken.pos).line;
            var endLine = ts.getLineAndCharacterOfPosition(file, equalsGreaterThanToken.end).line;
            return startLine !== endLine && grammarErrorOnNode(equalsGreaterThanToken, ts.Diagnostics.Line_terminator_not_permitted_before_arrow);
        }
        function checkGrammarIndexSignatureParameters(node) {
            var parameter = node.parameters[0];
            if (node.parameters.length !== 1) {
                if (parameter) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                }
                else {
                    return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter);
                }
            }
            checkGrammarForDisallowedTrailingComma(node.parameters, ts.Diagnostics.An_index_signature_cannot_have_a_trailing_comma);
            if (parameter.dotDotDotToken) {
                return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter);
            }
            if (ts.hasModifiers(parameter)) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier);
            }
            if (parameter.questionToken) {
                return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark);
            }
            if (parameter.initializer) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_initializer);
            }
            if (!parameter.type) {
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_must_have_a_type_annotation);
            }
            if (parameter.type.kind !== 143 /* StringKeyword */ && parameter.type.kind !== 140 /* NumberKeyword */) {
                var type = getTypeFromTypeNode(parameter.type);
                if (type.flags & 4 /* String */ || type.flags & 8 /* Number */) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, ts.getTextOfNode(parameter.name), typeToString(type), typeToString(node.type ? getTypeFromTypeNode(node.type) : anyType));
                }
                if (type.flags & 1048576 /* Union */ && allTypesAssignableToKind(type, 384 /* StringOrNumberLiteral */, /*strict*/ true)) {
                    return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead);
                }
                return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_must_be_either_string_or_number);
            }
            if (!node.type) {
                return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_a_type_annotation);
            }
            return false;
        }
        function checkGrammarIndexSignature(node) {
            // Prevent cascading error by short-circuit
            return checkGrammarDecoratorsAndModifiers(node) || checkGrammarIndexSignatureParameters(node);
        }
        function checkGrammarForAtLeastOneTypeArgument(node, typeArguments) {
            if (typeArguments && typeArguments.length === 0) {
                var sourceFile = ts.getSourceFileOfNode(node);
                var start = typeArguments.pos - "<".length;
                var end = ts.skipTrivia(sourceFile.text, typeArguments.end) + ">".length;
                return grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty);
            }
            return false;
        }
        function checkGrammarTypeArguments(node, typeArguments) {
            return checkGrammarForDisallowedTrailingComma(typeArguments) ||
                checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
        }
        function checkGrammarTaggedTemplateChain(node) {
            if (node.questionDotToken || node.flags & 32 /* OptionalChain */) {
                return grammarErrorOnNode(node.template, ts.Diagnostics.Tagged_template_expressions_are_not_permitted_in_an_optional_chain);
            }
            return false;
        }
        function checkGrammarForOmittedArgument(args) {
            if (args) {
                for (var _i = 0, args_4 = args; _i < args_4.length; _i++) {
                    var arg = args_4[_i];
                    if (arg.kind === 215 /* OmittedExpression */) {
                        return grammarErrorAtPos(arg, arg.pos, 0, ts.Diagnostics.Argument_expression_expected);
                    }
                }
            }
            return false;
        }
        function checkGrammarArguments(args) {
            return checkGrammarForOmittedArgument(args);
        }
        function checkGrammarHeritageClause(node) {
            var types = node.types;
            if (checkGrammarForDisallowedTrailingComma(types)) {
                return true;
            }
            if (types && types.length === 0) {
                var listType = ts.tokenToString(node.token);
                return grammarErrorAtPos(node, types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType);
            }
            return ts.some(types, checkGrammarExpressionWithTypeArguments);
        }
        function checkGrammarExpressionWithTypeArguments(node) {
            return checkGrammarTypeArguments(node, node.typeArguments);
        }
        function checkGrammarClassDeclarationHeritageClauses(node) {
            var seenExtendsClause = false;
            var seenImplementsClause = false;
            if (!checkGrammarDecoratorsAndModifiers(node) && node.heritageClauses) {
                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
                    var heritageClause = _a[_i];
                    if (heritageClause.token === 90 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        if (seenImplementsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_must_precede_implements_clause);
                        }
                        if (heritageClause.types.length > 1) {
                            return grammarErrorOnFirstToken(heritageClause.types[1], ts.Diagnostics.Classes_can_only_extend_a_single_class);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 113 /* ImplementsKeyword */);
                        if (seenImplementsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.implements_clause_already_seen);
                        }
                        seenImplementsClause = true;
                    }
                    // Grammar checking heritageClause inside class declaration
                    checkGrammarHeritageClause(heritageClause);
                }
            }
        }
        function checkGrammarInterfaceDeclaration(node) {
            var seenExtendsClause = false;
            if (node.heritageClauses) {
                for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) {
                    var heritageClause = _a[_i];
                    if (heritageClause.token === 90 /* ExtendsKeyword */) {
                        if (seenExtendsClause) {
                            return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen);
                        }
                        seenExtendsClause = true;
                    }
                    else {
                        ts.Debug.assert(heritageClause.token === 113 /* ImplementsKeyword */);
                        return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.Interface_declaration_cannot_have_implements_clause);
                    }
                    // Grammar checking heritageClause inside class declaration
                    checkGrammarHeritageClause(heritageClause);
                }
            }
            return false;
        }
        function checkGrammarComputedPropertyName(node) {
            // If node is not a computedPropertyName, just skip the grammar checking
            if (node.kind !== 154 /* ComputedPropertyName */) {
                return false;
            }
            var computedPropertyName = node;
            if (computedPropertyName.expression.kind === 209 /* BinaryExpression */ && computedPropertyName.expression.operatorToken.kind === 27 /* CommaToken */) {
                return grammarErrorOnNode(computedPropertyName.expression, ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
            }
            return false;
        }
        function checkGrammarForGenerator(node) {
            if (node.asteriskToken) {
                ts.Debug.assert(node.kind === 244 /* FunctionDeclaration */ ||
                    node.kind === 201 /* FunctionExpression */ ||
                    node.kind === 161 /* MethodDeclaration */);
                if (node.flags & 8388608 /* Ambient */) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context);
                }
                if (!node.body) {
                    return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator);
                }
            }
        }
        function checkGrammarForInvalidQuestionMark(questionToken, message) {
            return !!questionToken && grammarErrorOnNode(questionToken, message);
        }
        function checkGrammarForInvalidExclamationToken(exclamationToken, message) {
            return !!exclamationToken && grammarErrorOnNode(exclamationToken, message);
        }
        function checkGrammarObjectLiteralExpression(node, inDestructuring) {
            var seen = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                var prop = _a[_i];
                if (prop.kind === 283 /* SpreadAssignment */) {
                    if (inDestructuring) {
                        // a rest property cannot be destructured any further
                        var expression = ts.skipParentheses(prop.expression);
                        if (ts.isArrayLiteralExpression(expression) || ts.isObjectLiteralExpression(expression)) {
                            return grammarErrorOnNode(prop.expression, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
                        }
                    }
                    continue;
                }
                var name = prop.name;
                if (name.kind === 154 /* ComputedPropertyName */) {
                    // If the name is not a ComputedPropertyName, the grammar checking will skip it
                    checkGrammarComputedPropertyName(name);
                }
                if (prop.kind === 282 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) {
                    // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern
                    // outside of destructuring it is a syntax error
                    return grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
                }
                if (name.kind === 76 /* PrivateIdentifier */) {
                    return grammarErrorOnNode(name, ts.Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies);
                }
                // Modifiers are never allowed on properties except for 'async' on a method declaration
                if (prop.modifiers) {
                    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
                    for (var _b = 0, _c = prop.modifiers; _b < _c.length; _b++) { // TODO: GH#19955
                        var mod = _c[_b];
                        if (mod.kind !== 126 /* AsyncKeyword */ || prop.kind !== 161 /* MethodDeclaration */) {
                            grammarErrorOnNode(mod, ts.Diagnostics._0_modifier_cannot_be_used_here, ts.getTextOfNode(mod));
                        }
                    }
                }
                // ECMA-262 11.1.5 Object Initializer
                // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
                // a.This production is contained in strict code and IsDataDescriptor(previous) is true and
                // IsDataDescriptor(propId.descriptor) is true.
                //    b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true.
                //    c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true.
                //    d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true
                // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields
                var currentKind = void 0;
                switch (prop.kind) {
                    case 282 /* ShorthandPropertyAssignment */:
                        checkGrammarForInvalidExclamationToken(prop.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
                    // falls through
                    case 281 /* PropertyAssignment */:
                        // Grammar checking for computedPropertyName and shorthandPropertyAssignment
                        checkGrammarForInvalidQuestionMark(prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional);
                        if (name.kind === 8 /* NumericLiteral */) {
                            checkGrammarNumericLiteral(name);
                        }
                        currentKind = 4 /* PropertyAssignment */;
                        break;
                    case 161 /* MethodDeclaration */:
                        currentKind = 8 /* Method */;
                        break;
                    case 163 /* GetAccessor */:
                        currentKind = 1 /* GetAccessor */;
                        break;
                    case 164 /* SetAccessor */:
                        currentKind = 2 /* SetAccessor */;
                        break;
                    default:
                        throw ts.Debug.assertNever(prop, "Unexpected syntax kind:" + prop.kind);
                }
                if (!inDestructuring) {
                    var effectiveName = ts.getPropertyNameForPropertyNameNode(name);
                    if (effectiveName === undefined) {
                        continue;
                    }
                    var existingKind = seen.get(effectiveName);
                    if (!existingKind) {
                        seen.set(effectiveName, currentKind);
                    }
                    else {
                        if ((currentKind & 12 /* PropertyAssignmentOrMethod */) && (existingKind & 12 /* PropertyAssignmentOrMethod */)) {
                            grammarErrorOnNode(name, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name));
                        }
                        else if ((currentKind & 3 /* GetOrSetAccessor */) && (existingKind & 3 /* GetOrSetAccessor */)) {
                            if (existingKind !== 3 /* GetOrSetAccessor */ && currentKind !== existingKind) {
                                seen.set(effectiveName, currentKind | existingKind);
                            }
                            else {
                                return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
                            }
                        }
                        else {
                            return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
                        }
                    }
                }
            }
        }
        function checkGrammarJsxElement(node) {
            checkGrammarTypeArguments(node, node.typeArguments);
            var seen = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.attributes.properties; _i < _a.length; _i++) {
                var attr = _a[_i];
                if (attr.kind === 275 /* JsxSpreadAttribute */) {
                    continue;
                }
                var name = attr.name, initializer = attr.initializer;
                if (!seen.get(name.escapedText)) {
                    seen.set(name.escapedText, true);
                }
                else {
                    return grammarErrorOnNode(name, ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name);
                }
                if (initializer && initializer.kind === 276 /* JsxExpression */ && !initializer.expression) {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression);
                }
            }
        }
        function checkGrammarJsxExpression(node) {
            if (node.expression && ts.isCommaSequence(node.expression)) {
                return grammarErrorOnNode(node.expression, ts.Diagnostics.JSX_expressions_may_not_use_the_comma_operator_Did_you_mean_to_write_an_array);
            }
        }
        function checkGrammarForInOrForOfStatement(forInOrOfStatement) {
            if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) {
                return true;
            }
            if (forInOrOfStatement.kind === 232 /* ForOfStatement */ && forInOrOfStatement.awaitModifier) {
                if ((forInOrOfStatement.flags & 32768 /* AwaitContext */) === 0 /* None */) {
                    // use of 'for-await-of' in non-async function
                    var sourceFile = ts.getSourceFileOfNode(forInOrOfStatement);
                    if (!hasParseDiagnostics(sourceFile)) {
                        var diagnostic = ts.createDiagnosticForNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator);
                        var func = ts.getContainingFunction(forInOrOfStatement);
                        if (func && func.kind !== 162 /* Constructor */) {
                            ts.Debug.assert((ts.getFunctionFlags(func) & 2 /* Async */) === 0, "Enclosing function should never be an async function.");
                            var relatedInfo = ts.createDiagnosticForNode(func, ts.Diagnostics.Did_you_mean_to_mark_this_function_as_async);
                            ts.addRelatedInfo(diagnostic, relatedInfo);
                        }
                        diagnostics.add(diagnostic);
                        return true;
                    }
                    return false;
                }
            }
            if (forInOrOfStatement.initializer.kind === 243 /* VariableDeclarationList */) {
                var variableList = forInOrOfStatement.initializer;
                if (!checkGrammarVariableDeclarationList(variableList)) {
                    var declarations = variableList.declarations;
                    // declarations.length can be zero if there is an error in variable declaration in for-of or for-in
                    // See http://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements for details
                    // For example:
                    //      var let = 10;
                    //      for (let of [1,2,3]) {} // this is invalid ES6 syntax
                    //      for (let in [1,2,3]) {} // this is invalid ES6 syntax
                    // We will then want to skip on grammar checking on variableList declaration
                    if (!declarations.length) {
                        return false;
                    }
                    if (declarations.length > 1) {
                        var diagnostic = forInOrOfStatement.kind === 231 /* ForInStatement */
                            ? ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement
                            : ts.Diagnostics.Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement;
                        return grammarErrorOnFirstToken(variableList.declarations[1], diagnostic);
                    }
                    var firstDeclaration = declarations[0];
                    if (firstDeclaration.initializer) {
                        var diagnostic = forInOrOfStatement.kind === 231 /* ForInStatement */
                            ? ts.Diagnostics.The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer
                            : ts.Diagnostics.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer;
                        return grammarErrorOnNode(firstDeclaration.name, diagnostic);
                    }
                    if (firstDeclaration.type) {
                        var diagnostic = forInOrOfStatement.kind === 231 /* ForInStatement */
                            ? ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation
                            : ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation;
                        return grammarErrorOnNode(firstDeclaration, diagnostic);
                    }
                }
            }
            return false;
        }
        function checkGrammarAccessor(accessor) {
            if (!(accessor.flags & 8388608 /* Ambient */)) {
                if (languageVersion < 1 /* ES5 */) {
                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher);
                }
                if (accessor.body === undefined && !ts.hasModifier(accessor, 128 /* Abstract */)) {
                    return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
                }
            }
            if (accessor.body && ts.hasModifier(accessor, 128 /* Abstract */)) {
                return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation);
            }
            if (accessor.typeParameters) {
                return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_have_type_parameters);
            }
            if (!doesAccessorHaveCorrectParameterCount(accessor)) {
                return grammarErrorOnNode(accessor.name, accessor.kind === 163 /* GetAccessor */ ?
                    ts.Diagnostics.A_get_accessor_cannot_have_parameters :
                    ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter);
            }
            if (accessor.kind === 164 /* SetAccessor */) {
                if (accessor.type) {
                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_cannot_have_a_return_type_annotation);
                }
                var parameter = ts.Debug.checkDefined(ts.getSetAccessorValueParameter(accessor), "Return value does not match parameter count assertion.");
                if (parameter.dotDotDotToken) {
                    return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_set_accessor_cannot_have_rest_parameter);
                }
                if (parameter.questionToken) {
                    return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_set_accessor_cannot_have_an_optional_parameter);
                }
                if (parameter.initializer) {
                    return grammarErrorOnNode(accessor.name, ts.Diagnostics.A_set_accessor_parameter_cannot_have_an_initializer);
                }
            }
            return false;
        }
        /** Does the accessor have the right number of parameters?
         * A get accessor has no parameters or a single `this` parameter.
         * A set accessor has one parameter or a `this` parameter and one more parameter.
         */
        function doesAccessorHaveCorrectParameterCount(accessor) {
            return getAccessorThisParameter(accessor) || accessor.parameters.length === (accessor.kind === 163 /* GetAccessor */ ? 0 : 1);
        }
        function getAccessorThisParameter(accessor) {
            if (accessor.parameters.length === (accessor.kind === 163 /* GetAccessor */ ? 1 : 2)) {
                return ts.getThisParameter(accessor);
            }
        }
        function checkGrammarTypeOperatorNode(node) {
            if (node.operator === 147 /* UniqueKeyword */) {
                if (node.type.kind !== 144 /* SymbolKeyword */) {
                    return grammarErrorOnNode(node.type, ts.Diagnostics._0_expected, ts.tokenToString(144 /* SymbolKeyword */));
                }
                var parent = ts.walkUpParenthesizedTypes(node.parent);
                switch (parent.kind) {
                    case 242 /* VariableDeclaration */:
                        var decl = parent;
                        if (decl.name.kind !== 75 /* Identifier */) {
                            return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name);
                        }
                        if (!ts.isVariableDeclarationInVariableStatement(decl)) {
                            return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement);
                        }
                        if (!(decl.parent.flags & 2 /* Const */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const);
                        }
                        break;
                    case 159 /* PropertyDeclaration */:
                        if (!ts.hasModifier(parent, 32 /* Static */) ||
                            !ts.hasModifier(parent, 64 /* Readonly */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly);
                        }
                        break;
                    case 158 /* PropertySignature */:
                        if (!ts.hasModifier(parent, 64 /* Readonly */)) {
                            return grammarErrorOnNode(parent.name, ts.Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly);
                        }
                        break;
                    default:
                        return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_not_allowed_here);
                }
            }
            else if (node.operator === 138 /* ReadonlyKeyword */) {
                if (node.type.kind !== 174 /* ArrayType */ && node.type.kind !== 175 /* TupleType */) {
                    return grammarErrorOnFirstToken(node, ts.Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_literal_types, ts.tokenToString(144 /* SymbolKeyword */));
                }
            }
        }
        function checkGrammarForInvalidDynamicName(node, message) {
            if (isNonBindableDynamicName(node)) {
                return grammarErrorOnNode(node, message);
            }
        }
        function checkGrammarMethod(node) {
            if (checkGrammarFunctionLikeDeclaration(node)) {
                return true;
            }
            if (node.kind === 161 /* MethodDeclaration */) {
                if (node.parent.kind === 193 /* ObjectLiteralExpression */) {
                    // We only disallow modifier on a method declaration if it is a property of object-literal-expression
                    if (node.modifiers && !(node.modifiers.length === 1 && ts.first(node.modifiers).kind === 126 /* AsyncKeyword */)) {
                        return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here);
                    }
                    else if (checkGrammarForInvalidQuestionMark(node.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional)) {
                        return true;
                    }
                    else if (checkGrammarForInvalidExclamationToken(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context)) {
                        return true;
                    }
                    else if (node.body === undefined) {
                        return grammarErrorAtPos(node, node.end - 1, ";".length, ts.Diagnostics._0_expected, "{");
                    }
                }
                if (checkGrammarForGenerator(node)) {
                    return true;
                }
            }
            if (ts.isClassLike(node.parent)) {
                // Technically, computed properties in ambient contexts is disallowed
                // for property declarations and accessors too, not just methods.
                // However, property declarations disallow computed names in general,
                // and accessors are not allowed in ambient contexts in general,
                // so this error only really matters for methods.
                if (node.flags & 8388608 /* Ambient */) {
                    return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
                }
                else if (node.kind === 161 /* MethodDeclaration */ && !node.body) {
                    return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
                }
            }
            else if (node.parent.kind === 246 /* InterfaceDeclaration */) {
                return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
            }
            else if (node.parent.kind === 173 /* TypeLiteral */) {
                return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type);
            }
        }
        function checkGrammarBreakOrContinueStatement(node) {
            var current = node;
            while (current) {
                if (ts.isFunctionLike(current)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.Jump_target_cannot_cross_function_boundary);
                }
                switch (current.kind) {
                    case 238 /* LabeledStatement */:
                        if (node.label && current.label.escapedText === node.label.escapedText) {
                            // found matching label - verify that label usage is correct
                            // continue can only target labels that are on iteration statements
                            var isMisplacedContinueLabel = node.kind === 233 /* ContinueStatement */
                                && !ts.isIterationStatement(current.statement, /*lookInLabeledStatement*/ true);
                            if (isMisplacedContinueLabel) {
                                return grammarErrorOnNode(node, ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement);
                            }
                            return false;
                        }
                        break;
                    case 237 /* SwitchStatement */:
                        if (node.kind === 234 /* BreakStatement */ && !node.label) {
                            // unlabeled break within switch statement - ok
                            return false;
                        }
                        break;
                    default:
                        if (ts.isIterationStatement(current, /*lookInLabeledStatement*/ false) && !node.label) {
                            // unlabeled break or continue within iteration statement - ok
                            return false;
                        }
                        break;
                }
                current = current.parent;
            }
            if (node.label) {
                var message = node.kind === 234 /* BreakStatement */
                    ? ts.Diagnostics.A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement
                    : ts.Diagnostics.A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement;
                return grammarErrorOnNode(node, message);
            }
            else {
                var message = node.kind === 234 /* BreakStatement */
                    ? ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement
                    : ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement;
                return grammarErrorOnNode(node, message);
            }
        }
        function checkGrammarBindingElement(node) {
            if (node.dotDotDotToken) {
                var elements = node.parent.elements;
                if (node !== ts.last(elements)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern);
                }
                checkGrammarForDisallowedTrailingComma(elements, ts.Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
                if (node.propertyName) {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.A_rest_element_cannot_have_a_property_name);
                }
                if (node.initializer) {
                    // Error on equals token which immediately precedes the initializer
                    return grammarErrorAtPos(node, node.initializer.pos - 1, 1, ts.Diagnostics.A_rest_element_cannot_have_an_initializer);
                }
            }
        }
        function isStringOrNumberLiteralExpression(expr) {
            return ts.isStringOrNumericLiteralLike(expr) ||
                expr.kind === 207 /* PrefixUnaryExpression */ && expr.operator === 40 /* MinusToken */ &&
                    expr.operand.kind === 8 /* NumericLiteral */;
        }
        function isBigIntLiteralExpression(expr) {
            return expr.kind === 9 /* BigIntLiteral */ ||
                expr.kind === 207 /* PrefixUnaryExpression */ && expr.operator === 40 /* MinusToken */ &&
                    expr.operand.kind === 9 /* BigIntLiteral */;
        }
        function isSimpleLiteralEnumReference(expr) {
            if ((ts.isPropertyAccessExpression(expr) || (ts.isElementAccessExpression(expr) && isStringOrNumberLiteralExpression(expr.argumentExpression))) &&
                ts.isEntityNameExpression(expr.expression)) {
                return !!(checkExpressionCached(expr).flags & 1024 /* EnumLiteral */);
            }
        }
        function checkAmbientInitializer(node) {
            var initializer = node.initializer;
            if (initializer) {
                var isInvalidInitializer = !(isStringOrNumberLiteralExpression(initializer) ||
                    isSimpleLiteralEnumReference(initializer) ||
                    initializer.kind === 106 /* TrueKeyword */ || initializer.kind === 91 /* FalseKeyword */ ||
                    isBigIntLiteralExpression(initializer));
                var isConstOrReadonly = ts.isDeclarationReadonly(node) || ts.isVariableDeclaration(node) && ts.isVarConst(node);
                if (isConstOrReadonly && !node.type) {
                    if (isInvalidInitializer) {
                        return grammarErrorOnNode(initializer, ts.Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_or_literal_enum_reference);
                    }
                }
                else {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                }
                if (!isConstOrReadonly || isInvalidInitializer) {
                    return grammarErrorOnNode(initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
                }
            }
        }
        function checkGrammarVariableDeclaration(node) {
            if (node.parent.parent.kind !== 231 /* ForInStatement */ && node.parent.parent.kind !== 232 /* ForOfStatement */) {
                if (node.flags & 8388608 /* Ambient */) {
                    checkAmbientInitializer(node);
                }
                else if (!node.initializer) {
                    if (ts.isBindingPattern(node.name) && !ts.isBindingPattern(node.parent)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.A_destructuring_declaration_must_have_an_initializer);
                    }
                    if (ts.isVarConst(node)) {
                        return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_must_be_initialized);
                    }
                }
            }
            if (node.exclamationToken && (node.parent.parent.kind !== 225 /* VariableStatement */ || !node.type || node.initializer || node.flags & 8388608 /* Ambient */)) {
                return grammarErrorOnNode(node.exclamationToken, ts.Diagnostics.Definite_assignment_assertions_can_only_be_used_along_with_a_type_annotation);
            }
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            if (moduleKind < ts.ModuleKind.ES2015 && moduleKind !== ts.ModuleKind.System && !compilerOptions.noEmit &&
                !(node.parent.parent.flags & 8388608 /* Ambient */) && ts.hasModifier(node.parent.parent, 1 /* Export */)) {
                checkESModuleMarker(node.name);
            }
            var checkLetConstNames = (ts.isLet(node) || ts.isVarConst(node));
            // 1. LexicalDeclaration : LetOrConst BindingList ;
            // It is a Syntax Error if the BoundNames of BindingList contains "let".
            // 2. ForDeclaration: ForDeclaration : LetOrConst ForBinding
            // It is a Syntax Error if the BoundNames of ForDeclaration contains "let".
            // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code
            // and its Identifier is eval or arguments
            return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name);
        }
        function checkESModuleMarker(name) {
            if (name.kind === 75 /* Identifier */) {
                if (ts.idText(name) === "__esModule") {
                    return grammarErrorOnNode(name, ts.Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules);
                }
            }
            else {
                var elements = name.elements;
                for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
                    var element = elements_1[_i];
                    if (!ts.isOmittedExpression(element)) {
                        return checkESModuleMarker(element.name);
                    }
                }
            }
            return false;
        }
        function checkGrammarNameInLetOrConstDeclarations(name) {
            if (name.kind === 75 /* Identifier */) {
                if (name.originalKeywordKind === 115 /* LetKeyword */) {
                    return grammarErrorOnNode(name, ts.Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations);
                }
            }
            else {
                var elements = name.elements;
                for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) {
                    var element = elements_2[_i];
                    if (!ts.isOmittedExpression(element)) {
                        checkGrammarNameInLetOrConstDeclarations(element.name);
                    }
                }
            }
            return false;
        }
        function checkGrammarVariableDeclarationList(declarationList) {
            var declarations = declarationList.declarations;
            if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) {
                return true;
            }
            if (!declarationList.declarations.length) {
                return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty);
            }
            return false;
        }
        function allowLetAndConstDeclarations(parent) {
            switch (parent.kind) {
                case 227 /* IfStatement */:
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                case 236 /* WithStatement */:
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                    return false;
                case 238 /* LabeledStatement */:
                    return allowLetAndConstDeclarations(parent.parent);
            }
            return true;
        }
        function checkGrammarForDisallowedLetOrConstStatement(node) {
            if (!allowLetAndConstDeclarations(node.parent)) {
                if (ts.isLet(node.declarationList)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block);
                }
                else if (ts.isVarConst(node.declarationList)) {
                    return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block);
                }
            }
        }
        function checkGrammarMetaProperty(node) {
            var escapedText = node.name.escapedText;
            switch (node.keywordToken) {
                case 99 /* NewKeyword */:
                    if (escapedText !== "target") {
                        return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "target");
                    }
                    break;
                case 96 /* ImportKeyword */:
                    if (escapedText !== "meta") {
                        return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "meta");
                    }
                    break;
            }
        }
        function hasParseDiagnostics(sourceFile) {
            return sourceFile.parseDiagnostics.length > 0;
        }
        function grammarErrorOnFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function grammarErrorAtPos(nodeForSourceFile, start, length, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(nodeForSourceFile);
            if (!hasParseDiagnostics(sourceFile)) {
                diagnostics.add(ts.createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function grammarErrorOnNode(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                diagnostics.add(ts.createDiagnosticForNode(node, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function checkGrammarConstructorTypeParameters(node) {
            var jsdocTypeParameters = ts.isInJSFile(node) ? ts.getJSDocTypeParameterDeclarations(node) : undefined;
            var range = node.typeParameters || jsdocTypeParameters && ts.firstOrUndefined(jsdocTypeParameters);
            if (range) {
                var pos = range.pos === range.end ? range.pos : ts.skipTrivia(ts.getSourceFileOfNode(node).text, range.pos);
                return grammarErrorAtPos(node, pos, range.end - pos, ts.Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration);
            }
        }
        function checkGrammarConstructorTypeAnnotation(node) {
            var type = ts.getEffectiveReturnTypeNode(node);
            if (type) {
                return grammarErrorOnNode(type, ts.Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration);
            }
        }
        function checkGrammarProperty(node) {
            if (ts.isClassLike(node.parent)) {
                if (ts.isStringLiteral(node.name) && node.name.text === "constructor") {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.Classes_may_not_have_a_field_named_constructor);
                }
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
                if (languageVersion < 2 /* ES2015 */ && ts.isPrivateIdentifier(node.name)) {
                    return grammarErrorOnNode(node.name, ts.Diagnostics.Private_identifiers_are_only_available_when_targeting_ECMAScript_2015_and_higher);
                }
            }
            else if (node.parent.kind === 246 /* InterfaceDeclaration */) {
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
                if (node.initializer) {
                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.An_interface_property_cannot_have_an_initializer);
                }
            }
            else if (node.parent.kind === 173 /* TypeLiteral */) {
                if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) {
                    return true;
                }
                if (node.initializer) {
                    return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_type_literal_property_cannot_have_an_initializer);
                }
            }
            if (node.flags & 8388608 /* Ambient */) {
                checkAmbientInitializer(node);
            }
            if (ts.isPropertyDeclaration(node) && node.exclamationToken && (!ts.isClassLike(node.parent) || !node.type || node.initializer ||
                node.flags & 8388608 /* Ambient */ || ts.hasModifier(node, 32 /* Static */ | 128 /* Abstract */))) {
                return grammarErrorOnNode(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
            }
        }
        function checkGrammarTopLevelElementForRequiredDeclareModifier(node) {
            // A declare modifier is required for any top level .d.ts declaration except export=, export default, export as namespace
            // interfaces and imports categories:
            //
            //  DeclarationElement:
            //     ExportAssignment
            //     export_opt   InterfaceDeclaration
            //     export_opt   TypeAliasDeclaration
            //     export_opt   ImportDeclaration
            //     export_opt   ExternalImportDeclaration
            //     export_opt   AmbientDeclaration
            //
            // TODO: The spec needs to be amended to reflect this grammar.
            if (node.kind === 246 /* InterfaceDeclaration */ ||
                node.kind === 247 /* TypeAliasDeclaration */ ||
                node.kind === 254 /* ImportDeclaration */ ||
                node.kind === 253 /* ImportEqualsDeclaration */ ||
                node.kind === 260 /* ExportDeclaration */ ||
                node.kind === 259 /* ExportAssignment */ ||
                node.kind === 252 /* NamespaceExportDeclaration */ ||
                ts.hasModifier(node, 2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) {
                return false;
            }
            return grammarErrorOnFirstToken(node, ts.Diagnostics.Top_level_declarations_in_d_ts_files_must_start_with_either_a_declare_or_export_modifier);
        }
        function checkGrammarTopLevelElementsForRequiredDeclareModifier(file) {
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (ts.isDeclaration(decl) || decl.kind === 225 /* VariableStatement */) {
                    if (checkGrammarTopLevelElementForRequiredDeclareModifier(decl)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function checkGrammarSourceFile(node) {
            return !!(node.flags & 8388608 /* Ambient */) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node);
        }
        function checkGrammarStatementInAmbientContext(node) {
            if (node.flags & 8388608 /* Ambient */) {
                // Find containing block which is either Block, ModuleBlock, SourceFile
                var links = getNodeLinks(node);
                if (!links.hasReportedStatementInAmbientContext && (ts.isFunctionLike(node.parent) || ts.isAccessor(node.parent))) {
                    return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts);
                }
                // We are either parented by another statement, or some sort of block.
                // If we're in a block, we only want to really report an error once
                // to prevent noisiness.  So use a bit on the block to indicate if
                // this has already been reported, and don't report if it has.
                //
                if (node.parent.kind === 223 /* Block */ || node.parent.kind === 250 /* ModuleBlock */ || node.parent.kind === 290 /* SourceFile */) {
                    var links_2 = getNodeLinks(node.parent);
                    // Check if the containing block ever report this error
                    if (!links_2.hasReportedStatementInAmbientContext) {
                        return links_2.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
                    }
                }
                else {
                    // We must be parented by a statement.  If so, there's no need
                    // to report the error as our parent will have already done it.
                    // Debug.assert(isStatement(node.parent));
                }
            }
            return false;
        }
        function checkGrammarNumericLiteral(node) {
            // Grammar checking
            if (node.numericLiteralFlags & 32 /* Octal */) {
                var diagnosticMessage = void 0;
                if (languageVersion >= 1 /* ES5 */) {
                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0;
                }
                else if (ts.isChildOfNodeWithKind(node, 187 /* LiteralType */)) {
                    diagnosticMessage = ts.Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0;
                }
                else if (ts.isChildOfNodeWithKind(node, 284 /* EnumMember */)) {
                    diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0;
                }
                if (diagnosticMessage) {
                    var withMinus = ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === 40 /* MinusToken */;
                    var literal = (withMinus ? "-" : "") + "0o" + node.text;
                    return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal);
                }
            }
            // Realism (size) checking
            checkNumericLiteralValueSize(node);
            return false;
        }
        function checkNumericLiteralValueSize(node) {
            // Scientific notation (e.g. 2e54 and 1e00000000010) can't be converted to bigint
            // Literals with 15 or fewer characters aren't long enough to reach past 2^53 - 1
            // Fractional numbers (e.g. 9000000000000000.001) are inherently imprecise anyway
            if (node.numericLiteralFlags & 16 /* Scientific */ || node.text.length <= 15 || node.text.indexOf(".") !== -1) {
                return;
            }
            // We can't rely on the runtime to accurately store and compare extremely large numeric values
            // Even for internal use, we use getTextOfNode: https://github.com/microsoft/TypeScript/issues/33298
            // Thus, if the runtime claims a too-large number is lower than Number.MAX_SAFE_INTEGER,
            // it's likely addition operations on it will fail too
            var apparentValue = +ts.getTextOfNode(node);
            if (apparentValue <= Math.pow(2, 53) - 1 && apparentValue + 1 > apparentValue) {
                return;
            }
            addErrorOrSuggestion(/*isError*/ false, ts.createDiagnosticForNode(node, ts.Diagnostics.Numeric_literals_with_absolute_values_equal_to_2_53_or_greater_are_too_large_to_be_represented_accurately_as_integers));
        }
        function checkGrammarBigIntLiteral(node) {
            var literalType = ts.isLiteralTypeNode(node.parent) ||
                ts.isPrefixUnaryExpression(node.parent) && ts.isLiteralTypeNode(node.parent.parent);
            if (!literalType) {
                if (languageVersion < 7 /* ES2020 */) {
                    if (grammarErrorOnNode(node, ts.Diagnostics.BigInt_literals_are_not_available_when_targeting_lower_than_ES2020)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function grammarErrorAfterFirstToken(node, message, arg0, arg1, arg2) {
            var sourceFile = ts.getSourceFileOfNode(node);
            if (!hasParseDiagnostics(sourceFile)) {
                var span = ts.getSpanOfTokenAtPosition(sourceFile, node.pos);
                diagnostics.add(ts.createFileDiagnostic(sourceFile, ts.textSpanEnd(span), /*length*/ 0, message, arg0, arg1, arg2));
                return true;
            }
            return false;
        }
        function getAmbientModules() {
            if (!ambientModulesCache) {
                ambientModulesCache = [];
                globals.forEach(function (global, sym) {
                    // No need to `unescapeLeadingUnderscores`, an escaped symbol is never an ambient module.
                    if (ambientModuleSymbolRegex.test(sym)) {
                        ambientModulesCache.push(global);
                    }
                });
            }
            return ambientModulesCache;
        }
        function checkGrammarImportClause(node) {
            if (node.isTypeOnly && node.name && node.namedBindings) {
                return grammarErrorOnNode(node, ts.Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both);
            }
            return false;
        }
        function checkGrammarImportCallExpression(node) {
            if (moduleKind === ts.ModuleKind.ES2015) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_esnext_commonjs_amd_system_or_umd);
            }
            if (node.typeArguments) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_have_type_arguments);
            }
            var nodeArguments = node.arguments;
            if (nodeArguments.length !== 1) {
                return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument);
            }
            checkGrammarForDisallowedTrailingComma(nodeArguments);
            // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import.
            // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import.
            if (ts.isSpreadElement(nodeArguments[0])) {
                return grammarErrorOnNode(nodeArguments[0], ts.Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element);
            }
            return false;
        }
        function findMatchingTypeReferenceOrTypeAliasReference(source, unionTarget) {
            var sourceObjectFlags = ts.getObjectFlags(source);
            if (sourceObjectFlags & (4 /* Reference */ | 16 /* Anonymous */) && unionTarget.flags & 1048576 /* Union */) {
                return ts.find(unionTarget.types, function (target) {
                    if (target.flags & 524288 /* Object */) {
                        var overlapObjFlags = sourceObjectFlags & ts.getObjectFlags(target);
                        if (overlapObjFlags & 4 /* Reference */) {
                            return source.target === target.target;
                        }
                        if (overlapObjFlags & 16 /* Anonymous */) {
                            return !!source.aliasSymbol && source.aliasSymbol === target.aliasSymbol;
                        }
                    }
                    return false;
                });
            }
        }
        function findBestTypeForObjectLiteral(source, unionTarget) {
            if (ts.getObjectFlags(source) & 128 /* ObjectLiteral */ && forEachType(unionTarget, isArrayLikeType)) {
                return ts.find(unionTarget.types, function (t) { return !isArrayLikeType(t); });
            }
        }
        function findBestTypeForInvokable(source, unionTarget) {
            var signatureKind = 0 /* Call */;
            var hasSignatures = getSignaturesOfType(source, signatureKind).length > 0 ||
                (signatureKind = 1 /* Construct */, getSignaturesOfType(source, signatureKind).length > 0);
            if (hasSignatures) {
                return ts.find(unionTarget.types, function (t) { return getSignaturesOfType(t, signatureKind).length > 0; });
            }
        }
        function findMostOverlappyType(source, unionTarget) {
            var bestMatch;
            var matchingCount = 0;
            for (var _i = 0, _a = unionTarget.types; _i < _a.length; _i++) {
                var target = _a[_i];
                var overlap = getIntersectionType([getIndexType(source), getIndexType(target)]);
                if (overlap.flags & 4194304 /* Index */) {
                    // perfect overlap of keys
                    bestMatch = target;
                    matchingCount = Infinity;
                }
                else if (overlap.flags & 1048576 /* Union */) {
                    // We only want to account for literal types otherwise.
                    // If we have a union of index types, it seems likely that we
                    // needed to elaborate between two generic mapped types anyway.
                    var len = ts.length(ts.filter(overlap.types, isUnitType));
                    if (len >= matchingCount) {
                        bestMatch = target;
                        matchingCount = len;
                    }
                }
                else if (isUnitType(overlap) && 1 >= matchingCount) {
                    bestMatch = target;
                    matchingCount = 1;
                }
            }
            return bestMatch;
        }
        function filterPrimitivesIfContainsNonPrimitive(type) {
            if (maybeTypeOfKind(type, 67108864 /* NonPrimitive */)) {
                var result = filterType(type, function (t) { return !(t.flags & 131068 /* Primitive */); });
                if (!(result.flags & 131072 /* Never */)) {
                    return result;
                }
            }
            return type;
        }
        // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly
        function findMatchingDiscriminantType(source, target, isRelatedTo, skipPartial) {
            if (target.flags & 1048576 /* Union */ && source.flags & (2097152 /* Intersection */ | 524288 /* Object */)) {
                var sourceProperties = getPropertiesOfType(source);
                if (sourceProperties) {
                    var sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target);
                    if (sourcePropertiesFiltered) {
                        return discriminateTypeByDiscriminableItems(target, ts.map(sourcePropertiesFiltered, function (p) { return [function () { return getTypeOfSymbol(p); }, p.escapedName]; }), isRelatedTo, /*defaultValue*/ undefined, skipPartial);
                    }
                }
            }
            return undefined;
        }
    }
    ts.createTypeChecker = createTypeChecker;
    function isNotAccessor(declaration) {
        // Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks
        return !ts.isAccessor(declaration);
    }
    function isNotOverload(declaration) {
        return (declaration.kind !== 244 /* FunctionDeclaration */ && declaration.kind !== 161 /* MethodDeclaration */) ||
            !!declaration.body;
    }
    /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */
    function isDeclarationNameOrImportPropertyName(name) {
        switch (name.parent.kind) {
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
                return ts.isIdentifier(name);
            default:
                return ts.isDeclarationName(name);
        }
    }
    function isSomeImportDeclaration(decl) {
        switch (decl.kind) {
            case 255 /* ImportClause */: // For default import
            case 253 /* ImportEqualsDeclaration */:
            case 256 /* NamespaceImport */:
            case 258 /* ImportSpecifier */: // For rename import `x as y`
                return true;
            case 75 /* Identifier */:
                // For regular import, `decl` is an Identifier under the ImportSpecifier.
                return decl.parent.kind === 258 /* ImportSpecifier */;
            default:
                return false;
        }
    }
    var JsxNames;
    (function (JsxNames) {
        JsxNames.JSX = "JSX";
        JsxNames.IntrinsicElements = "IntrinsicElements";
        JsxNames.ElementClass = "ElementClass";
        JsxNames.ElementAttributesPropertyNameContainer = "ElementAttributesProperty"; // TODO: Deprecate and remove support
        JsxNames.ElementChildrenAttributeNameContainer = "ElementChildrenAttribute";
        JsxNames.Element = "Element";
        JsxNames.IntrinsicAttributes = "IntrinsicAttributes";
        JsxNames.IntrinsicClassAttributes = "IntrinsicClassAttributes";
        JsxNames.LibraryManagedAttributes = "LibraryManagedAttributes";
    })(JsxNames || (JsxNames = {}));
    function getIterationTypesKeyFromIterationTypeKind(typeKind) {
        switch (typeKind) {
            case 0 /* Yield */: return "yieldType";
            case 1 /* Return */: return "returnType";
            case 2 /* Next */: return "nextType";
        }
    }
    function signatureHasRestParameter(s) {
        return !!(s.flags & 1 /* HasRestParameter */);
    }
    ts.signatureHasRestParameter = signatureHasRestParameter;
    function signatureHasLiteralTypes(s) {
        return !!(s.flags & 2 /* HasLiteralTypes */);
    }
    ts.signatureHasLiteralTypes = signatureHasLiteralTypes;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createSynthesizedNode(kind) {
        var node = ts.createNode(kind, -1, -1);
        node.flags |= 8 /* Synthesized */;
        return node;
    }
    /* @internal */
    function updateNode(updated, original) {
        if (updated !== original) {
            setOriginalNode(updated, original);
            setTextRange(updated, original);
            ts.aggregateTransformFlags(updated);
        }
        return updated;
    }
    ts.updateNode = updateNode;
    /**
     * Make `elements` into a `NodeArray<T>`. If `elements` is `undefined`, returns an empty `NodeArray<T>`.
     */
    function createNodeArray(elements, hasTrailingComma) {
        if (!elements || elements === ts.emptyArray) {
            elements = [];
        }
        else if (ts.isNodeArray(elements)) {
            return elements;
        }
        var array = elements;
        array.pos = -1;
        array.end = -1;
        array.hasTrailingComma = hasTrailingComma;
        return array;
    }
    ts.createNodeArray = createNodeArray;
    /**
     * Creates a shallow, memberwise clone of a node with no source map location.
     */
    /* @internal */
    function getSynthesizedClone(node) {
        // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
        // the original node. We also need to exclude specific properties and only include own-
        // properties (to skip members already defined on the shared prototype).
        if (node === undefined) {
            return node;
        }
        var clone = createSynthesizedNode(node.kind);
        clone.flags |= node.flags;
        setOriginalNode(clone, node);
        for (var key in node) {
            if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) {
                continue;
            }
            clone[key] = node[key];
        }
        return clone;
    }
    ts.getSynthesizedClone = getSynthesizedClone;
    function createLiteral(value, isSingleQuote) {
        if (typeof value === "number") {
            return createNumericLiteral(value + "");
        }
        // eslint-disable-next-line no-in-operator
        if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt
            return createBigIntLiteral(ts.pseudoBigIntToString(value) + "n");
        }
        if (typeof value === "boolean") {
            return value ? createTrue() : createFalse();
        }
        if (ts.isString(value)) {
            var res = createStringLiteral(value);
            if (isSingleQuote)
                res.singleQuote = true;
            return res;
        }
        return createLiteralFromNode(value);
    }
    ts.createLiteral = createLiteral;
    function createNumericLiteral(value, numericLiteralFlags) {
        if (numericLiteralFlags === void 0) { numericLiteralFlags = 0 /* None */; }
        var node = createSynthesizedNode(8 /* NumericLiteral */);
        node.text = value;
        node.numericLiteralFlags = numericLiteralFlags;
        return node;
    }
    ts.createNumericLiteral = createNumericLiteral;
    function createBigIntLiteral(value) {
        var node = createSynthesizedNode(9 /* BigIntLiteral */);
        node.text = value;
        return node;
    }
    ts.createBigIntLiteral = createBigIntLiteral;
    function createStringLiteral(text) {
        var node = createSynthesizedNode(10 /* StringLiteral */);
        node.text = text;
        return node;
    }
    ts.createStringLiteral = createStringLiteral;
    function createRegularExpressionLiteral(text) {
        var node = createSynthesizedNode(13 /* RegularExpressionLiteral */);
        node.text = text;
        return node;
    }
    ts.createRegularExpressionLiteral = createRegularExpressionLiteral;
    function createLiteralFromNode(sourceNode) {
        var node = createStringLiteral(ts.getTextOfIdentifierOrLiteral(sourceNode));
        node.textSourceNode = sourceNode;
        return node;
    }
    function createIdentifier(text, typeArguments) {
        var node = createSynthesizedNode(75 /* Identifier */);
        node.escapedText = ts.escapeLeadingUnderscores(text);
        node.originalKeywordKind = text ? ts.stringToToken(text) : 0 /* Unknown */;
        node.autoGenerateFlags = 0 /* None */;
        node.autoGenerateId = 0;
        if (typeArguments) {
            node.typeArguments = createNodeArray(typeArguments);
        }
        return node;
    }
    ts.createIdentifier = createIdentifier;
    function updateIdentifier(node, typeArguments) {
        return node.typeArguments !== typeArguments
            ? updateNode(createIdentifier(ts.idText(node), typeArguments), node)
            : node;
    }
    ts.updateIdentifier = updateIdentifier;
    var nextAutoGenerateId = 0;
    function createTempVariable(recordTempVariable, reservedInNestedScopes) {
        var name = createIdentifier("");
        name.autoGenerateFlags = 1 /* Auto */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        if (recordTempVariable) {
            recordTempVariable(name);
        }
        if (reservedInNestedScopes) {
            name.autoGenerateFlags |= 8 /* ReservedInNestedScopes */;
        }
        return name;
    }
    ts.createTempVariable = createTempVariable;
    /** Create a unique temporary variable for use in a loop. */
    function createLoopVariable() {
        var name = createIdentifier("");
        name.autoGenerateFlags = 2 /* Loop */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createLoopVariable = createLoopVariable;
    /** Create a unique name based on the supplied text. */
    function createUniqueName(text) {
        var name = createIdentifier(text);
        name.autoGenerateFlags = 3 /* Unique */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createUniqueName = createUniqueName;
    function createOptimisticUniqueName(text) {
        var name = createIdentifier(text);
        name.autoGenerateFlags = 3 /* Unique */ | 16 /* Optimistic */;
        name.autoGenerateId = nextAutoGenerateId;
        nextAutoGenerateId++;
        return name;
    }
    ts.createOptimisticUniqueName = createOptimisticUniqueName;
    /** Create a unique name based on the supplied text. This does not consider names injected by the transformer. */
    function createFileLevelUniqueName(text) {
        var name = createOptimisticUniqueName(text);
        name.autoGenerateFlags |= 32 /* FileLevel */;
        return name;
    }
    ts.createFileLevelUniqueName = createFileLevelUniqueName;
    function getGeneratedNameForNode(node, flags) {
        var name = createIdentifier(node && ts.isIdentifier(node) ? ts.idText(node) : "");
        name.autoGenerateFlags = 4 /* Node */ | flags;
        name.autoGenerateId = nextAutoGenerateId;
        name.original = node;
        nextAutoGenerateId++;
        return name;
    }
    ts.getGeneratedNameForNode = getGeneratedNameForNode;
    // Private Identifiers
    function createPrivateIdentifier(text) {
        if (text[0] !== "#") {
            ts.Debug.fail("First character of private identifier must be #: " + text);
        }
        var node = createSynthesizedNode(76 /* PrivateIdentifier */);
        node.escapedText = ts.escapeLeadingUnderscores(text);
        return node;
    }
    ts.createPrivateIdentifier = createPrivateIdentifier;
    // Punctuation
    function createToken(token) {
        return createSynthesizedNode(token);
    }
    ts.createToken = createToken;
    // Reserved words
    function createSuper() {
        return createSynthesizedNode(102 /* SuperKeyword */);
    }
    ts.createSuper = createSuper;
    function createThis() {
        return createSynthesizedNode(104 /* ThisKeyword */);
    }
    ts.createThis = createThis;
    function createNull() {
        return createSynthesizedNode(100 /* NullKeyword */);
    }
    ts.createNull = createNull;
    function createTrue() {
        return createSynthesizedNode(106 /* TrueKeyword */);
    }
    ts.createTrue = createTrue;
    function createFalse() {
        return createSynthesizedNode(91 /* FalseKeyword */);
    }
    ts.createFalse = createFalse;
    // Modifiers
    function createModifier(kind) {
        return createToken(kind);
    }
    ts.createModifier = createModifier;
    function createModifiersFromModifierFlags(flags) {
        var result = [];
        if (flags & 1 /* Export */) {
            result.push(createModifier(89 /* ExportKeyword */));
        }
        if (flags & 2 /* Ambient */) {
            result.push(createModifier(130 /* DeclareKeyword */));
        }
        if (flags & 512 /* Default */) {
            result.push(createModifier(84 /* DefaultKeyword */));
        }
        if (flags & 2048 /* Const */) {
            result.push(createModifier(81 /* ConstKeyword */));
        }
        if (flags & 4 /* Public */) {
            result.push(createModifier(119 /* PublicKeyword */));
        }
        if (flags & 8 /* Private */) {
            result.push(createModifier(117 /* PrivateKeyword */));
        }
        if (flags & 16 /* Protected */) {
            result.push(createModifier(118 /* ProtectedKeyword */));
        }
        if (flags & 128 /* Abstract */) {
            result.push(createModifier(122 /* AbstractKeyword */));
        }
        if (flags & 32 /* Static */) {
            result.push(createModifier(120 /* StaticKeyword */));
        }
        if (flags & 64 /* Readonly */) {
            result.push(createModifier(138 /* ReadonlyKeyword */));
        }
        if (flags & 256 /* Async */) {
            result.push(createModifier(126 /* AsyncKeyword */));
        }
        return result;
    }
    ts.createModifiersFromModifierFlags = createModifiersFromModifierFlags;
    // Names
    function createQualifiedName(left, right) {
        var node = createSynthesizedNode(153 /* QualifiedName */);
        node.left = left;
        node.right = asName(right);
        return node;
    }
    ts.createQualifiedName = createQualifiedName;
    function updateQualifiedName(node, left, right) {
        return node.left !== left
            || node.right !== right
            ? updateNode(createQualifiedName(left, right), node)
            : node;
    }
    ts.updateQualifiedName = updateQualifiedName;
    function parenthesizeForComputedName(expression) {
        return ts.isCommaSequence(expression)
            ? createParen(expression)
            : expression;
    }
    function createComputedPropertyName(expression) {
        var node = createSynthesizedNode(154 /* ComputedPropertyName */);
        node.expression = parenthesizeForComputedName(expression);
        return node;
    }
    ts.createComputedPropertyName = createComputedPropertyName;
    function updateComputedPropertyName(node, expression) {
        return node.expression !== expression
            ? updateNode(createComputedPropertyName(expression), node)
            : node;
    }
    ts.updateComputedPropertyName = updateComputedPropertyName;
    // Signature elements
    function createTypeParameterDeclaration(name, constraint, defaultType) {
        var node = createSynthesizedNode(155 /* TypeParameter */);
        node.name = asName(name);
        node.constraint = constraint;
        node.default = defaultType;
        return node;
    }
    ts.createTypeParameterDeclaration = createTypeParameterDeclaration;
    function updateTypeParameterDeclaration(node, name, constraint, defaultType) {
        return node.name !== name
            || node.constraint !== constraint
            || node.default !== defaultType
            ? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node)
            : node;
    }
    ts.updateTypeParameterDeclaration = updateTypeParameterDeclaration;
    function createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(156 /* Parameter */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.dotDotDotToken = dotDotDotToken;
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createParameter = createParameter;
    function updateParameter(node, decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.dotDotDotToken !== dotDotDotToken
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updateParameter = updateParameter;
    function createDecorator(expression) {
        var node = createSynthesizedNode(157 /* Decorator */);
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createDecorator = createDecorator;
    function updateDecorator(node, expression) {
        return node.expression !== expression
            ? updateNode(createDecorator(expression), node)
            : node;
    }
    ts.updateDecorator = updateDecorator;
    // Type Elements
    function createPropertySignature(modifiers, name, questionToken, type, initializer) {
        var node = createSynthesizedNode(158 /* PropertySignature */);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.questionToken = questionToken;
        node.type = type;
        node.initializer = initializer;
        return node;
    }
    ts.createPropertySignature = createPropertySignature;
    function updatePropertySignature(node, modifiers, name, questionToken, type, initializer) {
        return node.modifiers !== modifiers
            || node.name !== name
            || node.questionToken !== questionToken
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node)
            : node;
    }
    ts.updatePropertySignature = updatePropertySignature;
    function createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer) {
        var node = createSynthesizedNode(159 /* PropertyDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.questionToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 57 /* QuestionToken */ ? questionOrExclamationToken : undefined;
        node.exclamationToken = questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 53 /* ExclamationToken */ ? questionOrExclamationToken : undefined;
        node.type = type;
        node.initializer = initializer;
        return node;
    }
    ts.createProperty = createProperty;
    function updateProperty(node, decorators, modifiers, name, questionOrExclamationToken, type, initializer) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.questionToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 57 /* QuestionToken */ ? questionOrExclamationToken : undefined)
            || node.exclamationToken !== (questionOrExclamationToken !== undefined && questionOrExclamationToken.kind === 53 /* ExclamationToken */ ? questionOrExclamationToken : undefined)
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createProperty(decorators, modifiers, name, questionOrExclamationToken, type, initializer), node)
            : node;
    }
    ts.updateProperty = updateProperty;
    function createMethodSignature(typeParameters, parameters, type, name, questionToken) {
        var node = createSignatureDeclaration(160 /* MethodSignature */, typeParameters, parameters, type);
        node.name = asName(name);
        node.questionToken = questionToken;
        return node;
    }
    ts.createMethodSignature = createMethodSignature;
    function updateMethodSignature(node, typeParameters, parameters, type, name, questionToken) {
        return node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.name !== name
            || node.questionToken !== questionToken
            ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
            : node;
    }
    ts.updateMethodSignature = updateMethodSignature;
    function createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(161 /* MethodDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.questionToken = questionToken;
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createMethod = createMethod;
    function createMethodCall(object, methodName, argumentsList) {
        return createCall(createPropertyAccess(object, asName(methodName)), 
        /*typeArguments*/ undefined, argumentsList);
    }
    function createGlobalMethodCall(globalObjectName, methodName, argumentsList) {
        return createMethodCall(createIdentifier(globalObjectName), methodName, argumentsList);
    }
    /* @internal */
    function createObjectDefinePropertyCall(target, propertyName, attributes) {
        return createGlobalMethodCall("Object", "defineProperty", [target, asExpression(propertyName), attributes]);
    }
    ts.createObjectDefinePropertyCall = createObjectDefinePropertyCall;
    function tryAddPropertyAssignment(properties, propertyName, expression) {
        if (expression) {
            properties.push(createPropertyAssignment(propertyName, expression));
            return true;
        }
        return false;
    }
    /* @internal */
    function createPropertyDescriptor(attributes, singleLine) {
        var properties = [];
        tryAddPropertyAssignment(properties, "enumerable", asExpression(attributes.enumerable));
        tryAddPropertyAssignment(properties, "configurable", asExpression(attributes.configurable));
        var isData = tryAddPropertyAssignment(properties, "writable", asExpression(attributes.writable));
        isData = tryAddPropertyAssignment(properties, "value", attributes.value) || isData;
        var isAccessor = tryAddPropertyAssignment(properties, "get", attributes.get);
        isAccessor = tryAddPropertyAssignment(properties, "set", attributes.set) || isAccessor;
        ts.Debug.assert(!(isData && isAccessor), "A PropertyDescriptor may not be both an accessor descriptor and a data descriptor.");
        return createObjectLiteral(properties, !singleLine);
    }
    ts.createPropertyDescriptor = createPropertyDescriptor;
    function updateMethod(node, decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.name !== name
            || node.questionToken !== questionToken
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateMethod = updateMethod;
    function createConstructor(decorators, modifiers, parameters, body) {
        var node = createSynthesizedNode(162 /* Constructor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.type = undefined;
        node.body = body;
        return node;
    }
    ts.createConstructor = createConstructor;
    function updateConstructor(node, decorators, modifiers, parameters, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.parameters !== parameters
            || node.body !== body
            ? updateNode(createConstructor(decorators, modifiers, parameters, body), node)
            : node;
    }
    ts.updateConstructor = updateConstructor;
    function createGetAccessor(decorators, modifiers, name, parameters, type, body) {
        var node = createSynthesizedNode(163 /* GetAccessor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createGetAccessor = createGetAccessor;
    function updateGetAccessor(node, decorators, modifiers, name, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body), node)
            : node;
    }
    ts.updateGetAccessor = updateGetAccessor;
    function createSetAccessor(decorators, modifiers, name, parameters, body) {
        var node = createSynthesizedNode(164 /* SetAccessor */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = undefined;
        node.parameters = createNodeArray(parameters);
        node.body = body;
        return node;
    }
    ts.createSetAccessor = createSetAccessor;
    function updateSetAccessor(node, decorators, modifiers, name, parameters, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.parameters !== parameters
            || node.body !== body
            ? updateNode(createSetAccessor(decorators, modifiers, name, parameters, body), node)
            : node;
    }
    ts.updateSetAccessor = updateSetAccessor;
    function createCallSignature(typeParameters, parameters, type) {
        return createSignatureDeclaration(165 /* CallSignature */, typeParameters, parameters, type);
    }
    ts.createCallSignature = createCallSignature;
    function updateCallSignature(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateCallSignature = updateCallSignature;
    function createConstructSignature(typeParameters, parameters, type) {
        return createSignatureDeclaration(166 /* ConstructSignature */, typeParameters, parameters, type);
    }
    ts.createConstructSignature = createConstructSignature;
    function updateConstructSignature(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateConstructSignature = updateConstructSignature;
    function createIndexSignature(decorators, modifiers, parameters, type) {
        var node = createSynthesizedNode(167 /* IndexSignature */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        return node;
    }
    ts.createIndexSignature = createIndexSignature;
    function updateIndexSignature(node, decorators, modifiers, parameters, type) {
        return node.parameters !== parameters
            || node.type !== type
            || node.decorators !== decorators
            || node.modifiers !== modifiers
            ? updateNode(createIndexSignature(decorators, modifiers, parameters, type), node)
            : node;
    }
    ts.updateIndexSignature = updateIndexSignature;
    /* @internal */
    function createSignatureDeclaration(kind, typeParameters, parameters, type, typeArguments) {
        var node = createSynthesizedNode(kind);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = asNodeArray(parameters);
        node.type = type;
        node.typeArguments = asNodeArray(typeArguments);
        return node;
    }
    ts.createSignatureDeclaration = createSignatureDeclaration;
    function updateSignatureDeclaration(node, typeParameters, parameters, type) {
        return node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
            : node;
    }
    // Types
    function createKeywordTypeNode(kind) {
        return createSynthesizedNode(kind);
    }
    ts.createKeywordTypeNode = createKeywordTypeNode;
    function createTypePredicateNode(parameterName, type) {
        return createTypePredicateNodeWithModifier(/*assertsModifier*/ undefined, parameterName, type);
    }
    ts.createTypePredicateNode = createTypePredicateNode;
    function createTypePredicateNodeWithModifier(assertsModifier, parameterName, type) {
        var node = createSynthesizedNode(168 /* TypePredicate */);
        node.assertsModifier = assertsModifier;
        node.parameterName = asName(parameterName);
        node.type = type;
        return node;
    }
    ts.createTypePredicateNodeWithModifier = createTypePredicateNodeWithModifier;
    function updateTypePredicateNode(node, parameterName, type) {
        return updateTypePredicateNodeWithModifier(node, node.assertsModifier, parameterName, type);
    }
    ts.updateTypePredicateNode = updateTypePredicateNode;
    function updateTypePredicateNodeWithModifier(node, assertsModifier, parameterName, type) {
        return node.assertsModifier !== assertsModifier
            || node.parameterName !== parameterName
            || node.type !== type
            ? updateNode(createTypePredicateNodeWithModifier(assertsModifier, parameterName, type), node)
            : node;
    }
    ts.updateTypePredicateNodeWithModifier = updateTypePredicateNodeWithModifier;
    function createTypeReferenceNode(typeName, typeArguments) {
        var node = createSynthesizedNode(169 /* TypeReference */);
        node.typeName = asName(typeName);
        node.typeArguments = typeArguments && ts.parenthesizeTypeParameters(typeArguments);
        return node;
    }
    ts.createTypeReferenceNode = createTypeReferenceNode;
    function updateTypeReferenceNode(node, typeName, typeArguments) {
        return node.typeName !== typeName
            || node.typeArguments !== typeArguments
            ? updateNode(createTypeReferenceNode(typeName, typeArguments), node)
            : node;
    }
    ts.updateTypeReferenceNode = updateTypeReferenceNode;
    function createFunctionTypeNode(typeParameters, parameters, type) {
        return createSignatureDeclaration(170 /* FunctionType */, typeParameters, parameters, type);
    }
    ts.createFunctionTypeNode = createFunctionTypeNode;
    function updateFunctionTypeNode(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateFunctionTypeNode = updateFunctionTypeNode;
    function createConstructorTypeNode(typeParameters, parameters, type) {
        return createSignatureDeclaration(171 /* ConstructorType */, typeParameters, parameters, type);
    }
    ts.createConstructorTypeNode = createConstructorTypeNode;
    function updateConstructorTypeNode(node, typeParameters, parameters, type) {
        return updateSignatureDeclaration(node, typeParameters, parameters, type);
    }
    ts.updateConstructorTypeNode = updateConstructorTypeNode;
    function createTypeQueryNode(exprName) {
        var node = createSynthesizedNode(172 /* TypeQuery */);
        node.exprName = exprName;
        return node;
    }
    ts.createTypeQueryNode = createTypeQueryNode;
    function updateTypeQueryNode(node, exprName) {
        return node.exprName !== exprName
            ? updateNode(createTypeQueryNode(exprName), node)
            : node;
    }
    ts.updateTypeQueryNode = updateTypeQueryNode;
    function createTypeLiteralNode(members) {
        var node = createSynthesizedNode(173 /* TypeLiteral */);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createTypeLiteralNode = createTypeLiteralNode;
    function updateTypeLiteralNode(node, members) {
        return node.members !== members
            ? updateNode(createTypeLiteralNode(members), node)
            : node;
    }
    ts.updateTypeLiteralNode = updateTypeLiteralNode;
    function createArrayTypeNode(elementType) {
        var node = createSynthesizedNode(174 /* ArrayType */);
        node.elementType = ts.parenthesizeArrayTypeMember(elementType);
        return node;
    }
    ts.createArrayTypeNode = createArrayTypeNode;
    function updateArrayTypeNode(node, elementType) {
        return node.elementType !== elementType
            ? updateNode(createArrayTypeNode(elementType), node)
            : node;
    }
    ts.updateArrayTypeNode = updateArrayTypeNode;
    function createTupleTypeNode(elementTypes) {
        var node = createSynthesizedNode(175 /* TupleType */);
        node.elementTypes = createNodeArray(elementTypes);
        return node;
    }
    ts.createTupleTypeNode = createTupleTypeNode;
    function updateTupleTypeNode(node, elementTypes) {
        return node.elementTypes !== elementTypes
            ? updateNode(createTupleTypeNode(elementTypes), node)
            : node;
    }
    ts.updateTupleTypeNode = updateTupleTypeNode;
    function createOptionalTypeNode(type) {
        var node = createSynthesizedNode(176 /* OptionalType */);
        node.type = ts.parenthesizeArrayTypeMember(type);
        return node;
    }
    ts.createOptionalTypeNode = createOptionalTypeNode;
    function updateOptionalTypeNode(node, type) {
        return node.type !== type
            ? updateNode(createOptionalTypeNode(type), node)
            : node;
    }
    ts.updateOptionalTypeNode = updateOptionalTypeNode;
    function createRestTypeNode(type) {
        var node = createSynthesizedNode(177 /* RestType */);
        node.type = type;
        return node;
    }
    ts.createRestTypeNode = createRestTypeNode;
    function updateRestTypeNode(node, type) {
        return node.type !== type
            ? updateNode(createRestTypeNode(type), node)
            : node;
    }
    ts.updateRestTypeNode = updateRestTypeNode;
    function createUnionTypeNode(types) {
        return createUnionOrIntersectionTypeNode(178 /* UnionType */, types);
    }
    ts.createUnionTypeNode = createUnionTypeNode;
    function updateUnionTypeNode(node, types) {
        return updateUnionOrIntersectionTypeNode(node, types);
    }
    ts.updateUnionTypeNode = updateUnionTypeNode;
    function createIntersectionTypeNode(types) {
        return createUnionOrIntersectionTypeNode(179 /* IntersectionType */, types);
    }
    ts.createIntersectionTypeNode = createIntersectionTypeNode;
    function updateIntersectionTypeNode(node, types) {
        return updateUnionOrIntersectionTypeNode(node, types);
    }
    ts.updateIntersectionTypeNode = updateIntersectionTypeNode;
    function createUnionOrIntersectionTypeNode(kind, types) {
        var node = createSynthesizedNode(kind);
        node.types = ts.parenthesizeElementTypeMembers(types);
        return node;
    }
    ts.createUnionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode;
    function updateUnionOrIntersectionTypeNode(node, types) {
        return node.types !== types
            ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node)
            : node;
    }
    function createConditionalTypeNode(checkType, extendsType, trueType, falseType) {
        var node = createSynthesizedNode(180 /* ConditionalType */);
        node.checkType = ts.parenthesizeConditionalTypeMember(checkType);
        node.extendsType = ts.parenthesizeConditionalTypeMember(extendsType);
        node.trueType = trueType;
        node.falseType = falseType;
        return node;
    }
    ts.createConditionalTypeNode = createConditionalTypeNode;
    function updateConditionalTypeNode(node, checkType, extendsType, trueType, falseType) {
        return node.checkType !== checkType
            || node.extendsType !== extendsType
            || node.trueType !== trueType
            || node.falseType !== falseType
            ? updateNode(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node)
            : node;
    }
    ts.updateConditionalTypeNode = updateConditionalTypeNode;
    function createInferTypeNode(typeParameter) {
        var node = createSynthesizedNode(181 /* InferType */);
        node.typeParameter = typeParameter;
        return node;
    }
    ts.createInferTypeNode = createInferTypeNode;
    function updateInferTypeNode(node, typeParameter) {
        return node.typeParameter !== typeParameter
            ? updateNode(createInferTypeNode(typeParameter), node)
            : node;
    }
    ts.updateInferTypeNode = updateInferTypeNode;
    function createImportTypeNode(argument, qualifier, typeArguments, isTypeOf) {
        var node = createSynthesizedNode(188 /* ImportType */);
        node.argument = argument;
        node.qualifier = qualifier;
        node.typeArguments = ts.parenthesizeTypeParameters(typeArguments);
        node.isTypeOf = isTypeOf;
        return node;
    }
    ts.createImportTypeNode = createImportTypeNode;
    function updateImportTypeNode(node, argument, qualifier, typeArguments, isTypeOf) {
        return node.argument !== argument
            || node.qualifier !== qualifier
            || node.typeArguments !== typeArguments
            || node.isTypeOf !== isTypeOf
            ? updateNode(createImportTypeNode(argument, qualifier, typeArguments, isTypeOf), node)
            : node;
    }
    ts.updateImportTypeNode = updateImportTypeNode;
    function createParenthesizedType(type) {
        var node = createSynthesizedNode(182 /* ParenthesizedType */);
        node.type = type;
        return node;
    }
    ts.createParenthesizedType = createParenthesizedType;
    function updateParenthesizedType(node, type) {
        return node.type !== type
            ? updateNode(createParenthesizedType(type), node)
            : node;
    }
    ts.updateParenthesizedType = updateParenthesizedType;
    function createThisTypeNode() {
        return createSynthesizedNode(183 /* ThisType */);
    }
    ts.createThisTypeNode = createThisTypeNode;
    function createTypeOperatorNode(operatorOrType, type) {
        var node = createSynthesizedNode(184 /* TypeOperator */);
        node.operator = typeof operatorOrType === "number" ? operatorOrType : 134 /* KeyOfKeyword */;
        node.type = ts.parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type : operatorOrType);
        return node;
    }
    ts.createTypeOperatorNode = createTypeOperatorNode;
    function updateTypeOperatorNode(node, type) {
        return node.type !== type ? updateNode(createTypeOperatorNode(node.operator, type), node) : node;
    }
    ts.updateTypeOperatorNode = updateTypeOperatorNode;
    function createIndexedAccessTypeNode(objectType, indexType) {
        var node = createSynthesizedNode(185 /* IndexedAccessType */);
        node.objectType = ts.parenthesizeElementTypeMember(objectType);
        node.indexType = indexType;
        return node;
    }
    ts.createIndexedAccessTypeNode = createIndexedAccessTypeNode;
    function updateIndexedAccessTypeNode(node, objectType, indexType) {
        return node.objectType !== objectType
            || node.indexType !== indexType
            ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node)
            : node;
    }
    ts.updateIndexedAccessTypeNode = updateIndexedAccessTypeNode;
    function createMappedTypeNode(readonlyToken, typeParameter, questionToken, type) {
        var node = createSynthesizedNode(186 /* MappedType */);
        node.readonlyToken = readonlyToken;
        node.typeParameter = typeParameter;
        node.questionToken = questionToken;
        node.type = type;
        return node;
    }
    ts.createMappedTypeNode = createMappedTypeNode;
    function updateMappedTypeNode(node, readonlyToken, typeParameter, questionToken, type) {
        return node.readonlyToken !== readonlyToken
            || node.typeParameter !== typeParameter
            || node.questionToken !== questionToken
            || node.type !== type
            ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node)
            : node;
    }
    ts.updateMappedTypeNode = updateMappedTypeNode;
    function createLiteralTypeNode(literal) {
        var node = createSynthesizedNode(187 /* LiteralType */);
        node.literal = literal;
        return node;
    }
    ts.createLiteralTypeNode = createLiteralTypeNode;
    function updateLiteralTypeNode(node, literal) {
        return node.literal !== literal
            ? updateNode(createLiteralTypeNode(literal), node)
            : node;
    }
    ts.updateLiteralTypeNode = updateLiteralTypeNode;
    // Binding Patterns
    function createObjectBindingPattern(elements) {
        var node = createSynthesizedNode(189 /* ObjectBindingPattern */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createObjectBindingPattern = createObjectBindingPattern;
    function updateObjectBindingPattern(node, elements) {
        return node.elements !== elements
            ? updateNode(createObjectBindingPattern(elements), node)
            : node;
    }
    ts.updateObjectBindingPattern = updateObjectBindingPattern;
    function createArrayBindingPattern(elements) {
        var node = createSynthesizedNode(190 /* ArrayBindingPattern */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createArrayBindingPattern = createArrayBindingPattern;
    function updateArrayBindingPattern(node, elements) {
        return node.elements !== elements
            ? updateNode(createArrayBindingPattern(elements), node)
            : node;
    }
    ts.updateArrayBindingPattern = updateArrayBindingPattern;
    function createBindingElement(dotDotDotToken, propertyName, name, initializer) {
        var node = createSynthesizedNode(191 /* BindingElement */);
        node.dotDotDotToken = dotDotDotToken;
        node.propertyName = asName(propertyName);
        node.name = asName(name);
        node.initializer = initializer;
        return node;
    }
    ts.createBindingElement = createBindingElement;
    function updateBindingElement(node, dotDotDotToken, propertyName, name, initializer) {
        return node.propertyName !== propertyName
            || node.dotDotDotToken !== dotDotDotToken
            || node.name !== name
            || node.initializer !== initializer
            ? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node)
            : node;
    }
    ts.updateBindingElement = updateBindingElement;
    // Expression
    function createArrayLiteral(elements, multiLine) {
        var node = createSynthesizedNode(192 /* ArrayLiteralExpression */);
        node.elements = ts.parenthesizeListElements(createNodeArray(elements));
        if (multiLine)
            node.multiLine = true;
        return node;
    }
    ts.createArrayLiteral = createArrayLiteral;
    function updateArrayLiteral(node, elements) {
        return node.elements !== elements
            ? updateNode(createArrayLiteral(elements, node.multiLine), node)
            : node;
    }
    ts.updateArrayLiteral = updateArrayLiteral;
    function createObjectLiteral(properties, multiLine) {
        var node = createSynthesizedNode(193 /* ObjectLiteralExpression */);
        node.properties = createNodeArray(properties);
        if (multiLine)
            node.multiLine = true;
        return node;
    }
    ts.createObjectLiteral = createObjectLiteral;
    function updateObjectLiteral(node, properties) {
        return node.properties !== properties
            ? updateNode(createObjectLiteral(properties, node.multiLine), node)
            : node;
    }
    ts.updateObjectLiteral = updateObjectLiteral;
    function createPropertyAccess(expression, name) {
        var node = createSynthesizedNode(194 /* PropertyAccessExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.name = asName(name);
        setEmitFlags(node, 131072 /* NoIndentation */);
        return node;
    }
    ts.createPropertyAccess = createPropertyAccess;
    function updatePropertyAccess(node, expression, name) {
        if (ts.isPropertyAccessChain(node)) {
            return updatePropertyAccessChain(node, expression, node.questionDotToken, ts.cast(name, ts.isIdentifier));
        }
        // Because we are updating existed propertyAccess we want to inherit its emitFlags
        // instead of using the default from createPropertyAccess
        return node.expression !== expression
            || node.name !== name
            ? updateNode(setEmitFlags(createPropertyAccess(expression, name), ts.getEmitFlags(node)), node)
            : node;
    }
    ts.updatePropertyAccess = updatePropertyAccess;
    function createPropertyAccessChain(expression, questionDotToken, name) {
        var node = createSynthesizedNode(194 /* PropertyAccessExpression */);
        node.flags |= 32 /* OptionalChain */;
        node.expression = ts.parenthesizeForAccess(expression);
        node.questionDotToken = questionDotToken;
        node.name = asName(name);
        setEmitFlags(node, 131072 /* NoIndentation */);
        return node;
    }
    ts.createPropertyAccessChain = createPropertyAccessChain;
    function updatePropertyAccessChain(node, expression, questionDotToken, name) {
        ts.Debug.assert(!!(node.flags & 32 /* OptionalChain */), "Cannot update a PropertyAccessExpression using updatePropertyAccessChain. Use updatePropertyAccess instead.");
        // Because we are updating an existing PropertyAccessChain we want to inherit its emitFlags
        // instead of using the default from createPropertyAccess
        return node.expression !== expression
            || node.questionDotToken !== questionDotToken
            || node.name !== name
            ? updateNode(setEmitFlags(createPropertyAccessChain(expression, questionDotToken, name), ts.getEmitFlags(node)), node)
            : node;
    }
    ts.updatePropertyAccessChain = updatePropertyAccessChain;
    function createElementAccess(expression, index) {
        var node = createSynthesizedNode(195 /* ElementAccessExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.argumentExpression = asExpression(index);
        return node;
    }
    ts.createElementAccess = createElementAccess;
    function updateElementAccess(node, expression, argumentExpression) {
        if (ts.isOptionalChain(node)) {
            return updateElementAccessChain(node, expression, node.questionDotToken, argumentExpression);
        }
        return node.expression !== expression
            || node.argumentExpression !== argumentExpression
            ? updateNode(createElementAccess(expression, argumentExpression), node)
            : node;
    }
    ts.updateElementAccess = updateElementAccess;
    function createElementAccessChain(expression, questionDotToken, index) {
        var node = createSynthesizedNode(195 /* ElementAccessExpression */);
        node.flags |= 32 /* OptionalChain */;
        node.expression = ts.parenthesizeForAccess(expression);
        node.questionDotToken = questionDotToken;
        node.argumentExpression = asExpression(index);
        return node;
    }
    ts.createElementAccessChain = createElementAccessChain;
    function updateElementAccessChain(node, expression, questionDotToken, argumentExpression) {
        ts.Debug.assert(!!(node.flags & 32 /* OptionalChain */), "Cannot update an ElementAccessExpression using updateElementAccessChain. Use updateElementAccess instead.");
        return node.expression !== expression
            || node.questionDotToken !== questionDotToken
            || node.argumentExpression !== argumentExpression
            ? updateNode(createElementAccessChain(expression, questionDotToken, argumentExpression), node)
            : node;
    }
    ts.updateElementAccessChain = updateElementAccessChain;
    function createCall(expression, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(196 /* CallExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = ts.parenthesizeListElements(createNodeArray(argumentsArray));
        return node;
    }
    ts.createCall = createCall;
    function updateCall(node, expression, typeArguments, argumentsArray) {
        if (ts.isOptionalChain(node)) {
            return updateCallChain(node, expression, node.questionDotToken, typeArguments, argumentsArray);
        }
        return node.expression !== expression
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createCall(expression, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateCall = updateCall;
    function createCallChain(expression, questionDotToken, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(196 /* CallExpression */);
        node.flags |= 32 /* OptionalChain */;
        node.expression = ts.parenthesizeForAccess(expression);
        node.questionDotToken = questionDotToken;
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = ts.parenthesizeListElements(createNodeArray(argumentsArray));
        return node;
    }
    ts.createCallChain = createCallChain;
    function updateCallChain(node, expression, questionDotToken, typeArguments, argumentsArray) {
        ts.Debug.assert(!!(node.flags & 32 /* OptionalChain */), "Cannot update a CallExpression using updateCallChain. Use updateCall instead.");
        return node.expression !== expression
            || node.questionDotToken !== questionDotToken
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createCallChain(expression, questionDotToken, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateCallChain = updateCallChain;
    function createNew(expression, typeArguments, argumentsArray) {
        var node = createSynthesizedNode(197 /* NewExpression */);
        node.expression = ts.parenthesizeForNew(expression);
        node.typeArguments = asNodeArray(typeArguments);
        node.arguments = argumentsArray ? ts.parenthesizeListElements(createNodeArray(argumentsArray)) : undefined;
        return node;
    }
    ts.createNew = createNew;
    function updateNew(node, expression, typeArguments, argumentsArray) {
        return node.expression !== expression
            || node.typeArguments !== typeArguments
            || node.arguments !== argumentsArray
            ? updateNode(createNew(expression, typeArguments, argumentsArray), node)
            : node;
    }
    ts.updateNew = updateNew;
    function createTaggedTemplate(tag, typeArgumentsOrTemplate, template) {
        var node = createSynthesizedNode(198 /* TaggedTemplateExpression */);
        node.tag = ts.parenthesizeForAccess(tag);
        if (template) {
            node.typeArguments = asNodeArray(typeArgumentsOrTemplate);
            node.template = template;
        }
        else {
            node.typeArguments = undefined;
            node.template = typeArgumentsOrTemplate;
        }
        return node;
    }
    ts.createTaggedTemplate = createTaggedTemplate;
    function updateTaggedTemplate(node, tag, typeArgumentsOrTemplate, template) {
        return node.tag !== tag
            || (template
                ? node.typeArguments !== typeArgumentsOrTemplate || node.template !== template
                : node.typeArguments !== undefined || node.template !== typeArgumentsOrTemplate)
            ? updateNode(createTaggedTemplate(tag, typeArgumentsOrTemplate, template), node)
            : node;
    }
    ts.updateTaggedTemplate = updateTaggedTemplate;
    function createTypeAssertion(type, expression) {
        var node = createSynthesizedNode(199 /* TypeAssertionExpression */);
        node.type = type;
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createTypeAssertion = createTypeAssertion;
    function updateTypeAssertion(node, type, expression) {
        return node.type !== type
            || node.expression !== expression
            ? updateNode(createTypeAssertion(type, expression), node)
            : node;
    }
    ts.updateTypeAssertion = updateTypeAssertion;
    function createParen(expression) {
        var node = createSynthesizedNode(200 /* ParenthesizedExpression */);
        node.expression = expression;
        return node;
    }
    ts.createParen = createParen;
    function updateParen(node, expression) {
        return node.expression !== expression
            ? updateNode(createParen(expression), node)
            : node;
    }
    ts.updateParen = updateParen;
    function createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(201 /* FunctionExpression */);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createFunctionExpression = createFunctionExpression;
    function updateFunctionExpression(node, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        return node.name !== name
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateFunctionExpression = updateFunctionExpression;
    function createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) {
        var node = createSynthesizedNode(202 /* ArrowFunction */);
        node.modifiers = asNodeArray(modifiers);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(38 /* EqualsGreaterThanToken */);
        node.body = ts.parenthesizeConciseBody(body);
        return node;
    }
    ts.createArrowFunction = createArrowFunction;
    function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) {
        return node.modifiers !== modifiers
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.equalsGreaterThanToken !== equalsGreaterThanToken
            || node.body !== body
            ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node)
            : node;
    }
    ts.updateArrowFunction = updateArrowFunction;
    function createDelete(expression) {
        var node = createSynthesizedNode(203 /* DeleteExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createDelete = createDelete;
    function updateDelete(node, expression) {
        return node.expression !== expression
            ? updateNode(createDelete(expression), node)
            : node;
    }
    ts.updateDelete = updateDelete;
    function createTypeOf(expression) {
        var node = createSynthesizedNode(204 /* TypeOfExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createTypeOf = createTypeOf;
    function updateTypeOf(node, expression) {
        return node.expression !== expression
            ? updateNode(createTypeOf(expression), node)
            : node;
    }
    ts.updateTypeOf = updateTypeOf;
    function createVoid(expression) {
        var node = createSynthesizedNode(205 /* VoidExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createVoid = createVoid;
    function updateVoid(node, expression) {
        return node.expression !== expression
            ? updateNode(createVoid(expression), node)
            : node;
    }
    ts.updateVoid = updateVoid;
    function createAwait(expression) {
        var node = createSynthesizedNode(206 /* AwaitExpression */);
        node.expression = ts.parenthesizePrefixOperand(expression);
        return node;
    }
    ts.createAwait = createAwait;
    function updateAwait(node, expression) {
        return node.expression !== expression
            ? updateNode(createAwait(expression), node)
            : node;
    }
    ts.updateAwait = updateAwait;
    function createPrefix(operator, operand) {
        var node = createSynthesizedNode(207 /* PrefixUnaryExpression */);
        node.operator = operator;
        node.operand = ts.parenthesizePrefixOperand(operand);
        return node;
    }
    ts.createPrefix = createPrefix;
    function updatePrefix(node, operand) {
        return node.operand !== operand
            ? updateNode(createPrefix(node.operator, operand), node)
            : node;
    }
    ts.updatePrefix = updatePrefix;
    function createPostfix(operand, operator) {
        var node = createSynthesizedNode(208 /* PostfixUnaryExpression */);
        node.operand = ts.parenthesizePostfixOperand(operand);
        node.operator = operator;
        return node;
    }
    ts.createPostfix = createPostfix;
    function updatePostfix(node, operand) {
        return node.operand !== operand
            ? updateNode(createPostfix(operand, node.operator), node)
            : node;
    }
    ts.updatePostfix = updatePostfix;
    function createBinary(left, operator, right) {
        var node = createSynthesizedNode(209 /* BinaryExpression */);
        var operatorToken = asToken(operator);
        var operatorKind = operatorToken.kind;
        node.left = ts.parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined);
        node.operatorToken = operatorToken;
        node.right = ts.parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left);
        return node;
    }
    ts.createBinary = createBinary;
    function updateBinary(node, left, right, operator) {
        return node.left !== left
            || node.right !== right
            ? updateNode(createBinary(left, operator || node.operatorToken, right), node)
            : node;
    }
    ts.updateBinary = updateBinary;
    function createConditional(condition, questionTokenOrWhenTrue, whenTrueOrWhenFalse, colonToken, whenFalse) {
        var node = createSynthesizedNode(210 /* ConditionalExpression */);
        node.condition = ts.parenthesizeForConditionalHead(condition);
        node.questionToken = whenFalse ? questionTokenOrWhenTrue : createToken(57 /* QuestionToken */);
        node.whenTrue = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : questionTokenOrWhenTrue);
        node.colonToken = whenFalse ? colonToken : createToken(58 /* ColonToken */);
        node.whenFalse = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse);
        return node;
    }
    ts.createConditional = createConditional;
    function updateConditional(node, condition, questionToken, whenTrue, colonToken, whenFalse) {
        return node.condition !== condition
            || node.questionToken !== questionToken
            || node.whenTrue !== whenTrue
            || node.colonToken !== colonToken
            || node.whenFalse !== whenFalse
            ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node)
            : node;
    }
    ts.updateConditional = updateConditional;
    function createTemplateExpression(head, templateSpans) {
        var node = createSynthesizedNode(211 /* TemplateExpression */);
        node.head = head;
        node.templateSpans = createNodeArray(templateSpans);
        return node;
    }
    ts.createTemplateExpression = createTemplateExpression;
    function updateTemplateExpression(node, head, templateSpans) {
        return node.head !== head
            || node.templateSpans !== templateSpans
            ? updateNode(createTemplateExpression(head, templateSpans), node)
            : node;
    }
    ts.updateTemplateExpression = updateTemplateExpression;
    var rawTextScanner;
    var invalidValueSentinel = {};
    function getCookedText(kind, rawText) {
        if (!rawTextScanner) {
            rawTextScanner = ts.createScanner(99 /* Latest */, /*skipTrivia*/ false, 0 /* Standard */);
        }
        switch (kind) {
            case 14 /* NoSubstitutionTemplateLiteral */:
                rawTextScanner.setText("`" + rawText + "`");
                break;
            case 15 /* TemplateHead */:
                rawTextScanner.setText("`" + rawText + "${");
                break;
            case 16 /* TemplateMiddle */:
                rawTextScanner.setText("}" + rawText + "${");
                break;
            case 17 /* TemplateTail */:
                rawTextScanner.setText("}" + rawText + "`");
                break;
        }
        var token = rawTextScanner.scan();
        if (token === 23 /* CloseBracketToken */) {
            token = rawTextScanner.reScanTemplateToken(/* isTaggedTemplate */ false);
        }
        if (rawTextScanner.isUnterminated()) {
            rawTextScanner.setText(undefined);
            return invalidValueSentinel;
        }
        var tokenValue;
        switch (token) {
            case 14 /* NoSubstitutionTemplateLiteral */:
            case 15 /* TemplateHead */:
            case 16 /* TemplateMiddle */:
            case 17 /* TemplateTail */:
                tokenValue = rawTextScanner.getTokenValue();
                break;
        }
        if (rawTextScanner.scan() !== 1 /* EndOfFileToken */) {
            rawTextScanner.setText(undefined);
            return invalidValueSentinel;
        }
        rawTextScanner.setText(undefined);
        return tokenValue;
    }
    function createTemplateLiteralLikeNode(kind, text, rawText) {
        var node = createSynthesizedNode(kind);
        node.text = text;
        if (rawText === undefined || text === rawText) {
            node.rawText = rawText;
        }
        else {
            var cooked = getCookedText(kind, rawText);
            if (typeof cooked === "object") {
                return ts.Debug.fail("Invalid raw text");
            }
            ts.Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'.");
            node.rawText = rawText;
        }
        return node;
    }
    function createTemplateHead(text, rawText) {
        var node = createTemplateLiteralLikeNode(15 /* TemplateHead */, text, rawText);
        node.text = text;
        return node;
    }
    ts.createTemplateHead = createTemplateHead;
    function createTemplateMiddle(text, rawText) {
        var node = createTemplateLiteralLikeNode(16 /* TemplateMiddle */, text, rawText);
        node.text = text;
        return node;
    }
    ts.createTemplateMiddle = createTemplateMiddle;
    function createTemplateTail(text, rawText) {
        var node = createTemplateLiteralLikeNode(17 /* TemplateTail */, text, rawText);
        node.text = text;
        return node;
    }
    ts.createTemplateTail = createTemplateTail;
    function createNoSubstitutionTemplateLiteral(text, rawText) {
        var node = createTemplateLiteralLikeNode(14 /* NoSubstitutionTemplateLiteral */, text, rawText);
        return node;
    }
    ts.createNoSubstitutionTemplateLiteral = createNoSubstitutionTemplateLiteral;
    function createYield(asteriskTokenOrExpression, expression) {
        var asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === 41 /* AsteriskToken */ ? asteriskTokenOrExpression : undefined;
        expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== 41 /* AsteriskToken */ ? asteriskTokenOrExpression : expression;
        var node = createSynthesizedNode(212 /* YieldExpression */);
        node.asteriskToken = asteriskToken;
        node.expression = expression && ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createYield = createYield;
    function updateYield(node, asteriskToken, expression) {
        return node.expression !== expression
            || node.asteriskToken !== asteriskToken
            ? updateNode(createYield(asteriskToken, expression), node)
            : node;
    }
    ts.updateYield = updateYield;
    function createSpread(expression) {
        var node = createSynthesizedNode(213 /* SpreadElement */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createSpread = createSpread;
    function updateSpread(node, expression) {
        return node.expression !== expression
            ? updateNode(createSpread(expression), node)
            : node;
    }
    ts.updateSpread = updateSpread;
    function createClassExpression(modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(214 /* ClassExpression */);
        node.decorators = undefined;
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createClassExpression = createClassExpression;
    function updateClassExpression(node, modifiers, name, typeParameters, heritageClauses, members) {
        return node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateClassExpression = updateClassExpression;
    function createOmittedExpression() {
        return createSynthesizedNode(215 /* OmittedExpression */);
    }
    ts.createOmittedExpression = createOmittedExpression;
    function createExpressionWithTypeArguments(typeArguments, expression) {
        var node = createSynthesizedNode(216 /* ExpressionWithTypeArguments */);
        node.expression = ts.parenthesizeForAccess(expression);
        node.typeArguments = asNodeArray(typeArguments);
        return node;
    }
    ts.createExpressionWithTypeArguments = createExpressionWithTypeArguments;
    function updateExpressionWithTypeArguments(node, typeArguments, expression) {
        return node.typeArguments !== typeArguments
            || node.expression !== expression
            ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node)
            : node;
    }
    ts.updateExpressionWithTypeArguments = updateExpressionWithTypeArguments;
    function createAsExpression(expression, type) {
        var node = createSynthesizedNode(217 /* AsExpression */);
        node.expression = expression;
        node.type = type;
        return node;
    }
    ts.createAsExpression = createAsExpression;
    function updateAsExpression(node, expression, type) {
        return node.expression !== expression
            || node.type !== type
            ? updateNode(createAsExpression(expression, type), node)
            : node;
    }
    ts.updateAsExpression = updateAsExpression;
    function createNonNullExpression(expression) {
        var node = createSynthesizedNode(218 /* NonNullExpression */);
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createNonNullExpression = createNonNullExpression;
    function updateNonNullExpression(node, expression) {
        if (ts.isNonNullChain(node)) {
            return updateNonNullChain(node, expression);
        }
        return node.expression !== expression
            ? updateNode(createNonNullExpression(expression), node)
            : node;
    }
    ts.updateNonNullExpression = updateNonNullExpression;
    function createNonNullChain(expression) {
        var node = createSynthesizedNode(218 /* NonNullExpression */);
        node.flags |= 32 /* OptionalChain */;
        node.expression = ts.parenthesizeForAccess(expression);
        return node;
    }
    ts.createNonNullChain = createNonNullChain;
    function updateNonNullChain(node, expression) {
        ts.Debug.assert(!!(node.flags & 32 /* OptionalChain */), "Cannot update a NonNullExpression using updateNonNullChain. Use updateNonNullExpression instead.");
        return node.expression !== expression
            ? updateNode(createNonNullChain(expression), node)
            : node;
    }
    ts.updateNonNullChain = updateNonNullChain;
    function createMetaProperty(keywordToken, name) {
        var node = createSynthesizedNode(219 /* MetaProperty */);
        node.keywordToken = keywordToken;
        node.name = name;
        return node;
    }
    ts.createMetaProperty = createMetaProperty;
    function updateMetaProperty(node, name) {
        return node.name !== name
            ? updateNode(createMetaProperty(node.keywordToken, name), node)
            : node;
    }
    ts.updateMetaProperty = updateMetaProperty;
    // Misc
    function createTemplateSpan(expression, literal) {
        var node = createSynthesizedNode(221 /* TemplateSpan */);
        node.expression = expression;
        node.literal = literal;
        return node;
    }
    ts.createTemplateSpan = createTemplateSpan;
    function updateTemplateSpan(node, expression, literal) {
        return node.expression !== expression
            || node.literal !== literal
            ? updateNode(createTemplateSpan(expression, literal), node)
            : node;
    }
    ts.updateTemplateSpan = updateTemplateSpan;
    function createSemicolonClassElement() {
        return createSynthesizedNode(222 /* SemicolonClassElement */);
    }
    ts.createSemicolonClassElement = createSemicolonClassElement;
    // Element
    function createBlock(statements, multiLine) {
        var block = createSynthesizedNode(223 /* Block */);
        block.statements = createNodeArray(statements);
        if (multiLine)
            block.multiLine = multiLine;
        return block;
    }
    ts.createBlock = createBlock;
    function updateBlock(node, statements) {
        return node.statements !== statements
            ? updateNode(createBlock(statements, node.multiLine), node)
            : node;
    }
    ts.updateBlock = updateBlock;
    function createVariableStatement(modifiers, declarationList) {
        var node = createSynthesizedNode(225 /* VariableStatement */);
        node.decorators = undefined;
        node.modifiers = asNodeArray(modifiers);
        node.declarationList = ts.isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList;
        return node;
    }
    ts.createVariableStatement = createVariableStatement;
    function updateVariableStatement(node, modifiers, declarationList) {
        return node.modifiers !== modifiers
            || node.declarationList !== declarationList
            ? updateNode(createVariableStatement(modifiers, declarationList), node)
            : node;
    }
    ts.updateVariableStatement = updateVariableStatement;
    function createEmptyStatement() {
        return createSynthesizedNode(224 /* EmptyStatement */);
    }
    ts.createEmptyStatement = createEmptyStatement;
    function createExpressionStatement(expression) {
        var node = createSynthesizedNode(226 /* ExpressionStatement */);
        node.expression = ts.parenthesizeExpressionForExpressionStatement(expression);
        return node;
    }
    ts.createExpressionStatement = createExpressionStatement;
    function updateExpressionStatement(node, expression) {
        return node.expression !== expression
            ? updateNode(createExpressionStatement(expression), node)
            : node;
    }
    ts.updateExpressionStatement = updateExpressionStatement;
    /** @deprecated Use `createExpressionStatement` instead.  */
    ts.createStatement = createExpressionStatement;
    /** @deprecated Use `updateExpressionStatement` instead.  */
    ts.updateStatement = updateExpressionStatement;
    function createIf(expression, thenStatement, elseStatement) {
        var node = createSynthesizedNode(227 /* IfStatement */);
        node.expression = expression;
        node.thenStatement = asEmbeddedStatement(thenStatement);
        node.elseStatement = asEmbeddedStatement(elseStatement);
        return node;
    }
    ts.createIf = createIf;
    function updateIf(node, expression, thenStatement, elseStatement) {
        return node.expression !== expression
            || node.thenStatement !== thenStatement
            || node.elseStatement !== elseStatement
            ? updateNode(createIf(expression, thenStatement, elseStatement), node)
            : node;
    }
    ts.updateIf = updateIf;
    function createDo(statement, expression) {
        var node = createSynthesizedNode(228 /* DoStatement */);
        node.statement = asEmbeddedStatement(statement);
        node.expression = expression;
        return node;
    }
    ts.createDo = createDo;
    function updateDo(node, statement, expression) {
        return node.statement !== statement
            || node.expression !== expression
            ? updateNode(createDo(statement, expression), node)
            : node;
    }
    ts.updateDo = updateDo;
    function createWhile(expression, statement) {
        var node = createSynthesizedNode(229 /* WhileStatement */);
        node.expression = expression;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createWhile = createWhile;
    function updateWhile(node, expression, statement) {
        return node.expression !== expression
            || node.statement !== statement
            ? updateNode(createWhile(expression, statement), node)
            : node;
    }
    ts.updateWhile = updateWhile;
    function createFor(initializer, condition, incrementor, statement) {
        var node = createSynthesizedNode(230 /* ForStatement */);
        node.initializer = initializer;
        node.condition = condition;
        node.incrementor = incrementor;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createFor = createFor;
    function updateFor(node, initializer, condition, incrementor, statement) {
        return node.initializer !== initializer
            || node.condition !== condition
            || node.incrementor !== incrementor
            || node.statement !== statement
            ? updateNode(createFor(initializer, condition, incrementor, statement), node)
            : node;
    }
    ts.updateFor = updateFor;
    function createForIn(initializer, expression, statement) {
        var node = createSynthesizedNode(231 /* ForInStatement */);
        node.initializer = initializer;
        node.expression = expression;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createForIn = createForIn;
    function updateForIn(node, initializer, expression, statement) {
        return node.initializer !== initializer
            || node.expression !== expression
            || node.statement !== statement
            ? updateNode(createForIn(initializer, expression, statement), node)
            : node;
    }
    ts.updateForIn = updateForIn;
    function createForOf(awaitModifier, initializer, expression, statement) {
        var node = createSynthesizedNode(232 /* ForOfStatement */);
        node.awaitModifier = awaitModifier;
        node.initializer = initializer;
        node.expression = ts.isCommaSequence(expression) ? createParen(expression) : expression;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createForOf = createForOf;
    function updateForOf(node, awaitModifier, initializer, expression, statement) {
        return node.awaitModifier !== awaitModifier
            || node.initializer !== initializer
            || node.expression !== expression
            || node.statement !== statement
            ? updateNode(createForOf(awaitModifier, initializer, expression, statement), node)
            : node;
    }
    ts.updateForOf = updateForOf;
    function createContinue(label) {
        var node = createSynthesizedNode(233 /* ContinueStatement */);
        node.label = asName(label);
        return node;
    }
    ts.createContinue = createContinue;
    function updateContinue(node, label) {
        return node.label !== label
            ? updateNode(createContinue(label), node)
            : node;
    }
    ts.updateContinue = updateContinue;
    function createBreak(label) {
        var node = createSynthesizedNode(234 /* BreakStatement */);
        node.label = asName(label);
        return node;
    }
    ts.createBreak = createBreak;
    function updateBreak(node, label) {
        return node.label !== label
            ? updateNode(createBreak(label), node)
            : node;
    }
    ts.updateBreak = updateBreak;
    function createReturn(expression) {
        var node = createSynthesizedNode(235 /* ReturnStatement */);
        node.expression = expression;
        return node;
    }
    ts.createReturn = createReturn;
    function updateReturn(node, expression) {
        return node.expression !== expression
            ? updateNode(createReturn(expression), node)
            : node;
    }
    ts.updateReturn = updateReturn;
    function createWith(expression, statement) {
        var node = createSynthesizedNode(236 /* WithStatement */);
        node.expression = expression;
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createWith = createWith;
    function updateWith(node, expression, statement) {
        return node.expression !== expression
            || node.statement !== statement
            ? updateNode(createWith(expression, statement), node)
            : node;
    }
    ts.updateWith = updateWith;
    function createSwitch(expression, caseBlock) {
        var node = createSynthesizedNode(237 /* SwitchStatement */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        node.caseBlock = caseBlock;
        return node;
    }
    ts.createSwitch = createSwitch;
    function updateSwitch(node, expression, caseBlock) {
        return node.expression !== expression
            || node.caseBlock !== caseBlock
            ? updateNode(createSwitch(expression, caseBlock), node)
            : node;
    }
    ts.updateSwitch = updateSwitch;
    function createLabel(label, statement) {
        var node = createSynthesizedNode(238 /* LabeledStatement */);
        node.label = asName(label);
        node.statement = asEmbeddedStatement(statement);
        return node;
    }
    ts.createLabel = createLabel;
    function updateLabel(node, label, statement) {
        return node.label !== label
            || node.statement !== statement
            ? updateNode(createLabel(label, statement), node)
            : node;
    }
    ts.updateLabel = updateLabel;
    function createThrow(expression) {
        var node = createSynthesizedNode(239 /* ThrowStatement */);
        node.expression = expression;
        return node;
    }
    ts.createThrow = createThrow;
    function updateThrow(node, expression) {
        return node.expression !== expression
            ? updateNode(createThrow(expression), node)
            : node;
    }
    ts.updateThrow = updateThrow;
    function createTry(tryBlock, catchClause, finallyBlock) {
        var node = createSynthesizedNode(240 /* TryStatement */);
        node.tryBlock = tryBlock;
        node.catchClause = catchClause;
        node.finallyBlock = finallyBlock;
        return node;
    }
    ts.createTry = createTry;
    function updateTry(node, tryBlock, catchClause, finallyBlock) {
        return node.tryBlock !== tryBlock
            || node.catchClause !== catchClause
            || node.finallyBlock !== finallyBlock
            ? updateNode(createTry(tryBlock, catchClause, finallyBlock), node)
            : node;
    }
    ts.updateTry = updateTry;
    function createDebuggerStatement() {
        return createSynthesizedNode(241 /* DebuggerStatement */);
    }
    ts.createDebuggerStatement = createDebuggerStatement;
    function createVariableDeclaration(name, type, initializer) {
        /* Internally, one should probably use createTypeScriptVariableDeclaration instead and handle definite assignment assertions */
        var node = createSynthesizedNode(242 /* VariableDeclaration */);
        node.name = asName(name);
        node.type = type;
        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
        return node;
    }
    ts.createVariableDeclaration = createVariableDeclaration;
    function updateVariableDeclaration(node, name, type, initializer) {
        /* Internally, one should probably use updateTypeScriptVariableDeclaration instead and handle definite assignment assertions */
        return node.name !== name
            || node.type !== type
            || node.initializer !== initializer
            ? updateNode(createVariableDeclaration(name, type, initializer), node)
            : node;
    }
    ts.updateVariableDeclaration = updateVariableDeclaration;
    /* @internal */
    function createTypeScriptVariableDeclaration(name, exclaimationToken, type, initializer) {
        var node = createSynthesizedNode(242 /* VariableDeclaration */);
        node.name = asName(name);
        node.type = type;
        node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined;
        node.exclamationToken = exclaimationToken;
        return node;
    }
    ts.createTypeScriptVariableDeclaration = createTypeScriptVariableDeclaration;
    /* @internal */
    function updateTypeScriptVariableDeclaration(node, name, exclaimationToken, type, initializer) {
        return node.name !== name
            || node.type !== type
            || node.initializer !== initializer
            || node.exclamationToken !== exclaimationToken
            ? updateNode(createTypeScriptVariableDeclaration(name, exclaimationToken, type, initializer), node)
            : node;
    }
    ts.updateTypeScriptVariableDeclaration = updateTypeScriptVariableDeclaration;
    function createVariableDeclarationList(declarations, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        var node = createSynthesizedNode(243 /* VariableDeclarationList */);
        node.flags |= flags & 3 /* BlockScoped */;
        node.declarations = createNodeArray(declarations);
        return node;
    }
    ts.createVariableDeclarationList = createVariableDeclarationList;
    function updateVariableDeclarationList(node, declarations) {
        return node.declarations !== declarations
            ? updateNode(createVariableDeclarationList(declarations, node.flags), node)
            : node;
    }
    ts.updateVariableDeclarationList = updateVariableDeclarationList;
    function createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        var node = createSynthesizedNode(244 /* FunctionDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.asteriskToken = asteriskToken;
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.parameters = createNodeArray(parameters);
        node.type = type;
        node.body = body;
        return node;
    }
    ts.createFunctionDeclaration = createFunctionDeclaration;
    function updateFunctionDeclaration(node, decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.asteriskToken !== asteriskToken
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.parameters !== parameters
            || node.type !== type
            || node.body !== body
            ? updateNode(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
            : node;
    }
    ts.updateFunctionDeclaration = updateFunctionDeclaration;
    /* @internal */
    function updateFunctionLikeBody(declaration, body) {
        switch (declaration.kind) {
            case 244 /* FunctionDeclaration */:
                return createFunctionDeclaration(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body);
            case 161 /* MethodDeclaration */:
                return createMethod(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.questionToken, declaration.typeParameters, declaration.parameters, declaration.type, body);
            case 163 /* GetAccessor */:
                return createGetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, declaration.type, body);
            case 164 /* SetAccessor */:
                return createSetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, body);
            case 162 /* Constructor */:
                return createConstructor(declaration.decorators, declaration.modifiers, declaration.parameters, body);
            case 201 /* FunctionExpression */:
                return createFunctionExpression(declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body);
            case 202 /* ArrowFunction */:
                return createArrowFunction(declaration.modifiers, declaration.typeParameters, declaration.parameters, declaration.type, declaration.equalsGreaterThanToken, body);
        }
    }
    ts.updateFunctionLikeBody = updateFunctionLikeBody;
    function createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(245 /* ClassDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createClassDeclaration = createClassDeclaration;
    function updateClassDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateClassDeclaration = updateClassDeclaration;
    function createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) {
        var node = createSynthesizedNode(246 /* InterfaceDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.heritageClauses = asNodeArray(heritageClauses);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createInterfaceDeclaration = createInterfaceDeclaration;
    function updateInterfaceDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.heritageClauses !== heritageClauses
            || node.members !== members
            ? updateNode(createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node)
            : node;
    }
    ts.updateInterfaceDeclaration = updateInterfaceDeclaration;
    function createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type) {
        var node = createSynthesizedNode(247 /* TypeAliasDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.typeParameters = asNodeArray(typeParameters);
        node.type = type;
        return node;
    }
    ts.createTypeAliasDeclaration = createTypeAliasDeclaration;
    function updateTypeAliasDeclaration(node, decorators, modifiers, name, typeParameters, type) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.typeParameters !== typeParameters
            || node.type !== type
            ? updateNode(createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type), node)
            : node;
    }
    ts.updateTypeAliasDeclaration = updateTypeAliasDeclaration;
    function createEnumDeclaration(decorators, modifiers, name, members) {
        var node = createSynthesizedNode(248 /* EnumDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.members = createNodeArray(members);
        return node;
    }
    ts.createEnumDeclaration = createEnumDeclaration;
    function updateEnumDeclaration(node, decorators, modifiers, name, members) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.members !== members
            ? updateNode(createEnumDeclaration(decorators, modifiers, name, members), node)
            : node;
    }
    ts.updateEnumDeclaration = updateEnumDeclaration;
    function createModuleDeclaration(decorators, modifiers, name, body, flags) {
        if (flags === void 0) { flags = 0 /* None */; }
        var node = createSynthesizedNode(249 /* ModuleDeclaration */);
        node.flags |= flags & (16 /* Namespace */ | 4 /* NestedNamespace */ | 1024 /* GlobalAugmentation */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = name;
        node.body = body;
        return node;
    }
    ts.createModuleDeclaration = createModuleDeclaration;
    function updateModuleDeclaration(node, decorators, modifiers, name, body) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.body !== body
            ? updateNode(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node)
            : node;
    }
    ts.updateModuleDeclaration = updateModuleDeclaration;
    function createModuleBlock(statements) {
        var node = createSynthesizedNode(250 /* ModuleBlock */);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createModuleBlock = createModuleBlock;
    function updateModuleBlock(node, statements) {
        return node.statements !== statements
            ? updateNode(createModuleBlock(statements), node)
            : node;
    }
    ts.updateModuleBlock = updateModuleBlock;
    function createCaseBlock(clauses) {
        var node = createSynthesizedNode(251 /* CaseBlock */);
        node.clauses = createNodeArray(clauses);
        return node;
    }
    ts.createCaseBlock = createCaseBlock;
    function updateCaseBlock(node, clauses) {
        return node.clauses !== clauses
            ? updateNode(createCaseBlock(clauses), node)
            : node;
    }
    ts.updateCaseBlock = updateCaseBlock;
    function createNamespaceExportDeclaration(name) {
        var node = createSynthesizedNode(252 /* NamespaceExportDeclaration */);
        node.name = asName(name);
        return node;
    }
    ts.createNamespaceExportDeclaration = createNamespaceExportDeclaration;
    function updateNamespaceExportDeclaration(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceExportDeclaration(name), node)
            : node;
    }
    ts.updateNamespaceExportDeclaration = updateNamespaceExportDeclaration;
    function createImportEqualsDeclaration(decorators, modifiers, name, moduleReference) {
        var node = createSynthesizedNode(253 /* ImportEqualsDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.name = asName(name);
        node.moduleReference = moduleReference;
        return node;
    }
    ts.createImportEqualsDeclaration = createImportEqualsDeclaration;
    function updateImportEqualsDeclaration(node, decorators, modifiers, name, moduleReference) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.name !== name
            || node.moduleReference !== moduleReference
            ? updateNode(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node)
            : node;
    }
    ts.updateImportEqualsDeclaration = updateImportEqualsDeclaration;
    function createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier) {
        var node = createSynthesizedNode(254 /* ImportDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.importClause = importClause;
        node.moduleSpecifier = moduleSpecifier;
        return node;
    }
    ts.createImportDeclaration = createImportDeclaration;
    function updateImportDeclaration(node, decorators, modifiers, importClause, moduleSpecifier) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.importClause !== importClause
            || node.moduleSpecifier !== moduleSpecifier
            ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node)
            : node;
    }
    ts.updateImportDeclaration = updateImportDeclaration;
    function createImportClause(name, namedBindings, isTypeOnly) {
        if (isTypeOnly === void 0) { isTypeOnly = false; }
        var node = createSynthesizedNode(255 /* ImportClause */);
        node.name = name;
        node.namedBindings = namedBindings;
        node.isTypeOnly = isTypeOnly;
        return node;
    }
    ts.createImportClause = createImportClause;
    function updateImportClause(node, name, namedBindings, isTypeOnly) {
        return node.name !== name
            || node.namedBindings !== namedBindings
            || node.isTypeOnly !== isTypeOnly
            ? updateNode(createImportClause(name, namedBindings, isTypeOnly), node)
            : node;
    }
    ts.updateImportClause = updateImportClause;
    function createNamespaceImport(name) {
        var node = createSynthesizedNode(256 /* NamespaceImport */);
        node.name = name;
        return node;
    }
    ts.createNamespaceImport = createNamespaceImport;
    function createNamespaceExport(name) {
        var node = createSynthesizedNode(262 /* NamespaceExport */);
        node.name = name;
        return node;
    }
    ts.createNamespaceExport = createNamespaceExport;
    function updateNamespaceImport(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceImport(name), node)
            : node;
    }
    ts.updateNamespaceImport = updateNamespaceImport;
    function updateNamespaceExport(node, name) {
        return node.name !== name
            ? updateNode(createNamespaceExport(name), node)
            : node;
    }
    ts.updateNamespaceExport = updateNamespaceExport;
    function createNamedImports(elements) {
        var node = createSynthesizedNode(257 /* NamedImports */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createNamedImports = createNamedImports;
    function updateNamedImports(node, elements) {
        return node.elements !== elements
            ? updateNode(createNamedImports(elements), node)
            : node;
    }
    ts.updateNamedImports = updateNamedImports;
    function createImportSpecifier(propertyName, name) {
        var node = createSynthesizedNode(258 /* ImportSpecifier */);
        node.propertyName = propertyName;
        node.name = name;
        return node;
    }
    ts.createImportSpecifier = createImportSpecifier;
    function updateImportSpecifier(node, propertyName, name) {
        return node.propertyName !== propertyName
            || node.name !== name
            ? updateNode(createImportSpecifier(propertyName, name), node)
            : node;
    }
    ts.updateImportSpecifier = updateImportSpecifier;
    function createExportAssignment(decorators, modifiers, isExportEquals, expression) {
        var node = createSynthesizedNode(259 /* ExportAssignment */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.isExportEquals = isExportEquals;
        node.expression = isExportEquals ? ts.parenthesizeBinaryOperand(62 /* EqualsToken */, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : ts.parenthesizeDefaultExpression(expression);
        return node;
    }
    ts.createExportAssignment = createExportAssignment;
    function updateExportAssignment(node, decorators, modifiers, expression) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.expression !== expression
            ? updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node)
            : node;
    }
    ts.updateExportAssignment = updateExportAssignment;
    function createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, isTypeOnly) {
        if (isTypeOnly === void 0) { isTypeOnly = false; }
        var node = createSynthesizedNode(260 /* ExportDeclaration */);
        node.decorators = asNodeArray(decorators);
        node.modifiers = asNodeArray(modifiers);
        node.isTypeOnly = isTypeOnly;
        node.exportClause = exportClause;
        node.moduleSpecifier = moduleSpecifier;
        return node;
    }
    ts.createExportDeclaration = createExportDeclaration;
    function updateExportDeclaration(node, decorators, modifiers, exportClause, moduleSpecifier, isTypeOnly) {
        return node.decorators !== decorators
            || node.modifiers !== modifiers
            || node.isTypeOnly !== isTypeOnly
            || node.exportClause !== exportClause
            || node.moduleSpecifier !== moduleSpecifier
            ? updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier, isTypeOnly), node)
            : node;
    }
    ts.updateExportDeclaration = updateExportDeclaration;
    /* @internal */
    function createEmptyExports() {
        return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined);
    }
    ts.createEmptyExports = createEmptyExports;
    function createNamedExports(elements) {
        var node = createSynthesizedNode(261 /* NamedExports */);
        node.elements = createNodeArray(elements);
        return node;
    }
    ts.createNamedExports = createNamedExports;
    function updateNamedExports(node, elements) {
        return node.elements !== elements
            ? updateNode(createNamedExports(elements), node)
            : node;
    }
    ts.updateNamedExports = updateNamedExports;
    function createExportSpecifier(propertyName, name) {
        var node = createSynthesizedNode(263 /* ExportSpecifier */);
        node.propertyName = asName(propertyName);
        node.name = asName(name);
        return node;
    }
    ts.createExportSpecifier = createExportSpecifier;
    function updateExportSpecifier(node, propertyName, name) {
        return node.propertyName !== propertyName
            || node.name !== name
            ? updateNode(createExportSpecifier(propertyName, name), node)
            : node;
    }
    ts.updateExportSpecifier = updateExportSpecifier;
    // Module references
    function createExternalModuleReference(expression) {
        var node = createSynthesizedNode(265 /* ExternalModuleReference */);
        node.expression = expression;
        return node;
    }
    ts.createExternalModuleReference = createExternalModuleReference;
    function updateExternalModuleReference(node, expression) {
        return node.expression !== expression
            ? updateNode(createExternalModuleReference(expression), node)
            : node;
    }
    ts.updateExternalModuleReference = updateExternalModuleReference;
    // JSDoc
    /* @internal */
    function createJSDocTypeExpression(type) {
        var node = createSynthesizedNode(294 /* JSDocTypeExpression */);
        node.type = type;
        return node;
    }
    ts.createJSDocTypeExpression = createJSDocTypeExpression;
    /* @internal */
    function createJSDocTypeTag(typeExpression, comment) {
        var tag = createJSDocTag(320 /* JSDocTypeTag */, "type");
        tag.typeExpression = typeExpression;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocTypeTag = createJSDocTypeTag;
    /* @internal */
    function createJSDocReturnTag(typeExpression, comment) {
        var tag = createJSDocTag(318 /* JSDocReturnTag */, "returns");
        tag.typeExpression = typeExpression;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocReturnTag = createJSDocReturnTag;
    /** @internal */
    function createJSDocThisTag(typeExpression) {
        var tag = createJSDocTag(319 /* JSDocThisTag */, "this");
        tag.typeExpression = typeExpression;
        return tag;
    }
    ts.createJSDocThisTag = createJSDocThisTag;
    /* @internal */
    function createJSDocParamTag(name, isBracketed, typeExpression, comment) {
        var tag = createJSDocTag(317 /* JSDocParameterTag */, "param");
        tag.typeExpression = typeExpression;
        tag.name = name;
        tag.isBracketed = isBracketed;
        tag.comment = comment;
        return tag;
    }
    ts.createJSDocParamTag = createJSDocParamTag;
    /* @internal */
    function createJSDocClassTag() {
        return createJSDocTag(310 /* JSDocClassTag */, "class");
    }
    ts.createJSDocClassTag = createJSDocClassTag;
    /* @internal */
    function createJSDocComment(comment, tags) {
        var node = createSynthesizedNode(303 /* JSDocComment */);
        node.comment = comment;
        node.tags = tags;
        return node;
    }
    ts.createJSDocComment = createJSDocComment;
    /* @internal */
    function createJSDocTag(kind, tagName) {
        var node = createSynthesizedNode(kind);
        node.tagName = createIdentifier(tagName);
        return node;
    }
    // JSX
    function createJsxElement(openingElement, children, closingElement) {
        var node = createSynthesizedNode(266 /* JsxElement */);
        node.openingElement = openingElement;
        node.children = createNodeArray(children);
        node.closingElement = closingElement;
        return node;
    }
    ts.createJsxElement = createJsxElement;
    function updateJsxElement(node, openingElement, children, closingElement) {
        return node.openingElement !== openingElement
            || node.children !== children
            || node.closingElement !== closingElement
            ? updateNode(createJsxElement(openingElement, children, closingElement), node)
            : node;
    }
    ts.updateJsxElement = updateJsxElement;
    function createJsxSelfClosingElement(tagName, typeArguments, attributes) {
        var node = createSynthesizedNode(267 /* JsxSelfClosingElement */);
        node.tagName = tagName;
        node.typeArguments = asNodeArray(typeArguments);
        node.attributes = attributes;
        return node;
    }
    ts.createJsxSelfClosingElement = createJsxSelfClosingElement;
    function updateJsxSelfClosingElement(node, tagName, typeArguments, attributes) {
        return node.tagName !== tagName
            || node.typeArguments !== typeArguments
            || node.attributes !== attributes
            ? updateNode(createJsxSelfClosingElement(tagName, typeArguments, attributes), node)
            : node;
    }
    ts.updateJsxSelfClosingElement = updateJsxSelfClosingElement;
    function createJsxOpeningElement(tagName, typeArguments, attributes) {
        var node = createSynthesizedNode(268 /* JsxOpeningElement */);
        node.tagName = tagName;
        node.typeArguments = asNodeArray(typeArguments);
        node.attributes = attributes;
        return node;
    }
    ts.createJsxOpeningElement = createJsxOpeningElement;
    function updateJsxOpeningElement(node, tagName, typeArguments, attributes) {
        return node.tagName !== tagName
            || node.typeArguments !== typeArguments
            || node.attributes !== attributes
            ? updateNode(createJsxOpeningElement(tagName, typeArguments, attributes), node)
            : node;
    }
    ts.updateJsxOpeningElement = updateJsxOpeningElement;
    function createJsxClosingElement(tagName) {
        var node = createSynthesizedNode(269 /* JsxClosingElement */);
        node.tagName = tagName;
        return node;
    }
    ts.createJsxClosingElement = createJsxClosingElement;
    function updateJsxClosingElement(node, tagName) {
        return node.tagName !== tagName
            ? updateNode(createJsxClosingElement(tagName), node)
            : node;
    }
    ts.updateJsxClosingElement = updateJsxClosingElement;
    function createJsxFragment(openingFragment, children, closingFragment) {
        var node = createSynthesizedNode(270 /* JsxFragment */);
        node.openingFragment = openingFragment;
        node.children = createNodeArray(children);
        node.closingFragment = closingFragment;
        return node;
    }
    ts.createJsxFragment = createJsxFragment;
    function createJsxText(text, containsOnlyTriviaWhiteSpaces) {
        var node = createSynthesizedNode(11 /* JsxText */);
        node.text = text;
        node.containsOnlyTriviaWhiteSpaces = !!containsOnlyTriviaWhiteSpaces;
        return node;
    }
    ts.createJsxText = createJsxText;
    function updateJsxText(node, text, containsOnlyTriviaWhiteSpaces) {
        return node.text !== text
            || node.containsOnlyTriviaWhiteSpaces !== containsOnlyTriviaWhiteSpaces
            ? updateNode(createJsxText(text, containsOnlyTriviaWhiteSpaces), node)
            : node;
    }
    ts.updateJsxText = updateJsxText;
    function createJsxOpeningFragment() {
        return createSynthesizedNode(271 /* JsxOpeningFragment */);
    }
    ts.createJsxOpeningFragment = createJsxOpeningFragment;
    function createJsxJsxClosingFragment() {
        return createSynthesizedNode(272 /* JsxClosingFragment */);
    }
    ts.createJsxJsxClosingFragment = createJsxJsxClosingFragment;
    function updateJsxFragment(node, openingFragment, children, closingFragment) {
        return node.openingFragment !== openingFragment
            || node.children !== children
            || node.closingFragment !== closingFragment
            ? updateNode(createJsxFragment(openingFragment, children, closingFragment), node)
            : node;
    }
    ts.updateJsxFragment = updateJsxFragment;
    function createJsxAttribute(name, initializer) {
        var node = createSynthesizedNode(273 /* JsxAttribute */);
        node.name = name;
        node.initializer = initializer;
        return node;
    }
    ts.createJsxAttribute = createJsxAttribute;
    function updateJsxAttribute(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createJsxAttribute(name, initializer), node)
            : node;
    }
    ts.updateJsxAttribute = updateJsxAttribute;
    function createJsxAttributes(properties) {
        var node = createSynthesizedNode(274 /* JsxAttributes */);
        node.properties = createNodeArray(properties);
        return node;
    }
    ts.createJsxAttributes = createJsxAttributes;
    function updateJsxAttributes(node, properties) {
        return node.properties !== properties
            ? updateNode(createJsxAttributes(properties), node)
            : node;
    }
    ts.updateJsxAttributes = updateJsxAttributes;
    function createJsxSpreadAttribute(expression) {
        var node = createSynthesizedNode(275 /* JsxSpreadAttribute */);
        node.expression = expression;
        return node;
    }
    ts.createJsxSpreadAttribute = createJsxSpreadAttribute;
    function updateJsxSpreadAttribute(node, expression) {
        return node.expression !== expression
            ? updateNode(createJsxSpreadAttribute(expression), node)
            : node;
    }
    ts.updateJsxSpreadAttribute = updateJsxSpreadAttribute;
    function createJsxExpression(dotDotDotToken, expression) {
        var node = createSynthesizedNode(276 /* JsxExpression */);
        node.dotDotDotToken = dotDotDotToken;
        node.expression = expression;
        return node;
    }
    ts.createJsxExpression = createJsxExpression;
    function updateJsxExpression(node, expression) {
        return node.expression !== expression
            ? updateNode(createJsxExpression(node.dotDotDotToken, expression), node)
            : node;
    }
    ts.updateJsxExpression = updateJsxExpression;
    // Clauses
    function createCaseClause(expression, statements) {
        var node = createSynthesizedNode(277 /* CaseClause */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createCaseClause = createCaseClause;
    function updateCaseClause(node, expression, statements) {
        return node.expression !== expression
            || node.statements !== statements
            ? updateNode(createCaseClause(expression, statements), node)
            : node;
    }
    ts.updateCaseClause = updateCaseClause;
    function createDefaultClause(statements) {
        var node = createSynthesizedNode(278 /* DefaultClause */);
        node.statements = createNodeArray(statements);
        return node;
    }
    ts.createDefaultClause = createDefaultClause;
    function updateDefaultClause(node, statements) {
        return node.statements !== statements
            ? updateNode(createDefaultClause(statements), node)
            : node;
    }
    ts.updateDefaultClause = updateDefaultClause;
    function createHeritageClause(token, types) {
        var node = createSynthesizedNode(279 /* HeritageClause */);
        node.token = token;
        node.types = createNodeArray(types);
        return node;
    }
    ts.createHeritageClause = createHeritageClause;
    function updateHeritageClause(node, types) {
        return node.types !== types
            ? updateNode(createHeritageClause(node.token, types), node)
            : node;
    }
    ts.updateHeritageClause = updateHeritageClause;
    function createCatchClause(variableDeclaration, block) {
        var node = createSynthesizedNode(280 /* CatchClause */);
        node.variableDeclaration = ts.isString(variableDeclaration) ? createVariableDeclaration(variableDeclaration) : variableDeclaration;
        node.block = block;
        return node;
    }
    ts.createCatchClause = createCatchClause;
    function updateCatchClause(node, variableDeclaration, block) {
        return node.variableDeclaration !== variableDeclaration
            || node.block !== block
            ? updateNode(createCatchClause(variableDeclaration, block), node)
            : node;
    }
    ts.updateCatchClause = updateCatchClause;
    // Property assignments
    function createPropertyAssignment(name, initializer) {
        var node = createSynthesizedNode(281 /* PropertyAssignment */);
        node.name = asName(name);
        node.questionToken = undefined;
        node.initializer = ts.parenthesizeExpressionForList(initializer);
        return node;
    }
    ts.createPropertyAssignment = createPropertyAssignment;
    function updatePropertyAssignment(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createPropertyAssignment(name, initializer), node)
            : node;
    }
    ts.updatePropertyAssignment = updatePropertyAssignment;
    function createShorthandPropertyAssignment(name, objectAssignmentInitializer) {
        var node = createSynthesizedNode(282 /* ShorthandPropertyAssignment */);
        node.name = asName(name);
        node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? ts.parenthesizeExpressionForList(objectAssignmentInitializer) : undefined;
        return node;
    }
    ts.createShorthandPropertyAssignment = createShorthandPropertyAssignment;
    function updateShorthandPropertyAssignment(node, name, objectAssignmentInitializer) {
        return node.name !== name
            || node.objectAssignmentInitializer !== objectAssignmentInitializer
            ? updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node)
            : node;
    }
    ts.updateShorthandPropertyAssignment = updateShorthandPropertyAssignment;
    function createSpreadAssignment(expression) {
        var node = createSynthesizedNode(283 /* SpreadAssignment */);
        node.expression = ts.parenthesizeExpressionForList(expression);
        return node;
    }
    ts.createSpreadAssignment = createSpreadAssignment;
    function updateSpreadAssignment(node, expression) {
        return node.expression !== expression
            ? updateNode(createSpreadAssignment(expression), node)
            : node;
    }
    ts.updateSpreadAssignment = updateSpreadAssignment;
    // Enum
    function createEnumMember(name, initializer) {
        var node = createSynthesizedNode(284 /* EnumMember */);
        node.name = asName(name);
        node.initializer = initializer && ts.parenthesizeExpressionForList(initializer);
        return node;
    }
    ts.createEnumMember = createEnumMember;
    function updateEnumMember(node, name, initializer) {
        return node.name !== name
            || node.initializer !== initializer
            ? updateNode(createEnumMember(name, initializer), node)
            : node;
    }
    ts.updateEnumMember = updateEnumMember;
    // Top-level nodes
    function updateSourceFileNode(node, statements, isDeclarationFile, referencedFiles, typeReferences, hasNoDefaultLib, libReferences) {
        if (node.statements !== statements ||
            (isDeclarationFile !== undefined && node.isDeclarationFile !== isDeclarationFile) ||
            (referencedFiles !== undefined && node.referencedFiles !== referencedFiles) ||
            (typeReferences !== undefined && node.typeReferenceDirectives !== typeReferences) ||
            (libReferences !== undefined && node.libReferenceDirectives !== libReferences) ||
            (hasNoDefaultLib !== undefined && node.hasNoDefaultLib !== hasNoDefaultLib)) {
            var updated = createSynthesizedNode(290 /* SourceFile */);
            updated.flags |= node.flags;
            updated.statements = createNodeArray(statements);
            updated.endOfFileToken = node.endOfFileToken;
            updated.fileName = node.fileName;
            updated.path = node.path;
            updated.text = node.text;
            updated.isDeclarationFile = isDeclarationFile === undefined ? node.isDeclarationFile : isDeclarationFile;
            updated.referencedFiles = referencedFiles === undefined ? node.referencedFiles : referencedFiles;
            updated.typeReferenceDirectives = typeReferences === undefined ? node.typeReferenceDirectives : typeReferences;
            updated.hasNoDefaultLib = hasNoDefaultLib === undefined ? node.hasNoDefaultLib : hasNoDefaultLib;
            updated.libReferenceDirectives = libReferences === undefined ? node.libReferenceDirectives : libReferences;
            if (node.amdDependencies !== undefined)
                updated.amdDependencies = node.amdDependencies;
            if (node.moduleName !== undefined)
                updated.moduleName = node.moduleName;
            if (node.languageVariant !== undefined)
                updated.languageVariant = node.languageVariant;
            if (node.renamedDependencies !== undefined)
                updated.renamedDependencies = node.renamedDependencies;
            if (node.languageVersion !== undefined)
                updated.languageVersion = node.languageVersion;
            if (node.scriptKind !== undefined)
                updated.scriptKind = node.scriptKind;
            if (node.externalModuleIndicator !== undefined)
                updated.externalModuleIndicator = node.externalModuleIndicator;
            if (node.commonJsModuleIndicator !== undefined)
                updated.commonJsModuleIndicator = node.commonJsModuleIndicator;
            if (node.identifiers !== undefined)
                updated.identifiers = node.identifiers;
            if (node.nodeCount !== undefined)
                updated.nodeCount = node.nodeCount;
            if (node.identifierCount !== undefined)
                updated.identifierCount = node.identifierCount;
            if (node.symbolCount !== undefined)
                updated.symbolCount = node.symbolCount;
            if (node.parseDiagnostics !== undefined)
                updated.parseDiagnostics = node.parseDiagnostics;
            if (node.bindDiagnostics !== undefined)
                updated.bindDiagnostics = node.bindDiagnostics;
            if (node.bindSuggestionDiagnostics !== undefined)
                updated.bindSuggestionDiagnostics = node.bindSuggestionDiagnostics;
            if (node.lineMap !== undefined)
                updated.lineMap = node.lineMap;
            if (node.classifiableNames !== undefined)
                updated.classifiableNames = node.classifiableNames;
            if (node.resolvedModules !== undefined)
                updated.resolvedModules = node.resolvedModules;
            if (node.resolvedTypeReferenceDirectiveNames !== undefined)
                updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames;
            if (node.imports !== undefined)
                updated.imports = node.imports;
            if (node.moduleAugmentations !== undefined)
                updated.moduleAugmentations = node.moduleAugmentations;
            if (node.pragmas !== undefined)
                updated.pragmas = node.pragmas;
            if (node.localJsxFactory !== undefined)
                updated.localJsxFactory = node.localJsxFactory;
            if (node.localJsxNamespace !== undefined)
                updated.localJsxNamespace = node.localJsxNamespace;
            return updateNode(updated, node);
        }
        return node;
    }
    ts.updateSourceFileNode = updateSourceFileNode;
    /**
     * Creates a shallow, memberwise clone of a node for mutation.
     */
    function getMutableClone(node) {
        var clone = getSynthesizedClone(node);
        clone.pos = node.pos;
        clone.end = node.end;
        clone.parent = node.parent;
        return clone;
    }
    ts.getMutableClone = getMutableClone;
    // Transformation nodes
    /**
     * Creates a synthetic statement to act as a placeholder for a not-emitted statement in
     * order to preserve comments.
     *
     * @param original The original statement.
     */
    function createNotEmittedStatement(original) {
        var node = createSynthesizedNode(325 /* NotEmittedStatement */);
        node.original = original;
        setTextRange(node, original);
        return node;
    }
    ts.createNotEmittedStatement = createNotEmittedStatement;
    /**
     * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in
     * order to properly emit exports.
     */
    /* @internal */
    function createEndOfDeclarationMarker(original) {
        var node = createSynthesizedNode(329 /* EndOfDeclarationMarker */);
        node.emitNode = {};
        node.original = original;
        return node;
    }
    ts.createEndOfDeclarationMarker = createEndOfDeclarationMarker;
    /**
     * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in
     * order to properly emit exports.
     */
    /* @internal */
    function createMergeDeclarationMarker(original) {
        var node = createSynthesizedNode(328 /* MergeDeclarationMarker */);
        node.emitNode = {};
        node.original = original;
        return node;
    }
    ts.createMergeDeclarationMarker = createMergeDeclarationMarker;
    /**
     * Creates a synthetic expression to act as a placeholder for a not-emitted expression in
     * order to preserve comments or sourcemap positions.
     *
     * @param expression The inner expression to emit.
     * @param original The original outer expression.
     * @param location The location for the expression. Defaults to the positions from "original" if provided.
     */
    function createPartiallyEmittedExpression(expression, original) {
        var node = createSynthesizedNode(326 /* PartiallyEmittedExpression */);
        node.expression = expression;
        node.original = original;
        setTextRange(node, original);
        return node;
    }
    ts.createPartiallyEmittedExpression = createPartiallyEmittedExpression;
    function updatePartiallyEmittedExpression(node, expression) {
        if (node.expression !== expression) {
            return updateNode(createPartiallyEmittedExpression(expression, node.original), node);
        }
        return node;
    }
    ts.updatePartiallyEmittedExpression = updatePartiallyEmittedExpression;
    function flattenCommaElements(node) {
        if (ts.nodeIsSynthesized(node) && !ts.isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) {
            if (node.kind === 327 /* CommaListExpression */) {
                return node.elements;
            }
            if (ts.isBinaryExpression(node) && node.operatorToken.kind === 27 /* CommaToken */) {
                return [node.left, node.right];
            }
        }
        return node;
    }
    function createCommaList(elements) {
        var node = createSynthesizedNode(327 /* CommaListExpression */);
        node.elements = createNodeArray(ts.sameFlatMap(elements, flattenCommaElements));
        return node;
    }
    ts.createCommaList = createCommaList;
    function updateCommaList(node, elements) {
        return node.elements !== elements
            ? updateNode(createCommaList(elements), node)
            : node;
    }
    ts.updateCommaList = updateCommaList;
    /* @internal */
    function createSyntheticReferenceExpression(expression, thisArg) {
        var node = createSynthesizedNode(330 /* SyntheticReferenceExpression */);
        node.expression = expression;
        node.thisArg = thisArg;
        return node;
    }
    ts.createSyntheticReferenceExpression = createSyntheticReferenceExpression;
    /* @internal */
    function updateSyntheticReferenceExpression(node, expression, thisArg) {
        return node.expression !== expression
            || node.thisArg !== thisArg
            ? updateNode(createSyntheticReferenceExpression(expression, thisArg), node)
            : node;
    }
    ts.updateSyntheticReferenceExpression = updateSyntheticReferenceExpression;
    function createBundle(sourceFiles, prepends) {
        if (prepends === void 0) { prepends = ts.emptyArray; }
        var node = ts.createNode(291 /* Bundle */);
        node.prepends = prepends;
        node.sourceFiles = sourceFiles;
        return node;
    }
    ts.createBundle = createBundle;
    var allUnscopedEmitHelpers;
    function getAllUnscopedEmitHelpers() {
        return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = ts.arrayToMap([
            ts.valuesHelper,
            ts.readHelper,
            ts.spreadHelper,
            ts.spreadArraysHelper,
            ts.restHelper,
            ts.decorateHelper,
            ts.metadataHelper,
            ts.paramHelper,
            ts.awaiterHelper,
            ts.assignHelper,
            ts.awaitHelper,
            ts.asyncGeneratorHelper,
            ts.asyncDelegator,
            ts.asyncValues,
            ts.extendsHelper,
            ts.templateObjectHelper,
            ts.generatorHelper,
            ts.importStarHelper,
            ts.importDefaultHelper,
            ts.classPrivateFieldGetHelper,
            ts.classPrivateFieldSetHelper,
            ts.createBindingHelper,
            ts.setModuleDefaultHelper
        ], function (helper) { return helper.name; }));
    }
    function createUnparsedSource() {
        var node = ts.createNode(292 /* UnparsedSource */);
        node.prologues = ts.emptyArray;
        node.referencedFiles = ts.emptyArray;
        node.libReferenceDirectives = ts.emptyArray;
        node.getLineAndCharacterOfPosition = function (pos) { return ts.getLineAndCharacterOfPosition(node, pos); };
        return node;
    }
    function createUnparsedSourceFile(textOrInputFiles, mapPathOrType, mapTextOrStripInternal) {
        var node = createUnparsedSource();
        var stripInternal;
        var bundleFileInfo;
        if (!ts.isString(textOrInputFiles)) {
            ts.Debug.assert(mapPathOrType === "js" || mapPathOrType === "dts");
            node.fileName = (mapPathOrType === "js" ? textOrInputFiles.javascriptPath : textOrInputFiles.declarationPath) || "";
            node.sourceMapPath = mapPathOrType === "js" ? textOrInputFiles.javascriptMapPath : textOrInputFiles.declarationMapPath;
            Object.defineProperties(node, {
                text: { get: function () { return mapPathOrType === "js" ? textOrInputFiles.javascriptText : textOrInputFiles.declarationText; } },
                sourceMapText: { get: function () { return mapPathOrType === "js" ? textOrInputFiles.javascriptMapText : textOrInputFiles.declarationMapText; } },
            });
            if (textOrInputFiles.buildInfo && textOrInputFiles.buildInfo.bundle) {
                node.oldFileOfCurrentEmit = textOrInputFiles.oldFileOfCurrentEmit;
                ts.Debug.assert(mapTextOrStripInternal === undefined || typeof mapTextOrStripInternal === "boolean");
                stripInternal = mapTextOrStripInternal;
                bundleFileInfo = mapPathOrType === "js" ? textOrInputFiles.buildInfo.bundle.js : textOrInputFiles.buildInfo.bundle.dts;
                if (node.oldFileOfCurrentEmit) {
                    parseOldFileOfCurrentEmit(node, ts.Debug.checkDefined(bundleFileInfo));
                    return node;
                }
            }
        }
        else {
            node.fileName = "";
            node.text = textOrInputFiles;
            node.sourceMapPath = mapPathOrType;
            node.sourceMapText = mapTextOrStripInternal;
        }
        ts.Debug.assert(!node.oldFileOfCurrentEmit);
        parseUnparsedSourceFile(node, bundleFileInfo, stripInternal);
        return node;
    }
    ts.createUnparsedSourceFile = createUnparsedSourceFile;
    function parseUnparsedSourceFile(node, bundleFileInfo, stripInternal) {
        var prologues;
        var helpers;
        var referencedFiles;
        var typeReferenceDirectives;
        var libReferenceDirectives;
        var texts;
        for (var _i = 0, _a = bundleFileInfo ? bundleFileInfo.sections : ts.emptyArray; _i < _a.length; _i++) {
            var section = _a[_i];
            switch (section.kind) {
                case "prologue" /* Prologue */:
                    (prologues || (prologues = [])).push(createUnparsedNode(section, node));
                    break;
                case "emitHelpers" /* EmitHelpers */:
                    (helpers || (helpers = [])).push(getAllUnscopedEmitHelpers().get(section.data));
                    break;
                case "no-default-lib" /* NoDefaultLib */:
                    node.hasNoDefaultLib = true;
                    break;
                case "reference" /* Reference */:
                    (referencedFiles || (referencedFiles = [])).push({ pos: -1, end: -1, fileName: section.data });
                    break;
                case "type" /* Type */:
                    (typeReferenceDirectives || (typeReferenceDirectives = [])).push(section.data);
                    break;
                case "lib" /* Lib */:
                    (libReferenceDirectives || (libReferenceDirectives = [])).push({ pos: -1, end: -1, fileName: section.data });
                    break;
                case "prepend" /* Prepend */:
                    var prependNode = createUnparsedNode(section, node);
                    var prependTexts = void 0;
                    for (var _b = 0, _c = section.texts; _b < _c.length; _b++) {
                        var text = _c[_b];
                        if (!stripInternal || text.kind !== "internal" /* Internal */) {
                            (prependTexts || (prependTexts = [])).push(createUnparsedNode(text, node));
                        }
                    }
                    prependNode.texts = prependTexts || ts.emptyArray;
                    (texts || (texts = [])).push(prependNode);
                    break;
                case "internal" /* Internal */:
                    if (stripInternal) {
                        if (!texts)
                            texts = [];
                        break;
                    }
                // falls through
                case "text" /* Text */:
                    (texts || (texts = [])).push(createUnparsedNode(section, node));
                    break;
                default:
                    ts.Debug.assertNever(section);
            }
        }
        node.prologues = prologues || ts.emptyArray;
        node.helpers = helpers;
        node.referencedFiles = referencedFiles || ts.emptyArray;
        node.typeReferenceDirectives = typeReferenceDirectives;
        node.libReferenceDirectives = libReferenceDirectives || ts.emptyArray;
        node.texts = texts || [createUnparsedNode({ kind: "text" /* Text */, pos: 0, end: node.text.length }, node)];
    }
    function parseOldFileOfCurrentEmit(node, bundleFileInfo) {
        ts.Debug.assert(!!node.oldFileOfCurrentEmit);
        var texts;
        var syntheticReferences;
        for (var _i = 0, _a = bundleFileInfo.sections; _i < _a.length; _i++) {
            var section = _a[_i];
            switch (section.kind) {
                case "internal" /* Internal */:
                case "text" /* Text */:
                    (texts || (texts = [])).push(createUnparsedNode(section, node));
                    break;
                case "no-default-lib" /* NoDefaultLib */:
                case "reference" /* Reference */:
                case "type" /* Type */:
                case "lib" /* Lib */:
                    (syntheticReferences || (syntheticReferences = [])).push(createUnparsedSyntheticReference(section, node));
                    break;
                // Ignore
                case "prologue" /* Prologue */:
                case "emitHelpers" /* EmitHelpers */:
                case "prepend" /* Prepend */:
                    break;
                default:
                    ts.Debug.assertNever(section);
            }
        }
        node.texts = texts || ts.emptyArray;
        node.helpers = ts.map(bundleFileInfo.sources && bundleFileInfo.sources.helpers, function (name) { return getAllUnscopedEmitHelpers().get(name); });
        node.syntheticReferences = syntheticReferences;
        return node;
    }
    function mapBundleFileSectionKindToSyntaxKind(kind) {
        switch (kind) {
            case "prologue" /* Prologue */: return 285 /* UnparsedPrologue */;
            case "prepend" /* Prepend */: return 286 /* UnparsedPrepend */;
            case "internal" /* Internal */: return 288 /* UnparsedInternalText */;
            case "text" /* Text */: return 287 /* UnparsedText */;
            case "emitHelpers" /* EmitHelpers */:
            case "no-default-lib" /* NoDefaultLib */:
            case "reference" /* Reference */:
            case "type" /* Type */:
            case "lib" /* Lib */:
                return ts.Debug.fail("BundleFileSectionKind: " + kind + " not yet mapped to SyntaxKind");
            default:
                return ts.Debug.assertNever(kind);
        }
    }
    function createUnparsedNode(section, parent) {
        var node = ts.createNode(mapBundleFileSectionKindToSyntaxKind(section.kind), section.pos, section.end);
        node.parent = parent;
        node.data = section.data;
        return node;
    }
    function createUnparsedSyntheticReference(section, parent) {
        var node = ts.createNode(289 /* UnparsedSyntheticReference */, section.pos, section.end);
        node.parent = parent;
        node.data = section.data;
        node.section = section;
        return node;
    }
    function createInputFiles(javascriptTextOrReadFileText, declarationTextOrJavascriptPath, javascriptMapPath, javascriptMapTextOrDeclarationPath, declarationMapPath, declarationMapTextOrBuildInfoPath, javascriptPath, declarationPath, buildInfoPath, buildInfo, oldFileOfCurrentEmit) {
        var node = ts.createNode(293 /* InputFiles */);
        if (!ts.isString(javascriptTextOrReadFileText)) {
            var cache_1 = ts.createMap();
            var textGetter_1 = function (path) {
                if (path === undefined)
                    return undefined;
                var value = cache_1.get(path);
                if (value === undefined) {
                    value = javascriptTextOrReadFileText(path);
                    cache_1.set(path, value !== undefined ? value : false);
                }
                return value !== false ? value : undefined;
            };
            var definedTextGetter_1 = function (path) {
                var result = textGetter_1(path);
                return result !== undefined ? result : "/* Input file " + path + " was missing */\r\n";
            };
            var buildInfo_1;
            var getAndCacheBuildInfo_1 = function (getText) {
                if (buildInfo_1 === undefined) {
                    var result = getText();
                    buildInfo_1 = result !== undefined ? ts.getBuildInfo(result) : false;
                }
                return buildInfo_1 || undefined;
            };
            node.javascriptPath = declarationTextOrJavascriptPath;
            node.javascriptMapPath = javascriptMapPath;
            node.declarationPath = ts.Debug.checkDefined(javascriptMapTextOrDeclarationPath);
            node.declarationMapPath = declarationMapPath;
            node.buildInfoPath = declarationMapTextOrBuildInfoPath;
            Object.defineProperties(node, {
                javascriptText: { get: function () { return definedTextGetter_1(declarationTextOrJavascriptPath); } },
                javascriptMapText: { get: function () { return textGetter_1(javascriptMapPath); } },
                declarationText: { get: function () { return definedTextGetter_1(ts.Debug.checkDefined(javascriptMapTextOrDeclarationPath)); } },
                declarationMapText: { get: function () { return textGetter_1(declarationMapPath); } },
                buildInfo: { get: function () { return getAndCacheBuildInfo_1(function () { return textGetter_1(declarationMapTextOrBuildInfoPath); }); } }
            });
        }
        else {
            node.javascriptText = javascriptTextOrReadFileText;
            node.javascriptMapPath = javascriptMapPath;
            node.javascriptMapText = javascriptMapTextOrDeclarationPath;
            node.declarationText = declarationTextOrJavascriptPath;
            node.declarationMapPath = declarationMapPath;
            node.declarationMapText = declarationMapTextOrBuildInfoPath;
            node.javascriptPath = javascriptPath;
            node.declarationPath = declarationPath;
            node.buildInfoPath = buildInfoPath;
            node.buildInfo = buildInfo;
            node.oldFileOfCurrentEmit = oldFileOfCurrentEmit;
        }
        return node;
    }
    ts.createInputFiles = createInputFiles;
    function updateBundle(node, sourceFiles, prepends) {
        if (prepends === void 0) { prepends = ts.emptyArray; }
        if (node.sourceFiles !== sourceFiles || node.prepends !== prepends) {
            return createBundle(sourceFiles, prepends);
        }
        return node;
    }
    ts.updateBundle = updateBundle;
    function createImmediatelyInvokedFunctionExpression(statements, param, paramValue) {
        return createCall(createFunctionExpression(
        /*modifiers*/ undefined, 
        /*asteriskToken*/ undefined, 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ param ? [param] : [], 
        /*type*/ undefined, createBlock(statements, /*multiLine*/ true)), 
        /*typeArguments*/ undefined, 
        /*argumentsArray*/ paramValue ? [paramValue] : []);
    }
    ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression;
    function createImmediatelyInvokedArrowFunction(statements, param, paramValue) {
        return createCall(createArrowFunction(
        /*modifiers*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ param ? [param] : [], 
        /*type*/ undefined, 
        /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), 
        /*typeArguments*/ undefined, 
        /*argumentsArray*/ paramValue ? [paramValue] : []);
    }
    ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction;
    function createComma(left, right) {
        return createBinary(left, 27 /* CommaToken */, right);
    }
    ts.createComma = createComma;
    function createLessThan(left, right) {
        return createBinary(left, 29 /* LessThanToken */, right);
    }
    ts.createLessThan = createLessThan;
    function createAssignment(left, right) {
        return createBinary(left, 62 /* EqualsToken */, right);
    }
    ts.createAssignment = createAssignment;
    function createStrictEquality(left, right) {
        return createBinary(left, 36 /* EqualsEqualsEqualsToken */, right);
    }
    ts.createStrictEquality = createStrictEquality;
    function createStrictInequality(left, right) {
        return createBinary(left, 37 /* ExclamationEqualsEqualsToken */, right);
    }
    ts.createStrictInequality = createStrictInequality;
    function createAdd(left, right) {
        return createBinary(left, 39 /* PlusToken */, right);
    }
    ts.createAdd = createAdd;
    function createSubtract(left, right) {
        return createBinary(left, 40 /* MinusToken */, right);
    }
    ts.createSubtract = createSubtract;
    function createPostfixIncrement(operand) {
        return createPostfix(operand, 45 /* PlusPlusToken */);
    }
    ts.createPostfixIncrement = createPostfixIncrement;
    function createLogicalAnd(left, right) {
        return createBinary(left, 55 /* AmpersandAmpersandToken */, right);
    }
    ts.createLogicalAnd = createLogicalAnd;
    function createLogicalOr(left, right) {
        return createBinary(left, 56 /* BarBarToken */, right);
    }
    ts.createLogicalOr = createLogicalOr;
    function createNullishCoalesce(left, right) {
        return createBinary(left, 60 /* QuestionQuestionToken */, right);
    }
    ts.createNullishCoalesce = createNullishCoalesce;
    function createLogicalNot(operand) {
        return createPrefix(53 /* ExclamationToken */, operand);
    }
    ts.createLogicalNot = createLogicalNot;
    function createVoidZero() {
        return createVoid(createLiteral(0));
    }
    ts.createVoidZero = createVoidZero;
    function createExportDefault(expression) {
        return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression);
    }
    ts.createExportDefault = createExportDefault;
    function createExternalModuleExport(exportName) {
        return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)]));
    }
    ts.createExternalModuleExport = createExternalModuleExport;
    // Utilities
    function asName(name) {
        return ts.isString(name) ? createIdentifier(name) : name;
    }
    function asExpression(value) {
        return typeof value === "string" ? createStringLiteral(value) :
            typeof value === "number" ? createNumericLiteral("" + value) :
                typeof value === "boolean" ? value ? createTrue() : createFalse() :
                    value;
    }
    function asNodeArray(array) {
        return array ? createNodeArray(array) : undefined;
    }
    function asToken(value) {
        return typeof value === "number" ? createToken(value) : value;
    }
    function asEmbeddedStatement(statement) {
        return statement && ts.isNotEmittedStatement(statement) ? setTextRange(setOriginalNode(createEmptyStatement(), statement), statement) : statement;
    }
    /**
     * Clears any EmitNode entries from parse-tree nodes.
     * @param sourceFile A source file.
     */
    function disposeEmitNodes(sourceFile) {
        // During transformation we may need to annotate a parse tree node with transient
        // transformation properties. As parse tree nodes live longer than transformation
        // nodes, we need to make sure we reclaim any memory allocated for custom ranges
        // from these nodes to ensure we do not hold onto entire subtrees just for position
        // information. We also need to reset these nodes to a pre-transformation state
        // for incremental parsing scenarios so that we do not impact later emit.
        sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(sourceFile));
        var emitNode = sourceFile && sourceFile.emitNode;
        var annotatedNodes = emitNode && emitNode.annotatedNodes;
        if (annotatedNodes) {
            for (var _i = 0, annotatedNodes_1 = annotatedNodes; _i < annotatedNodes_1.length; _i++) {
                var node = annotatedNodes_1[_i];
                node.emitNode = undefined;
            }
        }
    }
    ts.disposeEmitNodes = disposeEmitNodes;
    /**
     * Associates a node with the current transformation, initializing
     * various transient transformation properties.
     */
    /* @internal */
    function getOrCreateEmitNode(node) {
        if (!node.emitNode) {
            if (ts.isParseTreeNode(node)) {
                // To avoid holding onto transformation artifacts, we keep track of any
                // parse tree node we are annotating. This allows us to clean them up after
                // all transformations have completed.
                if (node.kind === 290 /* SourceFile */) {
                    return node.emitNode = { annotatedNodes: [node] };
                }
                var sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(ts.getSourceFileOfNode(node)));
                getOrCreateEmitNode(sourceFile).annotatedNodes.push(node);
            }
            node.emitNode = {};
        }
        return node.emitNode;
    }
    ts.getOrCreateEmitNode = getOrCreateEmitNode;
    /**
     * Sets `EmitFlags.NoComments` on a node and removes any leading and trailing synthetic comments.
     * @internal
     */
    function removeAllComments(node) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.flags |= 1536 /* NoComments */;
        emitNode.leadingComments = undefined;
        emitNode.trailingComments = undefined;
        return node;
    }
    ts.removeAllComments = removeAllComments;
    function setTextRange(range, location) {
        if (location) {
            range.pos = location.pos;
            range.end = location.end;
        }
        return range;
    }
    ts.setTextRange = setTextRange;
    /**
     * Sets flags that control emit behavior of a node.
     */
    function setEmitFlags(node, emitFlags) {
        getOrCreateEmitNode(node).flags = emitFlags;
        return node;
    }
    ts.setEmitFlags = setEmitFlags;
    /**
     * Sets flags that control emit behavior of a node.
     */
    /* @internal */
    function addEmitFlags(node, emitFlags) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.flags = emitNode.flags | emitFlags;
        return node;
    }
    ts.addEmitFlags = addEmitFlags;
    /**
     * Gets a custom text range to use when emitting source maps.
     */
    function getSourceMapRange(node) {
        var emitNode = node.emitNode;
        return (emitNode && emitNode.sourceMapRange) || node;
    }
    ts.getSourceMapRange = getSourceMapRange;
    /**
     * Sets a custom text range to use when emitting source maps.
     */
    function setSourceMapRange(node, range) {
        getOrCreateEmitNode(node).sourceMapRange = range;
        return node;
    }
    ts.setSourceMapRange = setSourceMapRange;
    var SourceMapSource;
    /**
     * Create an external source map source file reference
     */
    function createSourceMapSource(fileName, text, skipTrivia) {
        return new (SourceMapSource || (SourceMapSource = ts.objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia);
    }
    ts.createSourceMapSource = createSourceMapSource;
    /**
     * Gets the TextRange to use for source maps for a token of a node.
     */
    function getTokenSourceMapRange(node, token) {
        var emitNode = node.emitNode;
        var tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
        return tokenSourceMapRanges && tokenSourceMapRanges[token];
    }
    ts.getTokenSourceMapRange = getTokenSourceMapRange;
    /**
     * Sets the TextRange to use for source maps for a token of a node.
     */
    function setTokenSourceMapRange(node, token, range) {
        var emitNode = getOrCreateEmitNode(node);
        var tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
        tokenSourceMapRanges[token] = range;
        return node;
    }
    ts.setTokenSourceMapRange = setTokenSourceMapRange;
    /**
     * Gets a custom text range to use when emitting comments.
     */
    /*@internal*/
    function getStartsOnNewLine(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.startsOnNewLine;
    }
    ts.getStartsOnNewLine = getStartsOnNewLine;
    /**
     * Sets a custom text range to use when emitting comments.
     */
    /*@internal*/
    function setStartsOnNewLine(node, newLine) {
        getOrCreateEmitNode(node).startsOnNewLine = newLine;
        return node;
    }
    ts.setStartsOnNewLine = setStartsOnNewLine;
    /**
     * Gets a custom text range to use when emitting comments.
     */
    function getCommentRange(node) {
        var emitNode = node.emitNode;
        return (emitNode && emitNode.commentRange) || node;
    }
    ts.getCommentRange = getCommentRange;
    /**
     * Sets a custom text range to use when emitting comments.
     */
    function setCommentRange(node, range) {
        getOrCreateEmitNode(node).commentRange = range;
        return node;
    }
    ts.setCommentRange = setCommentRange;
    function getSyntheticLeadingComments(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.leadingComments;
    }
    ts.getSyntheticLeadingComments = getSyntheticLeadingComments;
    function setSyntheticLeadingComments(node, comments) {
        getOrCreateEmitNode(node).leadingComments = comments;
        return node;
    }
    ts.setSyntheticLeadingComments = setSyntheticLeadingComments;
    function addSyntheticLeadingComment(node, kind, text, hasTrailingNewLine) {
        return setSyntheticLeadingComments(node, ts.append(getSyntheticLeadingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
    }
    ts.addSyntheticLeadingComment = addSyntheticLeadingComment;
    function getSyntheticTrailingComments(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.trailingComments;
    }
    ts.getSyntheticTrailingComments = getSyntheticTrailingComments;
    function setSyntheticTrailingComments(node, comments) {
        getOrCreateEmitNode(node).trailingComments = comments;
        return node;
    }
    ts.setSyntheticTrailingComments = setSyntheticTrailingComments;
    function addSyntheticTrailingComment(node, kind, text, hasTrailingNewLine) {
        return setSyntheticTrailingComments(node, ts.append(getSyntheticTrailingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text }));
    }
    ts.addSyntheticTrailingComment = addSyntheticTrailingComment;
    function moveSyntheticComments(node, original) {
        setSyntheticLeadingComments(node, getSyntheticLeadingComments(original));
        setSyntheticTrailingComments(node, getSyntheticTrailingComments(original));
        var emit = getOrCreateEmitNode(original);
        emit.leadingComments = undefined;
        emit.trailingComments = undefined;
        return node;
    }
    ts.moveSyntheticComments = moveSyntheticComments;
    /** @internal */
    function ignoreSourceNewlines(node) {
        getOrCreateEmitNode(node).flags |= 134217728 /* IgnoreSourceNewlines */;
        return node;
    }
    ts.ignoreSourceNewlines = ignoreSourceNewlines;
    /**
     * Gets the constant value to emit for an expression.
     */
    function getConstantValue(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.constantValue;
    }
    ts.getConstantValue = getConstantValue;
    /**
     * Sets the constant value to emit for an expression.
     */
    function setConstantValue(node, value) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.constantValue = value;
        return node;
    }
    ts.setConstantValue = setConstantValue;
    /**
     * Adds an EmitHelper to a node.
     */
    function addEmitHelper(node, helper) {
        var emitNode = getOrCreateEmitNode(node);
        emitNode.helpers = ts.append(emitNode.helpers, helper);
        return node;
    }
    ts.addEmitHelper = addEmitHelper;
    /**
     * Add EmitHelpers to a node.
     */
    function addEmitHelpers(node, helpers) {
        if (ts.some(helpers)) {
            var emitNode = getOrCreateEmitNode(node);
            for (var _i = 0, helpers_1 = helpers; _i < helpers_1.length; _i++) {
                var helper = helpers_1[_i];
                emitNode.helpers = ts.appendIfUnique(emitNode.helpers, helper);
            }
        }
        return node;
    }
    ts.addEmitHelpers = addEmitHelpers;
    /**
     * Removes an EmitHelper from a node.
     */
    function removeEmitHelper(node, helper) {
        var emitNode = node.emitNode;
        if (emitNode) {
            var helpers = emitNode.helpers;
            if (helpers) {
                return ts.orderedRemoveItem(helpers, helper);
            }
        }
        return false;
    }
    ts.removeEmitHelper = removeEmitHelper;
    /**
     * Gets the EmitHelpers of a node.
     */
    function getEmitHelpers(node) {
        var emitNode = node.emitNode;
        return emitNode && emitNode.helpers;
    }
    ts.getEmitHelpers = getEmitHelpers;
    /**
     * Moves matching emit helpers from a source node to a target node.
     */
    function moveEmitHelpers(source, target, predicate) {
        var sourceEmitNode = source.emitNode;
        var sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers;
        if (!ts.some(sourceEmitHelpers))
            return;
        var targetEmitNode = getOrCreateEmitNode(target);
        var helpersRemoved = 0;
        for (var i = 0; i < sourceEmitHelpers.length; i++) {
            var helper = sourceEmitHelpers[i];
            if (predicate(helper)) {
                helpersRemoved++;
                targetEmitNode.helpers = ts.appendIfUnique(targetEmitNode.helpers, helper);
            }
            else if (helpersRemoved > 0) {
                sourceEmitHelpers[i - helpersRemoved] = helper;
            }
        }
        if (helpersRemoved > 0) {
            sourceEmitHelpers.length -= helpersRemoved;
        }
    }
    ts.moveEmitHelpers = moveEmitHelpers;
    /* @internal */
    function compareEmitHelpers(x, y) {
        if (x === y)
            return 0 /* EqualTo */;
        if (x.priority === y.priority)
            return 0 /* EqualTo */;
        if (x.priority === undefined)
            return 1 /* GreaterThan */;
        if (y.priority === undefined)
            return -1 /* LessThan */;
        return ts.compareValues(x.priority, y.priority);
    }
    ts.compareEmitHelpers = compareEmitHelpers;
    function setOriginalNode(node, original) {
        node.original = original;
        if (original) {
            var emitNode = original.emitNode;
            if (emitNode)
                node.emitNode = mergeEmitNode(emitNode, node.emitNode);
        }
        return node;
    }
    ts.setOriginalNode = setOriginalNode;
    function mergeEmitNode(sourceEmitNode, destEmitNode) {
        var flags = sourceEmitNode.flags, leadingComments = sourceEmitNode.leadingComments, trailingComments = sourceEmitNode.trailingComments, commentRange = sourceEmitNode.commentRange, sourceMapRange = sourceEmitNode.sourceMapRange, tokenSourceMapRanges = sourceEmitNode.tokenSourceMapRanges, constantValue = sourceEmitNode.constantValue, helpers = sourceEmitNode.helpers, startsOnNewLine = sourceEmitNode.startsOnNewLine;
        if (!destEmitNode)
            destEmitNode = {};
        // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later.
        if (leadingComments)
            destEmitNode.leadingComments = ts.addRange(leadingComments.slice(), destEmitNode.leadingComments);
        if (trailingComments)
            destEmitNode.trailingComments = ts.addRange(trailingComments.slice(), destEmitNode.trailingComments);
        if (flags)
            destEmitNode.flags = flags;
        if (commentRange)
            destEmitNode.commentRange = commentRange;
        if (sourceMapRange)
            destEmitNode.sourceMapRange = sourceMapRange;
        if (tokenSourceMapRanges)
            destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges);
        if (constantValue !== undefined)
            destEmitNode.constantValue = constantValue;
        if (helpers)
            destEmitNode.helpers = ts.addRange(destEmitNode.helpers, helpers);
        if (startsOnNewLine !== undefined)
            destEmitNode.startsOnNewLine = startsOnNewLine;
        return destEmitNode;
    }
    function mergeTokenSourceMapRanges(sourceRanges, destRanges) {
        if (!destRanges)
            destRanges = [];
        for (var key in sourceRanges) {
            destRanges[key] = sourceRanges[key];
        }
        return destRanges;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    ts.nullTransformationContext = {
        enableEmitNotification: ts.noop,
        enableSubstitution: ts.noop,
        endLexicalEnvironment: ts.returnUndefined,
        getCompilerOptions: function () { return ({}); },
        getEmitHost: ts.notImplemented,
        getEmitResolver: ts.notImplemented,
        setLexicalEnvironmentFlags: ts.noop,
        getLexicalEnvironmentFlags: function () { return 0; },
        hoistFunctionDeclaration: ts.noop,
        hoistVariableDeclaration: ts.noop,
        addInitializationStatement: ts.noop,
        isEmitNotificationEnabled: ts.notImplemented,
        isSubstitutionEnabled: ts.notImplemented,
        onEmitNode: ts.noop,
        onSubstituteNode: ts.notImplemented,
        readEmitHelpers: ts.notImplemented,
        requestEmitHelper: ts.noop,
        resumeLexicalEnvironment: ts.noop,
        startLexicalEnvironment: ts.noop,
        suspendLexicalEnvironment: ts.noop,
        addDiagnostic: ts.noop,
    };
    function createTypeCheck(value, tag) {
        return tag === "undefined"
            ? ts.createStrictEquality(value, ts.createVoidZero())
            : ts.createStrictEquality(ts.createTypeOf(value), ts.createLiteral(tag));
    }
    ts.createTypeCheck = createTypeCheck;
    function createMemberAccessForPropertyName(target, memberName, location) {
        if (ts.isComputedPropertyName(memberName)) {
            return ts.setTextRange(ts.createElementAccess(target, memberName.expression), location);
        }
        else {
            var expression = ts.setTextRange((ts.isIdentifier(memberName) || ts.isPrivateIdentifier(memberName))
                ? ts.createPropertyAccess(target, memberName)
                : ts.createElementAccess(target, memberName), memberName);
            ts.getOrCreateEmitNode(expression).flags |= 64 /* NoNestedSourceMaps */;
            return expression;
        }
    }
    ts.createMemberAccessForPropertyName = createMemberAccessForPropertyName;
    function createFunctionCall(func, thisArg, argumentsList, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "call"), 
        /*typeArguments*/ undefined, __spreadArrays([
            thisArg
        ], argumentsList)), location);
    }
    ts.createFunctionCall = createFunctionCall;
    function createFunctionApply(func, thisArg, argumentsExpression, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "apply"), 
        /*typeArguments*/ undefined, [
            thisArg,
            argumentsExpression
        ]), location);
    }
    ts.createFunctionApply = createFunctionApply;
    function createArraySlice(array, start) {
        var argumentsList = [];
        if (start !== undefined) {
            argumentsList.push(typeof start === "number" ? ts.createLiteral(start) : start);
        }
        return ts.createCall(ts.createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList);
    }
    ts.createArraySlice = createArraySlice;
    function createArrayConcat(array, values) {
        return ts.createCall(ts.createPropertyAccess(array, "concat"), 
        /*typeArguments*/ undefined, values);
    }
    ts.createArrayConcat = createArrayConcat;
    function createMathPow(left, right, location) {
        return ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Math"), "pow"), 
        /*typeArguments*/ undefined, [left, right]), location);
    }
    ts.createMathPow = createMathPow;
    function createReactNamespace(reactNamespace, parent) {
        // To ensure the emit resolver can properly resolve the namespace, we need to
        // treat this identifier as if it were a source tree node by clearing the `Synthesized`
        // flag and setting a parent node.
        var react = ts.createIdentifier(reactNamespace || "React");
        react.flags &= ~8 /* Synthesized */;
        // Set the parent that is in parse tree
        // this makes sure that parent chain is intact for checker to traverse complete scope tree
        react.parent = ts.getParseTreeNode(parent);
        return react;
    }
    function createJsxFactoryExpressionFromEntityName(jsxFactory, parent) {
        if (ts.isQualifiedName(jsxFactory)) {
            var left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent);
            var right = ts.createIdentifier(ts.idText(jsxFactory.right));
            right.escapedText = jsxFactory.right.escapedText;
            return ts.createPropertyAccess(left, right);
        }
        else {
            return createReactNamespace(ts.idText(jsxFactory), parent);
        }
    }
    function createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parent) {
        return jsxFactoryEntity ?
            createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) :
            ts.createPropertyAccess(createReactNamespace(reactNamespace, parent), "createElement");
    }
    function createExpressionForJsxElement(jsxFactoryEntity, reactNamespace, tagName, props, children, parentElement, location) {
        var argumentsList = [tagName];
        if (props) {
            argumentsList.push(props);
        }
        if (children && children.length > 0) {
            if (!props) {
                argumentsList.push(ts.createNull());
            }
            if (children.length > 1) {
                for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
                    var child = children_2[_i];
                    startOnNewLine(child);
                    argumentsList.push(child);
                }
            }
            else {
                argumentsList.push(children[0]);
            }
        }
        return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), 
        /*typeArguments*/ undefined, argumentsList), location);
    }
    ts.createExpressionForJsxElement = createExpressionForJsxElement;
    function createExpressionForJsxFragment(jsxFactoryEntity, reactNamespace, children, parentElement, location) {
        var tagName = ts.createPropertyAccess(createReactNamespace(reactNamespace, parentElement), "Fragment");
        var argumentsList = [tagName];
        argumentsList.push(ts.createNull());
        if (children && children.length > 0) {
            if (children.length > 1) {
                for (var _i = 0, children_3 = children; _i < children_3.length; _i++) {
                    var child = children_3[_i];
                    startOnNewLine(child);
                    argumentsList.push(child);
                }
            }
            else {
                argumentsList.push(children[0]);
            }
        }
        return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), 
        /*typeArguments*/ undefined, argumentsList), location);
    }
    ts.createExpressionForJsxFragment = createExpressionForJsxFragment;
    // Helpers
    /**
     * Gets an identifier for the name of an *unscoped* emit helper.
     */
    function getUnscopedHelperName(name) {
        return ts.setEmitFlags(ts.createIdentifier(name), 4096 /* HelperName */ | 2 /* AdviseOnEmitNode */);
    }
    ts.getUnscopedHelperName = getUnscopedHelperName;
    ts.valuesHelper = {
        name: "typescript:values",
        importName: "__values",
        scoped: false,
        text: "\n            var __values = (this && this.__values) || function(o) {\n                var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n                if (m) return m.call(o);\n                if (o && typeof o.length === \"number\") return {\n                    next: function () {\n                        if (o && i >= o.length) o = void 0;\n                        return { value: o && o[i++], done: !o };\n                    }\n                };\n                throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n            };"
    };
    function createValuesHelper(context, expression, location) {
        context.requestEmitHelper(ts.valuesHelper);
        return ts.setTextRange(ts.createCall(getUnscopedHelperName("__values"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
    ts.createValuesHelper = createValuesHelper;
    ts.readHelper = {
        name: "typescript:read",
        importName: "__read",
        scoped: false,
        text: "\n            var __read = (this && this.__read) || function (o, n) {\n                var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n                if (!m) return o;\n                var i = m.call(o), r, ar = [], e;\n                try {\n                    while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n                }\n                catch (error) { e = { error: error }; }\n                finally {\n                    try {\n                        if (r && !r.done && (m = i[\"return\"])) m.call(i);\n                    }\n                    finally { if (e) throw e.error; }\n                }\n                return ar;\n            };"
    };
    function createReadHelper(context, iteratorRecord, count, location) {
        context.requestEmitHelper(ts.readHelper);
        return ts.setTextRange(ts.createCall(getUnscopedHelperName("__read"), 
        /*typeArguments*/ undefined, count !== undefined
            ? [iteratorRecord, ts.createLiteral(count)]
            : [iteratorRecord]), location);
    }
    ts.createReadHelper = createReadHelper;
    ts.spreadHelper = {
        name: "typescript:spread",
        importName: "__spread",
        scoped: false,
        dependencies: [ts.readHelper],
        text: "\n            var __spread = (this && this.__spread) || function () {\n                for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));\n                return ar;\n            };"
    };
    function createSpreadHelper(context, argumentList, location) {
        context.requestEmitHelper(ts.spreadHelper);
        return ts.setTextRange(ts.createCall(getUnscopedHelperName("__spread"), 
        /*typeArguments*/ undefined, argumentList), location);
    }
    ts.createSpreadHelper = createSpreadHelper;
    ts.spreadArraysHelper = {
        name: "typescript:spreadArrays",
        importName: "__spreadArrays",
        scoped: false,
        text: "\n            var __spreadArrays = (this && this.__spreadArrays) || function () {\n                for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n                for (var r = Array(s), k = 0, i = 0; i < il; i++)\n                    for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n                        r[k] = a[j];\n                return r;\n            };"
    };
    function createSpreadArraysHelper(context, argumentList, location) {
        context.requestEmitHelper(ts.spreadArraysHelper);
        return ts.setTextRange(ts.createCall(getUnscopedHelperName("__spreadArrays"), 
        /*typeArguments*/ undefined, argumentList), location);
    }
    ts.createSpreadArraysHelper = createSpreadArraysHelper;
    // Utilities
    function createForOfBindingStatement(node, boundValue) {
        if (ts.isVariableDeclarationList(node)) {
            var firstDeclaration = ts.first(node.declarations);
            var updatedDeclaration = ts.updateVariableDeclaration(firstDeclaration, firstDeclaration.name, 
            /*typeNode*/ undefined, boundValue);
            return ts.setTextRange(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.updateVariableDeclarationList(node, [updatedDeclaration])), 
            /*location*/ node);
        }
        else {
            var updatedExpression = ts.setTextRange(ts.createAssignment(node, boundValue), /*location*/ node);
            return ts.setTextRange(ts.createStatement(updatedExpression), /*location*/ node);
        }
    }
    ts.createForOfBindingStatement = createForOfBindingStatement;
    function insertLeadingStatement(dest, source) {
        if (ts.isBlock(dest)) {
            return ts.updateBlock(dest, ts.setTextRange(ts.createNodeArray(__spreadArrays([source], dest.statements)), dest.statements));
        }
        else {
            return ts.createBlock(ts.createNodeArray([dest, source]), /*multiLine*/ true);
        }
    }
    ts.insertLeadingStatement = insertLeadingStatement;
    function restoreEnclosingLabel(node, outermostLabeledStatement, afterRestoreLabelCallback) {
        if (!outermostLabeledStatement) {
            return node;
        }
        var updated = ts.updateLabel(outermostLabeledStatement, outermostLabeledStatement.label, outermostLabeledStatement.statement.kind === 238 /* LabeledStatement */
            ? restoreEnclosingLabel(node, outermostLabeledStatement.statement)
            : node);
        if (afterRestoreLabelCallback) {
            afterRestoreLabelCallback(outermostLabeledStatement);
        }
        return updated;
    }
    ts.restoreEnclosingLabel = restoreEnclosingLabel;
    function shouldBeCapturedInTempVariable(node, cacheIdentifiers) {
        var target = ts.skipParentheses(node);
        switch (target.kind) {
            case 75 /* Identifier */:
                return cacheIdentifiers;
            case 104 /* ThisKeyword */:
            case 8 /* NumericLiteral */:
            case 9 /* BigIntLiteral */:
            case 10 /* StringLiteral */:
                return false;
            case 192 /* ArrayLiteralExpression */:
                var elements = target.elements;
                if (elements.length === 0) {
                    return false;
                }
                return true;
            case 193 /* ObjectLiteralExpression */:
                return target.properties.length > 0;
            default:
                return true;
        }
    }
    function createCallBinding(expression, recordTempVariable, languageVersion, cacheIdentifiers) {
        if (cacheIdentifiers === void 0) { cacheIdentifiers = false; }
        var callee = skipOuterExpressions(expression, 15 /* All */);
        var thisArg;
        var target;
        if (ts.isSuperProperty(callee)) {
            thisArg = ts.createThis();
            target = callee;
        }
        else if (callee.kind === 102 /* SuperKeyword */) {
            thisArg = ts.createThis();
            target = languageVersion < 2 /* ES2015 */
                ? ts.setTextRange(ts.createIdentifier("_super"), callee)
                : callee;
        }
        else if (ts.getEmitFlags(callee) & 4096 /* HelperName */) {
            thisArg = ts.createVoidZero();
            target = parenthesizeForAccess(callee);
        }
        else {
            switch (callee.kind) {
                case 194 /* PropertyAccessExpression */: {
                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
                        // for `a.b()` target is `(_a = a).b` and thisArg is `_a`
                        thisArg = ts.createTempVariable(recordTempVariable);
                        target = ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.name);
                        ts.setTextRange(target, callee);
                    }
                    else {
                        thisArg = callee.expression;
                        target = callee;
                    }
                    break;
                }
                case 195 /* ElementAccessExpression */: {
                    if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) {
                        // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a`
                        thisArg = ts.createTempVariable(recordTempVariable);
                        target = ts.createElementAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.argumentExpression);
                        ts.setTextRange(target, callee);
                    }
                    else {
                        thisArg = callee.expression;
                        target = callee;
                    }
                    break;
                }
                default: {
                    // for `a()` target is `a` and thisArg is `void 0`
                    thisArg = ts.createVoidZero();
                    target = parenthesizeForAccess(expression);
                    break;
                }
            }
        }
        return { target: target, thisArg: thisArg };
    }
    ts.createCallBinding = createCallBinding;
    function inlineExpressions(expressions) {
        // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call
        // stack size exceeded" errors.
        return expressions.length > 10
            ? ts.createCommaList(expressions)
            : ts.reduceLeft(expressions, ts.createComma);
    }
    ts.inlineExpressions = inlineExpressions;
    function createExpressionFromEntityName(node) {
        if (ts.isQualifiedName(node)) {
            var left = createExpressionFromEntityName(node.left);
            var right = ts.getMutableClone(node.right);
            return ts.setTextRange(ts.createPropertyAccess(left, right), node);
        }
        else {
            return ts.getMutableClone(node);
        }
    }
    ts.createExpressionFromEntityName = createExpressionFromEntityName;
    function createExpressionForPropertyName(memberName) {
        if (ts.isIdentifier(memberName)) {
            return ts.createLiteral(memberName);
        }
        else if (ts.isComputedPropertyName(memberName)) {
            return ts.getMutableClone(memberName.expression);
        }
        else {
            return ts.getMutableClone(memberName);
        }
    }
    ts.createExpressionForPropertyName = createExpressionForPropertyName;
    function createExpressionForObjectLiteralElementLike(node, property, receiver) {
        if (property.name && ts.isPrivateIdentifier(property.name)) {
            ts.Debug.failBadSyntaxKind(property.name, "Private identifiers are not allowed in object literals.");
        }
        switch (property.kind) {
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
                return createExpressionForAccessorDeclaration(node.properties, property, receiver, !!node.multiLine);
            case 281 /* PropertyAssignment */:
                return createExpressionForPropertyAssignment(property, receiver);
            case 282 /* ShorthandPropertyAssignment */:
                return createExpressionForShorthandPropertyAssignment(property, receiver);
            case 161 /* MethodDeclaration */:
                return createExpressionForMethodDeclaration(property, receiver);
        }
    }
    ts.createExpressionForObjectLiteralElementLike = createExpressionForObjectLiteralElementLike;
    function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) {
        var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
        if (property === firstAccessor) {
            var properties_7 = [];
            if (getAccessor) {
                var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, getAccessor.parameters, 
                /*type*/ undefined, getAccessor.body // TODO: GH#18217
                );
                ts.setTextRange(getterFunction, getAccessor);
                ts.setOriginalNode(getterFunction, getAccessor);
                var getter = ts.createPropertyAssignment("get", getterFunction);
                properties_7.push(getter);
            }
            if (setAccessor) {
                var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, setAccessor.parameters, 
                /*type*/ undefined, setAccessor.body // TODO: GH#18217
                );
                ts.setTextRange(setterFunction, setAccessor);
                ts.setOriginalNode(setterFunction, setAccessor);
                var setter = ts.createPropertyAssignment("set", setterFunction);
                properties_7.push(setter);
            }
            properties_7.push(ts.createPropertyAssignment("enumerable", getAccessor || setAccessor ? ts.createFalse() : ts.createTrue()));
            properties_7.push(ts.createPropertyAssignment("configurable", ts.createTrue()));
            var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                receiver,
                createExpressionForPropertyName(property.name),
                ts.createObjectLiteral(properties_7, multiLine)
            ]), 
            /*location*/ firstAccessor);
            return ts.aggregateTransformFlags(expression);
        }
        return undefined;
    }
    function createExpressionForPropertyAssignment(property, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), property.initializer), property), property));
    }
    function createExpressionForShorthandPropertyAssignment(property, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), ts.getSynthesizedClone(property.name)), 
        /*location*/ property), 
        /*original*/ property));
    }
    function createExpressionForMethodDeclaration(method, receiver) {
        return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(method.modifiers, method.asteriskToken, 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, method.parameters, 
        /*type*/ undefined, method.body // TODO: GH#18217
        ), 
        /*location*/ method), 
        /*original*/ method)), 
        /*location*/ method), 
        /*original*/ method));
    }
    /**
     * Gets the internal name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the body of an ES5 class function body. An internal name will *never*
     * be prefixed with an module or namespace export modifier like "exports." when emitted as an
     * expression. An internal name will also *never* be renamed due to a collision with a block
     * scoped variable.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getInternalName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */ | 32768 /* InternalName */);
    }
    ts.getInternalName = getInternalName;
    /**
     * Gets whether an identifier should only be referred to by its internal name.
     */
    function isInternalName(node) {
        return (ts.getEmitFlags(node) & 32768 /* InternalName */) !== 0;
    }
    ts.isInternalName = isInternalName;
    /**
     * Gets the local name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A
     * local name will *never* be prefixed with an module or namespace export modifier like
     * "exports." when emitted as an expression.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getLocalName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */);
    }
    ts.getLocalName = getLocalName;
    /**
     * Gets whether an identifier should only be referred to by its local name.
     */
    function isLocalName(node) {
        return (ts.getEmitFlags(node) & 16384 /* LocalName */) !== 0;
    }
    ts.isLocalName = isLocalName;
    /**
     * Gets the export name of a declaration. This is primarily used for declarations that can be
     * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An
     * export name will *always* be prefixed with an module or namespace export modifier like
     * `"exports."` when emitted as an expression if the name points to an exported symbol.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getExportName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps, 8192 /* ExportName */);
    }
    ts.getExportName = getExportName;
    /**
     * Gets whether an identifier should only be referred to by its export representation if the
     * name points to an exported symbol.
     */
    function isExportName(node) {
        return (ts.getEmitFlags(node) & 8192 /* ExportName */) !== 0;
    }
    ts.isExportName = isExportName;
    /**
     * Gets the name of a declaration for use in declarations.
     *
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getDeclarationName(node, allowComments, allowSourceMaps) {
        return getName(node, allowComments, allowSourceMaps);
    }
    ts.getDeclarationName = getDeclarationName;
    function getName(node, allowComments, allowSourceMaps, emitFlags) {
        if (emitFlags === void 0) { emitFlags = 0; }
        var nodeName = ts.getNameOfDeclaration(node);
        if (nodeName && ts.isIdentifier(nodeName) && !ts.isGeneratedIdentifier(nodeName)) {
            var name = ts.getMutableClone(nodeName);
            emitFlags |= ts.getEmitFlags(nodeName);
            if (!allowSourceMaps)
                emitFlags |= 48 /* NoSourceMap */;
            if (!allowComments)
                emitFlags |= 1536 /* NoComments */;
            if (emitFlags)
                ts.setEmitFlags(name, emitFlags);
            return name;
        }
        return ts.getGeneratedNameForNode(node);
    }
    /**
     * Gets the exported name of a declaration for use in expressions.
     *
     * An exported name will *always* be prefixed with an module or namespace export modifier like
     * "exports." if the name points to an exported symbol.
     *
     * @param ns The namespace identifier.
     * @param node The declaration.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getExternalModuleOrNamespaceExportName(ns, node, allowComments, allowSourceMaps) {
        if (ns && ts.hasModifier(node, 1 /* Export */)) {
            return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps);
        }
        return getExportName(node, allowComments, allowSourceMaps);
    }
    ts.getExternalModuleOrNamespaceExportName = getExternalModuleOrNamespaceExportName;
    /**
     * Gets a namespace-qualified name for use in expressions.
     *
     * @param ns The namespace identifier.
     * @param name The name.
     * @param allowComments A value indicating whether comments may be emitted for the name.
     * @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
     */
    function getNamespaceMemberName(ns, name, allowComments, allowSourceMaps) {
        var qualifiedName = ts.createPropertyAccess(ns, ts.nodeIsSynthesized(name) ? name : ts.getSynthesizedClone(name));
        ts.setTextRange(qualifiedName, name);
        var emitFlags = 0;
        if (!allowSourceMaps)
            emitFlags |= 48 /* NoSourceMap */;
        if (!allowComments)
            emitFlags |= 1536 /* NoComments */;
        if (emitFlags)
            ts.setEmitFlags(qualifiedName, emitFlags);
        return qualifiedName;
    }
    ts.getNamespaceMemberName = getNamespaceMemberName;
    function convertToFunctionBody(node, multiLine) {
        return ts.isBlock(node) ? node : ts.setTextRange(ts.createBlock([ts.setTextRange(ts.createReturn(node), node)], multiLine), node);
    }
    ts.convertToFunctionBody = convertToFunctionBody;
    function convertFunctionDeclarationToExpression(node) {
        if (!node.body)
            return ts.Debug.fail();
        var updated = ts.createFunctionExpression(node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body);
        ts.setOriginalNode(updated, node);
        ts.setTextRange(updated, node);
        if (ts.getStartsOnNewLine(node)) {
            ts.setStartsOnNewLine(updated, /*newLine*/ true);
        }
        ts.aggregateTransformFlags(updated);
        return updated;
    }
    ts.convertFunctionDeclarationToExpression = convertFunctionDeclarationToExpression;
    function isUseStrictPrologue(node) {
        return ts.isStringLiteral(node.expression) && node.expression.text === "use strict";
    }
    /**
     * Add any necessary prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     *
     * @param target: result statements array
     * @param source: origin statements array
     * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives
     * @param visitor: Optional callback used to visit any custom prologue directives.
     */
    function addPrologue(target, source, ensureUseStrict, visitor) {
        var offset = addStandardPrologue(target, source, ensureUseStrict);
        return addCustomPrologue(target, source, offset, visitor);
    }
    ts.addPrologue = addPrologue;
    /**
     * Add just the standard (string-expression) prologue-directives into target statement-array.
     * The function needs to be called during each transformation step.
     * This function needs to be called whenever we transform the statement
     * list of a source file, namespace, or function-like body.
     */
    function addStandardPrologue(target, source, ensureUseStrict) {
        ts.Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array");
        var foundUseStrict = false;
        var statementOffset = 0;
        var numStatements = source.length;
        while (statementOffset < numStatements) {
            var statement = source[statementOffset];
            if (ts.isPrologueDirective(statement)) {
                if (isUseStrictPrologue(statement)) {
                    foundUseStrict = true;
                }
                target.push(statement);
            }
            else {
                break;
            }
            statementOffset++;
        }
        if (ensureUseStrict && !foundUseStrict) {
            target.push(startOnNewLine(ts.createStatement(ts.createLiteral("use strict"))));
        }
        return statementOffset;
    }
    ts.addStandardPrologue = addStandardPrologue;
    function addCustomPrologue(target, source, statementOffset, visitor, filter) {
        if (filter === void 0) { filter = ts.returnTrue; }
        var numStatements = source.length;
        while (statementOffset !== undefined && statementOffset < numStatements) {
            var statement = source[statementOffset];
            if (ts.getEmitFlags(statement) & 1048576 /* CustomPrologue */ && filter(statement)) {
                ts.append(target, visitor ? ts.visitNode(statement, visitor, ts.isStatement) : statement);
            }
            else {
                break;
            }
            statementOffset++;
        }
        return statementOffset;
    }
    ts.addCustomPrologue = addCustomPrologue;
    function findUseStrictPrologue(statements) {
        for (var _i = 0, statements_4 = statements; _i < statements_4.length; _i++) {
            var statement = statements_4[_i];
            if (ts.isPrologueDirective(statement)) {
                if (isUseStrictPrologue(statement)) {
                    return statement;
                }
            }
            else {
                break;
            }
        }
        return undefined;
    }
    ts.findUseStrictPrologue = findUseStrictPrologue;
    function startsWithUseStrict(statements) {
        var firstStatement = ts.firstOrUndefined(statements);
        return firstStatement !== undefined
            && ts.isPrologueDirective(firstStatement)
            && isUseStrictPrologue(firstStatement);
    }
    ts.startsWithUseStrict = startsWithUseStrict;
    /**
     * Ensures "use strict" directive is added
     *
     * @param statements An array of statements
     */
    function ensureUseStrict(statements) {
        var foundUseStrict = findUseStrictPrologue(statements);
        if (!foundUseStrict) {
            return ts.setTextRange(ts.createNodeArray(__spreadArrays([
                startOnNewLine(ts.createStatement(ts.createLiteral("use strict")))
            ], statements)), statements);
        }
        return statements;
    }
    ts.ensureUseStrict = ensureUseStrict;
    /**
     * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
     * order of operations.
     *
     * @param binaryOperator The operator for the BinaryExpression.
     * @param operand The operand for the BinaryExpression.
     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
     *                           BinaryExpression.
     */
    function parenthesizeBinaryOperand(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
        var skipped = ts.skipPartiallyEmittedExpressions(operand);
        // If the resulting expression is already parenthesized, we do not need to do any further processing.
        if (skipped.kind === 200 /* ParenthesizedExpression */) {
            return operand;
        }
        return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand)
            ? ts.createParen(operand)
            : operand;
    }
    ts.parenthesizeBinaryOperand = parenthesizeBinaryOperand;
    /**
     * Determines whether the operand to a BinaryExpression needs to be parenthesized.
     *
     * @param binaryOperator The operator for the BinaryExpression.
     * @param operand The operand for the BinaryExpression.
     * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the
     *                           BinaryExpression.
     */
    function binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) {
        // If the operand has lower precedence, then it needs to be parenthesized to preserve the
        // intent of the expression. For example, if the operand is `a + b` and the operator is
        // `*`, then we need to parenthesize the operand to preserve the intended order of
        // operations: `(a + b) * x`.
        //
        // If the operand has higher precedence, then it does not need to be parenthesized. For
        // example, if the operand is `a * b` and the operator is `+`, then we do not need to
        // parenthesize to preserve the intended order of operations: `a * b + x`.
        //
        // If the operand has the same precedence, then we need to check the associativity of
        // the operator based on whether this is the left or right operand of the expression.
        //
        // For example, if `a / d` is on the right of operator `*`, we need to parenthesize
        // to preserve the intended order of operations: `x * (a / d)`
        //
        // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve
        // the intended order of operations: `(a ** b) ** c`
        var binaryOperatorPrecedence = ts.getOperatorPrecedence(209 /* BinaryExpression */, binaryOperator);
        var binaryOperatorAssociativity = ts.getOperatorAssociativity(209 /* BinaryExpression */, binaryOperator);
        var emittedOperand = ts.skipPartiallyEmittedExpressions(operand);
        if (!isLeftSideOfBinary && operand.kind === 202 /* ArrowFunction */ && binaryOperatorPrecedence > 3) {
            // We need to parenthesize arrow functions on the right side to avoid it being
            // parsed as parenthesized expression: `a && (() => {})`
            return true;
        }
        var operandPrecedence = ts.getExpressionPrecedence(emittedOperand);
        switch (ts.compareValues(operandPrecedence, binaryOperatorPrecedence)) {
            case -1 /* LessThan */:
                // If the operand is the right side of a right-associative binary operation
                // and is a yield expression, then we do not need parentheses.
                if (!isLeftSideOfBinary
                    && binaryOperatorAssociativity === 1 /* Right */
                    && operand.kind === 212 /* YieldExpression */) {
                    return false;
                }
                return true;
            case 1 /* GreaterThan */:
                return false;
            case 0 /* EqualTo */:
                if (isLeftSideOfBinary) {
                    // No need to parenthesize the left operand when the binary operator is
                    // left associative:
                    //  (a*b)/x    -> a*b/x
                    //  (a**b)/x   -> a**b/x
                    //
                    // Parentheses are needed for the left operand when the binary operator is
                    // right associative:
                    //  (a/b)**x   -> (a/b)**x
                    //  (a**b)**x  -> (a**b)**x
                    return binaryOperatorAssociativity === 1 /* Right */;
                }
                else {
                    if (ts.isBinaryExpression(emittedOperand)
                        && emittedOperand.operatorToken.kind === binaryOperator) {
                        // No need to parenthesize the right operand when the binary operator and
                        // operand are the same and one of the following:
                        //  x*(a*b)     => x*a*b
                        //  x|(a|b)     => x|a|b
                        //  x&(a&b)     => x&a&b
                        //  x^(a^b)     => x^a^b
                        if (operatorHasAssociativeProperty(binaryOperator)) {
                            return false;
                        }
                        // No need to parenthesize the right operand when the binary operator
                        // is plus (+) if both the left and right operands consist solely of either
                        // literals of the same kind or binary plus (+) expressions for literals of
                        // the same kind (recursively).
                        //  "a"+(1+2)       => "a"+(1+2)
                        //  "a"+("b"+"c")   => "a"+"b"+"c"
                        if (binaryOperator === 39 /* PlusToken */) {
                            var leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : 0 /* Unknown */;
                            if (ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) {
                                return false;
                            }
                        }
                    }
                    // No need to parenthesize the right operand when the operand is right
                    // associative:
                    //  x/(a**b)    -> x/a**b
                    //  x**(a**b)   -> x**a**b
                    //
                    // Parentheses are needed for the right operand when the operand is left
                    // associative:
                    //  x/(a*b)     -> x/(a*b)
                    //  x**(a/b)    -> x**(a/b)
                    var operandAssociativity = ts.getExpressionAssociativity(emittedOperand);
                    return operandAssociativity === 0 /* Left */;
                }
        }
    }
    /**
     * Determines whether a binary operator is mathematically associative.
     *
     * @param binaryOperator The binary operator.
     */
    function operatorHasAssociativeProperty(binaryOperator) {
        // The following operators are associative in JavaScript:
        //  (a*b)*c     -> a*(b*c)  -> a*b*c
        //  (a|b)|c     -> a|(b|c)  -> a|b|c
        //  (a&b)&c     -> a&(b&c)  -> a&b&c
        //  (a^b)^c     -> a^(b^c)  -> a^b^c
        //
        // While addition is associative in mathematics, JavaScript's `+` is not
        // guaranteed to be associative as it is overloaded with string concatenation.
        return binaryOperator === 41 /* AsteriskToken */
            || binaryOperator === 51 /* BarToken */
            || binaryOperator === 50 /* AmpersandToken */
            || binaryOperator === 52 /* CaretToken */;
    }
    /**
     * This function determines whether an expression consists of a homogeneous set of
     * literal expressions or binary plus expressions that all share the same literal kind.
     * It is used to determine whether the right-hand operand of a binary plus expression can be
     * emitted without parentheses.
     */
    function getLiteralKindOfBinaryPlusOperand(node) {
        node = ts.skipPartiallyEmittedExpressions(node);
        if (ts.isLiteralKind(node.kind)) {
            return node.kind;
        }
        if (node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 39 /* PlusToken */) {
            if (node.cachedLiteralKind !== undefined) {
                return node.cachedLiteralKind;
            }
            var leftKind = getLiteralKindOfBinaryPlusOperand(node.left);
            var literalKind = ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(node.right) ? leftKind :
                0 /* Unknown */;
            node.cachedLiteralKind = literalKind;
            return literalKind;
        }
        return 0 /* Unknown */;
    }
    function parenthesizeForConditionalHead(condition) {
        var conditionalPrecedence = ts.getOperatorPrecedence(210 /* ConditionalExpression */, 57 /* QuestionToken */);
        var emittedCondition = ts.skipPartiallyEmittedExpressions(condition);
        var conditionPrecedence = ts.getExpressionPrecedence(emittedCondition);
        if (ts.compareValues(conditionPrecedence, conditionalPrecedence) !== 1 /* GreaterThan */) {
            return ts.createParen(condition);
        }
        return condition;
    }
    ts.parenthesizeForConditionalHead = parenthesizeForConditionalHead;
    function parenthesizeSubexpressionOfConditionalExpression(e) {
        // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions
        // so in case when comma expression is introduced as a part of previous transformations
        // if should be wrapped in parens since comma operator has the lowest precedence
        var emittedExpression = ts.skipPartiallyEmittedExpressions(e);
        return isCommaSequence(emittedExpression)
            ? ts.createParen(e)
            : e;
    }
    ts.parenthesizeSubexpressionOfConditionalExpression = parenthesizeSubexpressionOfConditionalExpression;
    /**
     *  [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but
     *  has a lookahead restriction for `function`, `async function`, and `class`.
     *
     * Basically, that means we need to parenthesize in the following cases:
     *
     * - BinaryExpression of CommaToken
     * - CommaList (synthetic list of multiple comma expressions)
     * - FunctionExpression
     * - ClassExpression
     */
    function parenthesizeDefaultExpression(e) {
        var check = ts.skipPartiallyEmittedExpressions(e);
        var needsParens = isCommaSequence(check);
        if (!needsParens) {
            switch (getLeftmostExpression(check, /*stopAtCallExpression*/ false).kind) {
                case 214 /* ClassExpression */:
                case 201 /* FunctionExpression */:
                    needsParens = true;
            }
        }
        return needsParens ? ts.createParen(e) : e;
    }
    ts.parenthesizeDefaultExpression = parenthesizeDefaultExpression;
    /**
     * Wraps an expression in parentheses if it is needed in order to use the expression
     * as the expression of a NewExpression node.
     *
     * @param expression The Expression node.
     */
    function parenthesizeForNew(expression) {
        var leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true);
        switch (leftmostExpr.kind) {
            case 196 /* CallExpression */:
                return ts.createParen(expression);
            case 197 /* NewExpression */:
                return !leftmostExpr.arguments
                    ? ts.createParen(expression)
                    : expression;
        }
        return parenthesizeForAccess(expression);
    }
    ts.parenthesizeForNew = parenthesizeForNew;
    /**
     * Wraps an expression in parentheses if it is needed in order to use the expression for
     * property or element access.
     *
     * @param expr The expression node.
     */
    function parenthesizeForAccess(expression) {
        // isLeftHandSideExpression is almost the correct criterion for when it is not necessary
        // to parenthesize the expression before a dot. The known exception is:
        //
        //    NewExpression:
        //       new C.x        -> not the same as (new C).x
        //
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        if (ts.isLeftHandSideExpression(emittedExpression)
            && (emittedExpression.kind !== 197 /* NewExpression */ || emittedExpression.arguments)) {
            return expression;
        }
        return ts.setTextRange(ts.createParen(expression), expression);
    }
    ts.parenthesizeForAccess = parenthesizeForAccess;
    function parenthesizePostfixOperand(operand) {
        return ts.isLeftHandSideExpression(operand)
            ? operand
            : ts.setTextRange(ts.createParen(operand), operand);
    }
    ts.parenthesizePostfixOperand = parenthesizePostfixOperand;
    function parenthesizePrefixOperand(operand) {
        return ts.isUnaryExpression(operand)
            ? operand
            : ts.setTextRange(ts.createParen(operand), operand);
    }
    ts.parenthesizePrefixOperand = parenthesizePrefixOperand;
    function parenthesizeListElements(elements) {
        var result;
        for (var i = 0; i < elements.length; i++) {
            var element = parenthesizeExpressionForList(elements[i]);
            if (result !== undefined || element !== elements[i]) {
                if (result === undefined) {
                    result = elements.slice(0, i);
                }
                result.push(element);
            }
        }
        if (result !== undefined) {
            return ts.setTextRange(ts.createNodeArray(result, elements.hasTrailingComma), elements);
        }
        return elements;
    }
    ts.parenthesizeListElements = parenthesizeListElements;
    function parenthesizeExpressionForList(expression) {
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        var expressionPrecedence = ts.getExpressionPrecedence(emittedExpression);
        var commaPrecedence = ts.getOperatorPrecedence(209 /* BinaryExpression */, 27 /* CommaToken */);
        return expressionPrecedence > commaPrecedence
            ? expression
            : ts.setTextRange(ts.createParen(expression), expression);
    }
    ts.parenthesizeExpressionForList = parenthesizeExpressionForList;
    function parenthesizeExpressionForExpressionStatement(expression) {
        var emittedExpression = ts.skipPartiallyEmittedExpressions(expression);
        if (ts.isCallExpression(emittedExpression)) {
            var callee = emittedExpression.expression;
            var kind = ts.skipPartiallyEmittedExpressions(callee).kind;
            if (kind === 201 /* FunctionExpression */ || kind === 202 /* ArrowFunction */) {
                var mutableCall = ts.getMutableClone(emittedExpression);
                mutableCall.expression = ts.setTextRange(ts.createParen(callee), callee);
                return recreateOuterExpressions(expression, mutableCall, 8 /* PartiallyEmittedExpressions */);
            }
        }
        var leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind;
        if (leftmostExpressionKind === 193 /* ObjectLiteralExpression */ || leftmostExpressionKind === 201 /* FunctionExpression */) {
            return ts.setTextRange(ts.createParen(expression), expression);
        }
        return expression;
    }
    ts.parenthesizeExpressionForExpressionStatement = parenthesizeExpressionForExpressionStatement;
    function parenthesizeConditionalTypeMember(member) {
        return member.kind === 180 /* ConditionalType */ ? ts.createParenthesizedType(member) : member;
    }
    ts.parenthesizeConditionalTypeMember = parenthesizeConditionalTypeMember;
    function parenthesizeElementTypeMember(member) {
        switch (member.kind) {
            case 178 /* UnionType */:
            case 179 /* IntersectionType */:
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
                return ts.createParenthesizedType(member);
        }
        return parenthesizeConditionalTypeMember(member);
    }
    ts.parenthesizeElementTypeMember = parenthesizeElementTypeMember;
    function parenthesizeArrayTypeMember(member) {
        switch (member.kind) {
            case 172 /* TypeQuery */:
            case 184 /* TypeOperator */:
            case 181 /* InferType */:
                return ts.createParenthesizedType(member);
        }
        return parenthesizeElementTypeMember(member);
    }
    ts.parenthesizeArrayTypeMember = parenthesizeArrayTypeMember;
    function parenthesizeElementTypeMembers(members) {
        return ts.createNodeArray(ts.sameMap(members, parenthesizeElementTypeMember));
    }
    ts.parenthesizeElementTypeMembers = parenthesizeElementTypeMembers;
    function parenthesizeTypeParameters(typeParameters) {
        if (ts.some(typeParameters)) {
            var params = [];
            for (var i = 0; i < typeParameters.length; ++i) {
                var entry = typeParameters[i];
                params.push(i === 0 && ts.isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ?
                    ts.createParenthesizedType(entry) :
                    entry);
            }
            return ts.createNodeArray(params);
        }
    }
    ts.parenthesizeTypeParameters = parenthesizeTypeParameters;
    function getLeftmostExpression(node, stopAtCallExpressions) {
        while (true) {
            switch (node.kind) {
                case 208 /* PostfixUnaryExpression */:
                    node = node.operand;
                    continue;
                case 209 /* BinaryExpression */:
                    node = node.left;
                    continue;
                case 210 /* ConditionalExpression */:
                    node = node.condition;
                    continue;
                case 198 /* TaggedTemplateExpression */:
                    node = node.tag;
                    continue;
                case 196 /* CallExpression */:
                    if (stopAtCallExpressions) {
                        return node;
                    }
                // falls through
                case 217 /* AsExpression */:
                case 195 /* ElementAccessExpression */:
                case 194 /* PropertyAccessExpression */:
                case 218 /* NonNullExpression */:
                case 326 /* PartiallyEmittedExpression */:
                    node = node.expression;
                    continue;
            }
            return node;
        }
    }
    ts.getLeftmostExpression = getLeftmostExpression;
    function parenthesizeConciseBody(body) {
        if (!ts.isBlock(body) && (isCommaSequence(body) || getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === 193 /* ObjectLiteralExpression */)) {
            return ts.setTextRange(ts.createParen(body), body);
        }
        return body;
    }
    ts.parenthesizeConciseBody = parenthesizeConciseBody;
    function isCommaSequence(node) {
        return node.kind === 209 /* BinaryExpression */ && node.operatorToken.kind === 27 /* CommaToken */ ||
            node.kind === 327 /* CommaListExpression */;
    }
    ts.isCommaSequence = isCommaSequence;
    var OuterExpressionKinds;
    (function (OuterExpressionKinds) {
        OuterExpressionKinds[OuterExpressionKinds["Parentheses"] = 1] = "Parentheses";
        OuterExpressionKinds[OuterExpressionKinds["TypeAssertions"] = 2] = "TypeAssertions";
        OuterExpressionKinds[OuterExpressionKinds["NonNullAssertions"] = 4] = "NonNullAssertions";
        OuterExpressionKinds[OuterExpressionKinds["PartiallyEmittedExpressions"] = 8] = "PartiallyEmittedExpressions";
        OuterExpressionKinds[OuterExpressionKinds["Assertions"] = 6] = "Assertions";
        OuterExpressionKinds[OuterExpressionKinds["All"] = 15] = "All";
    })(OuterExpressionKinds = ts.OuterExpressionKinds || (ts.OuterExpressionKinds = {}));
    function isOuterExpression(node, kinds) {
        if (kinds === void 0) { kinds = 15 /* All */; }
        switch (node.kind) {
            case 200 /* ParenthesizedExpression */:
                return (kinds & 1 /* Parentheses */) !== 0;
            case 199 /* TypeAssertionExpression */:
            case 217 /* AsExpression */:
                return (kinds & 2 /* TypeAssertions */) !== 0;
            case 218 /* NonNullExpression */:
                return (kinds & 4 /* NonNullAssertions */) !== 0;
            case 326 /* PartiallyEmittedExpression */:
                return (kinds & 8 /* PartiallyEmittedExpressions */) !== 0;
        }
        return false;
    }
    ts.isOuterExpression = isOuterExpression;
    function skipOuterExpressions(node, kinds) {
        if (kinds === void 0) { kinds = 15 /* All */; }
        while (isOuterExpression(node, kinds)) {
            node = node.expression;
        }
        return node;
    }
    ts.skipOuterExpressions = skipOuterExpressions;
    function skipAssertions(node) {
        return skipOuterExpressions(node, 6 /* Assertions */);
    }
    ts.skipAssertions = skipAssertions;
    function updateOuterExpression(outerExpression, expression) {
        switch (outerExpression.kind) {
            case 200 /* ParenthesizedExpression */: return ts.updateParen(outerExpression, expression);
            case 199 /* TypeAssertionExpression */: return ts.updateTypeAssertion(outerExpression, outerExpression.type, expression);
            case 217 /* AsExpression */: return ts.updateAsExpression(outerExpression, expression, outerExpression.type);
            case 218 /* NonNullExpression */: return ts.updateNonNullExpression(outerExpression, expression);
            case 326 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(outerExpression, expression);
        }
    }
    /**
     * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions.
     *
     * A parenthesized expression can be ignored when all of the following are true:
     *
     * - It's `pos` and `end` are not -1
     * - It does not have a custom source map range
     * - It does not have a custom comment range
     * - It does not have synthetic leading or trailing comments
     *
     * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around
     * the expression to maintain precedence, a new parenthesized expression should be created automatically when
     * the containing expression is created/updated.
     */
    function isIgnorableParen(node) {
        return node.kind === 200 /* ParenthesizedExpression */
            && ts.nodeIsSynthesized(node)
            && ts.nodeIsSynthesized(ts.getSourceMapRange(node))
            && ts.nodeIsSynthesized(ts.getCommentRange(node))
            && !ts.some(ts.getSyntheticLeadingComments(node))
            && !ts.some(ts.getSyntheticTrailingComments(node));
    }
    function recreateOuterExpressions(outerExpression, innerExpression, kinds) {
        if (kinds === void 0) { kinds = 15 /* All */; }
        if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) {
            return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression));
        }
        return innerExpression;
    }
    ts.recreateOuterExpressions = recreateOuterExpressions;
    function startOnNewLine(node) {
        return ts.setStartsOnNewLine(node, /*newLine*/ true);
    }
    ts.startOnNewLine = startOnNewLine;
    function getExternalHelpersModuleName(node) {
        var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
        var emitNode = parseNode && parseNode.emitNode;
        return emitNode && emitNode.externalHelpersModuleName;
    }
    ts.getExternalHelpersModuleName = getExternalHelpersModuleName;
    function hasRecordedExternalHelpers(sourceFile) {
        var parseNode = ts.getOriginalNode(sourceFile, ts.isSourceFile);
        var emitNode = parseNode && parseNode.emitNode;
        return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers);
    }
    ts.hasRecordedExternalHelpers = hasRecordedExternalHelpers;
    function createExternalHelpersImportDeclarationIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar, hasImportDefault) {
        if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(sourceFile, compilerOptions)) {
            var namedBindings = void 0;
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            if (moduleKind >= ts.ModuleKind.ES2015 && moduleKind <= ts.ModuleKind.ESNext) {
                // use named imports
                var helpers = ts.getEmitHelpers(sourceFile);
                if (helpers) {
                    var helperNames = [];
                    for (var _i = 0, helpers_2 = helpers; _i < helpers_2.length; _i++) {
                        var helper = helpers_2[_i];
                        if (!helper.scoped) {
                            var importName = helper.importName;
                            if (importName) {
                                ts.pushIfUnique(helperNames, importName);
                            }
                        }
                    }
                    if (ts.some(helperNames)) {
                        helperNames.sort(ts.compareStringsCaseSensitive);
                        // Alias the imports if the names are used somewhere in the file.
                        // NOTE: We don't need to care about global import collisions as this is a module.
                        namedBindings = ts.createNamedImports(ts.map(helperNames, function (name) { return ts.isFileLevelUniqueName(sourceFile, name)
                            ? ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(name))
                            : ts.createImportSpecifier(ts.createIdentifier(name), getUnscopedHelperName(name)); }));
                        var parseNode = ts.getOriginalNode(sourceFile, ts.isSourceFile);
                        var emitNode = ts.getOrCreateEmitNode(parseNode);
                        emitNode.externalHelpers = true;
                    }
                }
            }
            else {
                // use a namespace import
                var externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar || hasImportDefault);
                if (externalHelpersModuleName) {
                    namedBindings = ts.createNamespaceImport(externalHelpersModuleName);
                }
            }
            if (namedBindings) {
                var externalHelpersImportDeclaration = ts.createImportDeclaration(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, namedBindings), ts.createLiteral(ts.externalHelpersModuleNameText));
                ts.addEmitFlags(externalHelpersImportDeclaration, 67108864 /* NeverApplyImportHelper */);
                return externalHelpersImportDeclaration;
            }
        }
    }
    ts.createExternalHelpersImportDeclarationIfNeeded = createExternalHelpersImportDeclarationIfNeeded;
    function getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions, hasExportStarsToExportValues, hasImportStarOrImportDefault) {
        if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(node, compilerOptions)) {
            var externalHelpersModuleName = getExternalHelpersModuleName(node);
            if (externalHelpersModuleName) {
                return externalHelpersModuleName;
            }
            var moduleKind = ts.getEmitModuleKind(compilerOptions);
            var create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault))
                && moduleKind !== ts.ModuleKind.System
                && moduleKind < ts.ModuleKind.ES2015;
            if (!create) {
                var helpers = ts.getEmitHelpers(node);
                if (helpers) {
                    for (var _i = 0, helpers_3 = helpers; _i < helpers_3.length; _i++) {
                        var helper = helpers_3[_i];
                        if (!helper.scoped) {
                            create = true;
                            break;
                        }
                    }
                }
            }
            if (create) {
                var parseNode = ts.getOriginalNode(node, ts.isSourceFile);
                var emitNode = ts.getOrCreateEmitNode(parseNode);
                return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = ts.createUniqueName(ts.externalHelpersModuleNameText));
            }
        }
    }
    ts.getOrCreateExternalHelpersModuleNameIfNeeded = getOrCreateExternalHelpersModuleNameIfNeeded;
    /**
     * Get the name of that target module from an import or export declaration
     */
    function getLocalNameForExternalImport(node, sourceFile) {
        var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
        if (namespaceDeclaration && !ts.isDefaultImport(node)) {
            var name = namespaceDeclaration.name;
            return ts.isGeneratedIdentifier(name) ? name : ts.createIdentifier(ts.getSourceTextOfNodeFromSourceFile(sourceFile, name) || ts.idText(name));
        }
        if (node.kind === 254 /* ImportDeclaration */ && node.importClause) {
            return ts.getGeneratedNameForNode(node);
        }
        if (node.kind === 260 /* ExportDeclaration */ && node.moduleSpecifier) {
            return ts.getGeneratedNameForNode(node);
        }
        return undefined;
    }
    ts.getLocalNameForExternalImport = getLocalNameForExternalImport;
    /**
     * Get the name of a target module from an import/export declaration as should be written in the emitted output.
     * The emitted output name can be different from the input if:
     *  1. The module has a /// <amd-module name="<new name>" />
     *  2. --out or --outFile is used, making the name relative to the rootDir
     *  3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System).
     * Otherwise, a new StringLiteral node representing the module name will be returned.
     */
    function getExternalModuleNameLiteral(importNode, sourceFile, host, resolver, compilerOptions) {
        var moduleName = ts.getExternalModuleName(importNode); // TODO: GH#18217
        if (moduleName.kind === 10 /* StringLiteral */) {
            return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions)
                || tryRenameExternalModule(moduleName, sourceFile)
                || ts.getSynthesizedClone(moduleName);
        }
        return undefined;
    }
    ts.getExternalModuleNameLiteral = getExternalModuleNameLiteral;
    /**
     * Some bundlers (SystemJS builder) sometimes want to rename dependencies.
     * Here we check if alternative name was provided for a given moduleName and return it if possible.
     */
    function tryRenameExternalModule(moduleName, sourceFile) {
        var rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text);
        return rename && ts.createLiteral(rename);
    }
    /**
     * Get the name of a module as should be written in the emitted output.
     * The emitted output name can be different from the input if:
     *  1. The module has a /// <amd-module name="<new name>" />
     *  2. --out or --outFile is used, making the name relative to the rootDir
     * Otherwise, a new StringLiteral node representing the module name will be returned.
     */
    function tryGetModuleNameFromFile(file, host, options) {
        if (!file) {
            return undefined;
        }
        if (file.moduleName) {
            return ts.createLiteral(file.moduleName);
        }
        if (!file.isDeclarationFile && (options.out || options.outFile)) {
            return ts.createLiteral(ts.getExternalModuleNameFromPath(host, file.fileName));
        }
        return undefined;
    }
    ts.tryGetModuleNameFromFile = tryGetModuleNameFromFile;
    function tryGetModuleNameFromDeclaration(declaration, host, resolver, compilerOptions) {
        return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions);
    }
    /**
     * Gets the initializer of an BindingOrAssignmentElement.
     */
    function getInitializerOfBindingOrAssignmentElement(bindingElement) {
        if (ts.isDeclarationBindingElement(bindingElement)) {
            // `1` in `let { a = 1 } = ...`
            // `1` in `let { a: b = 1 } = ...`
            // `1` in `let { a: {b} = 1 } = ...`
            // `1` in `let { a: [b] = 1 } = ...`
            // `1` in `let [a = 1] = ...`
            // `1` in `let [{a} = 1] = ...`
            // `1` in `let [[a] = 1] = ...`
            return bindingElement.initializer;
        }
        if (ts.isPropertyAssignment(bindingElement)) {
            // `1` in `({ a: b = 1 } = ...)`
            // `1` in `({ a: {b} = 1 } = ...)`
            // `1` in `({ a: [b] = 1 } = ...)`
            var initializer = bindingElement.initializer;
            return ts.isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true)
                ? initializer.right
                : undefined;
        }
        if (ts.isShorthandPropertyAssignment(bindingElement)) {
            // `1` in `({ a = 1 } = ...)`
            return bindingElement.objectAssignmentInitializer;
        }
        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
            // `1` in `[a = 1] = ...`
            // `1` in `[{a} = 1] = ...`
            // `1` in `[[a] = 1] = ...`
            return bindingElement.right;
        }
        if (ts.isSpreadElement(bindingElement)) {
            // Recovery consistent with existing emit.
            return getInitializerOfBindingOrAssignmentElement(bindingElement.expression);
        }
    }
    ts.getInitializerOfBindingOrAssignmentElement = getInitializerOfBindingOrAssignmentElement;
    /**
     * Gets the name of an BindingOrAssignmentElement.
     */
    function getTargetOfBindingOrAssignmentElement(bindingElement) {
        if (ts.isDeclarationBindingElement(bindingElement)) {
            // `a` in `let { a } = ...`
            // `a` in `let { a = 1 } = ...`
            // `b` in `let { a: b } = ...`
            // `b` in `let { a: b = 1 } = ...`
            // `a` in `let { ...a } = ...`
            // `{b}` in `let { a: {b} } = ...`
            // `{b}` in `let { a: {b} = 1 } = ...`
            // `[b]` in `let { a: [b] } = ...`
            // `[b]` in `let { a: [b] = 1 } = ...`
            // `a` in `let [a] = ...`
            // `a` in `let [a = 1] = ...`
            // `a` in `let [...a] = ...`
            // `{a}` in `let [{a}] = ...`
            // `{a}` in `let [{a} = 1] = ...`
            // `[a]` in `let [[a]] = ...`
            // `[a]` in `let [[a] = 1] = ...`
            return bindingElement.name;
        }
        if (ts.isObjectLiteralElementLike(bindingElement)) {
            switch (bindingElement.kind) {
                case 281 /* PropertyAssignment */:
                    // `b` in `({ a: b } = ...)`
                    // `b` in `({ a: b = 1 } = ...)`
                    // `{b}` in `({ a: {b} } = ...)`
                    // `{b}` in `({ a: {b} = 1 } = ...)`
                    // `[b]` in `({ a: [b] } = ...)`
                    // `[b]` in `({ a: [b] = 1 } = ...)`
                    // `b.c` in `({ a: b.c } = ...)`
                    // `b.c` in `({ a: b.c = 1 } = ...)`
                    // `b[0]` in `({ a: b[0] } = ...)`
                    // `b[0]` in `({ a: b[0] = 1 } = ...)`
                    return getTargetOfBindingOrAssignmentElement(bindingElement.initializer);
                case 282 /* ShorthandPropertyAssignment */:
                    // `a` in `({ a } = ...)`
                    // `a` in `({ a = 1 } = ...)`
                    return bindingElement.name;
                case 283 /* SpreadAssignment */:
                    // `a` in `({ ...a } = ...)`
                    return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
            }
            // no target
            return undefined;
        }
        if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
            // `a` in `[a = 1] = ...`
            // `{a}` in `[{a} = 1] = ...`
            // `[a]` in `[[a] = 1] = ...`
            // `a.b` in `[a.b = 1] = ...`
            // `a[0]` in `[a[0] = 1] = ...`
            return getTargetOfBindingOrAssignmentElement(bindingElement.left);
        }
        if (ts.isSpreadElement(bindingElement)) {
            // `a` in `[...a] = ...`
            return getTargetOfBindingOrAssignmentElement(bindingElement.expression);
        }
        // `a` in `[a] = ...`
        // `{a}` in `[{a}] = ...`
        // `[a]` in `[[a]] = ...`
        // `a.b` in `[a.b] = ...`
        // `a[0]` in `[a[0]] = ...`
        return bindingElement;
    }
    ts.getTargetOfBindingOrAssignmentElement = getTargetOfBindingOrAssignmentElement;
    /**
     * Determines whether an BindingOrAssignmentElement is a rest element.
     */
    function getRestIndicatorOfBindingOrAssignmentElement(bindingElement) {
        switch (bindingElement.kind) {
            case 156 /* Parameter */:
            case 191 /* BindingElement */:
                // `...` in `let [...a] = ...`
                return bindingElement.dotDotDotToken;
            case 213 /* SpreadElement */:
            case 283 /* SpreadAssignment */:
                // `...` in `[...a] = ...`
                return bindingElement;
        }
        return undefined;
    }
    ts.getRestIndicatorOfBindingOrAssignmentElement = getRestIndicatorOfBindingOrAssignmentElement;
    /**
     * Gets the property name of a BindingOrAssignmentElement
     */
    function getPropertyNameOfBindingOrAssignmentElement(bindingElement) {
        var propertyName = tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement);
        ts.Debug.assert(!!propertyName || ts.isSpreadAssignment(bindingElement), "Invalid property name for binding element.");
        return propertyName;
    }
    ts.getPropertyNameOfBindingOrAssignmentElement = getPropertyNameOfBindingOrAssignmentElement;
    function tryGetPropertyNameOfBindingOrAssignmentElement(bindingElement) {
        switch (bindingElement.kind) {
            case 191 /* BindingElement */:
                // `a` in `let { a: b } = ...`
                // `[a]` in `let { [a]: b } = ...`
                // `"a"` in `let { "a": b } = ...`
                // `1` in `let { 1: b } = ...`
                if (bindingElement.propertyName) {
                    var propertyName = bindingElement.propertyName;
                    if (ts.isPrivateIdentifier(propertyName)) {
                        return ts.Debug.failBadSyntaxKind(propertyName);
                    }
                    return ts.isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
                        ? propertyName.expression
                        : propertyName;
                }
                break;
            case 281 /* PropertyAssignment */:
                // `a` in `({ a: b } = ...)`
                // `[a]` in `({ [a]: b } = ...)`
                // `"a"` in `({ "a": b } = ...)`
                // `1` in `({ 1: b } = ...)`
                if (bindingElement.name) {
                    var propertyName = bindingElement.name;
                    if (ts.isPrivateIdentifier(propertyName)) {
                        return ts.Debug.failBadSyntaxKind(propertyName);
                    }
                    return ts.isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
                        ? propertyName.expression
                        : propertyName;
                }
                break;
            case 283 /* SpreadAssignment */:
                // `a` in `({ ...a } = ...)`
                if (bindingElement.name && ts.isPrivateIdentifier(bindingElement.name)) {
                    return ts.Debug.failBadSyntaxKind(bindingElement.name);
                }
                return bindingElement.name;
        }
        var target = getTargetOfBindingOrAssignmentElement(bindingElement);
        if (target && ts.isPropertyName(target)) {
            return target;
        }
    }
    ts.tryGetPropertyNameOfBindingOrAssignmentElement = tryGetPropertyNameOfBindingOrAssignmentElement;
    function isStringOrNumericLiteral(node) {
        var kind = node.kind;
        return kind === 10 /* StringLiteral */
            || kind === 8 /* NumericLiteral */;
    }
    /**
     * Gets the elements of a BindingOrAssignmentPattern
     */
    function getElementsOfBindingOrAssignmentPattern(name) {
        switch (name.kind) {
            case 189 /* ObjectBindingPattern */:
            case 190 /* ArrayBindingPattern */:
            case 192 /* ArrayLiteralExpression */:
                // `a` in `{a}`
                // `a` in `[a]`
                return name.elements;
            case 193 /* ObjectLiteralExpression */:
                // `a` in `{a}`
                return name.properties;
        }
    }
    ts.getElementsOfBindingOrAssignmentPattern = getElementsOfBindingOrAssignmentPattern;
    function convertToArrayAssignmentElement(element) {
        if (ts.isBindingElement(element)) {
            if (element.dotDotDotToken) {
                ts.Debug.assertNode(element.name, ts.isIdentifier);
                return ts.setOriginalNode(ts.setTextRange(ts.createSpread(element.name), element), element);
            }
            var expression = convertToAssignmentElementTarget(element.name);
            return element.initializer
                ? ts.setOriginalNode(ts.setTextRange(ts.createAssignment(expression, element.initializer), element), element)
                : expression;
        }
        ts.Debug.assertNode(element, ts.isExpression);
        return element;
    }
    ts.convertToArrayAssignmentElement = convertToArrayAssignmentElement;
    function convertToObjectAssignmentElement(element) {
        if (ts.isBindingElement(element)) {
            if (element.dotDotDotToken) {
                ts.Debug.assertNode(element.name, ts.isIdentifier);
                return ts.setOriginalNode(ts.setTextRange(ts.createSpreadAssignment(element.name), element), element);
            }
            if (element.propertyName) {
                var expression = convertToAssignmentElementTarget(element.name);
                return ts.setOriginalNode(ts.setTextRange(ts.createPropertyAssignment(element.propertyName, element.initializer ? ts.createAssignment(expression, element.initializer) : expression), element), element);
            }
            ts.Debug.assertNode(element.name, ts.isIdentifier);
            return ts.setOriginalNode(ts.setTextRange(ts.createShorthandPropertyAssignment(element.name, element.initializer), element), element);
        }
        ts.Debug.assertNode(element, ts.isObjectLiteralElementLike);
        return element;
    }
    ts.convertToObjectAssignmentElement = convertToObjectAssignmentElement;
    function convertToAssignmentPattern(node) {
        switch (node.kind) {
            case 190 /* ArrayBindingPattern */:
            case 192 /* ArrayLiteralExpression */:
                return convertToArrayAssignmentPattern(node);
            case 189 /* ObjectBindingPattern */:
            case 193 /* ObjectLiteralExpression */:
                return convertToObjectAssignmentPattern(node);
        }
    }
    ts.convertToAssignmentPattern = convertToAssignmentPattern;
    function convertToObjectAssignmentPattern(node) {
        if (ts.isObjectBindingPattern(node)) {
            return ts.setOriginalNode(ts.setTextRange(ts.createObjectLiteral(ts.map(node.elements, convertToObjectAssignmentElement)), node), node);
        }
        ts.Debug.assertNode(node, ts.isObjectLiteralExpression);
        return node;
    }
    ts.convertToObjectAssignmentPattern = convertToObjectAssignmentPattern;
    function convertToArrayAssignmentPattern(node) {
        if (ts.isArrayBindingPattern(node)) {
            return ts.setOriginalNode(ts.setTextRange(ts.createArrayLiteral(ts.map(node.elements, convertToArrayAssignmentElement)), node), node);
        }
        ts.Debug.assertNode(node, ts.isArrayLiteralExpression);
        return node;
    }
    ts.convertToArrayAssignmentPattern = convertToArrayAssignmentPattern;
    function convertToAssignmentElementTarget(node) {
        if (ts.isBindingPattern(node)) {
            return convertToAssignmentPattern(node);
        }
        ts.Debug.assertNode(node, ts.isExpression);
        return node;
    }
    ts.convertToAssignmentElementTarget = convertToAssignmentElementTarget;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var isTypeNodeOrTypeParameterDeclaration = ts.or(ts.isTypeNode, ts.isTypeParameterDeclaration);
    function visitNode(node, visitor, test, lift) {
        if (node === undefined || visitor === undefined) {
            return node;
        }
        ts.aggregateTransformFlags(node);
        var visited = visitor(node);
        if (visited === node) {
            return node;
        }
        var visitedNode;
        if (visited === undefined) {
            return undefined;
        }
        else if (ts.isArray(visited)) {
            visitedNode = (lift || extractSingleNode)(visited);
        }
        else {
            visitedNode = visited;
        }
        ts.Debug.assertNode(visitedNode, test);
        ts.aggregateTransformFlags(visitedNode);
        return visitedNode;
    }
    ts.visitNode = visitNode;
    /**
     * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place.
     *
     * @param nodes The NodeArray to visit.
     * @param visitor The callback used to visit a Node.
     * @param test A node test to execute for each node.
     * @param start An optional value indicating the starting offset at which to start visiting.
     * @param count An optional value indicating the maximum number of nodes to visit.
     */
    function visitNodes(nodes, visitor, test, start, count) {
        if (nodes === undefined || visitor === undefined) {
            return nodes;
        }
        var updated;
        // Ensure start and count have valid values
        var length = nodes.length;
        if (start === undefined || start < 0) {
            start = 0;
        }
        if (count === undefined || count > length - start) {
            count = length - start;
        }
        if (start > 0 || count < length) {
            // If we are not visiting all of the original nodes, we must always create a new array.
            // Since this is a fragment of a node array, we do not copy over the previous location
            // and will only copy over `hasTrailingComma` if we are including the last element.
            updated = ts.createNodeArray([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
        }
        // Visit each original node.
        for (var i = 0; i < count; i++) {
            var node = nodes[i + start];
            ts.aggregateTransformFlags(node);
            var visited = node !== undefined ? visitor(node) : undefined;
            if (updated !== undefined || visited === undefined || visited !== node) {
                if (updated === undefined) {
                    // Ensure we have a copy of `nodes`, up to the current index.
                    updated = ts.createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma);
                    ts.setTextRange(updated, nodes);
                }
                if (visited) {
                    if (ts.isArray(visited)) {
                        for (var _i = 0, visited_1 = visited; _i < visited_1.length; _i++) {
                            var visitedNode = visited_1[_i];
                            ts.Debug.assertNode(visitedNode, test);
                            ts.aggregateTransformFlags(visitedNode);
                            updated.push(visitedNode);
                        }
                    }
                    else {
                        ts.Debug.assertNode(visited, test);
                        ts.aggregateTransformFlags(visited);
                        updated.push(visited);
                    }
                }
            }
        }
        return updated || nodes;
    }
    ts.visitNodes = visitNodes;
    /**
     * Starts a new lexical environment and visits a statement list, ending the lexical environment
     * and merging hoisted declarations upon completion.
     */
    function visitLexicalEnvironment(statements, visitor, context, start, ensureUseStrict) {
        context.startLexicalEnvironment();
        statements = visitNodes(statements, visitor, ts.isStatement, start);
        if (ensureUseStrict)
            statements = ts.ensureUseStrict(statements); // eslint-disable-line @typescript-eslint/no-unnecessary-qualifier
        return ts.mergeLexicalEnvironment(statements, context.endLexicalEnvironment());
    }
    ts.visitLexicalEnvironment = visitLexicalEnvironment;
    function visitParameterList(nodes, visitor, context, nodesVisitor) {
        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
        var updated;
        context.startLexicalEnvironment();
        if (nodes) {
            context.setLexicalEnvironmentFlags(1 /* InParameters */, true);
            updated = nodesVisitor(nodes, visitor, ts.isParameterDeclaration);
            // As of ES2015, any runtime execution of that occurs in for a parameter (such as evaluating an
            // initializer or a binding pattern), occurs in its own lexical scope. As a result, any expression
            // that we might transform that introduces a temporary variable would fail as the temporary variable
            // exists in a different lexical scope. To address this, we move any binding patterns and initializers
            // in a parameter list to the body if we detect a variable being hoisted while visiting a parameter list
            // when the emit target is greater than ES2015.
            if (context.getLexicalEnvironmentFlags() & 2 /* VariablesHoistedInParameters */ &&
                ts.getEmitScriptTarget(context.getCompilerOptions()) >= 2 /* ES2015 */) {
                updated = addDefaultValueAssignmentsIfNeeded(updated, context);
            }
            context.setLexicalEnvironmentFlags(1 /* InParameters */, false);
        }
        context.suspendLexicalEnvironment();
        return updated;
    }
    ts.visitParameterList = visitParameterList;
    function addDefaultValueAssignmentsIfNeeded(parameters, context) {
        var result;
        for (var i = 0; i < parameters.length; i++) {
            var parameter = parameters[i];
            var updated = addDefaultValueAssignmentIfNeeded(parameter, context);
            if (result || updated !== parameter) {
                if (!result)
                    result = parameters.slice(0, i);
                result[i] = updated;
            }
        }
        if (result) {
            return ts.setTextRange(ts.createNodeArray(result, parameters.hasTrailingComma), parameters);
        }
        return parameters;
    }
    function addDefaultValueAssignmentIfNeeded(parameter, context) {
        // A rest parameter cannot have a binding pattern or an initializer,
        // so let's just ignore it.
        return parameter.dotDotDotToken ? parameter :
            ts.isBindingPattern(parameter.name) ? addDefaultValueAssignmentForBindingPattern(parameter, context) :
                parameter.initializer ? addDefaultValueAssignmentForInitializer(parameter, parameter.name, parameter.initializer, context) :
                    parameter;
    }
    function addDefaultValueAssignmentForBindingPattern(parameter, context) {
        context.addInitializationStatement(ts.createVariableStatement(
        /*modifiers*/ undefined, ts.createVariableDeclarationList([
            ts.createVariableDeclaration(parameter.name, parameter.type, parameter.initializer ?
                ts.createConditional(ts.createStrictEquality(ts.getGeneratedNameForNode(parameter), ts.createVoidZero()), parameter.initializer, ts.getGeneratedNameForNode(parameter)) :
                ts.getGeneratedNameForNode(parameter)),
        ])));
        return ts.updateParameter(parameter, parameter.decorators, parameter.modifiers, parameter.dotDotDotToken, ts.getGeneratedNameForNode(parameter), parameter.questionToken, parameter.type, 
        /*initializer*/ undefined);
    }
    function addDefaultValueAssignmentForInitializer(parameter, name, initializer, context) {
        context.addInitializationStatement(ts.createIf(ts.createTypeCheck(ts.getSynthesizedClone(name), "undefined"), ts.setEmitFlags(ts.setTextRange(ts.createBlock([
            ts.createExpressionStatement(ts.setEmitFlags(ts.setTextRange(ts.createAssignment(ts.setEmitFlags(ts.getMutableClone(name), 48 /* NoSourceMap */), ts.setEmitFlags(initializer, 48 /* NoSourceMap */ | ts.getEmitFlags(initializer) | 1536 /* NoComments */)), parameter), 1536 /* NoComments */))
        ]), parameter), 1 /* SingleLine */ | 32 /* NoTrailingSourceMap */ | 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */)));
        return ts.updateParameter(parameter, parameter.decorators, parameter.modifiers, parameter.dotDotDotToken, parameter.name, parameter.questionToken, parameter.type, 
        /*initializer*/ undefined);
    }
    function visitFunctionBody(node, visitor, context) {
        context.resumeLexicalEnvironment();
        var updated = visitNode(node, visitor, ts.isConciseBody);
        var declarations = context.endLexicalEnvironment();
        if (ts.some(declarations)) {
            var block = ts.convertToFunctionBody(updated);
            var statements = ts.mergeLexicalEnvironment(block.statements, declarations);
            return ts.updateBlock(block, statements);
        }
        return updated;
    }
    ts.visitFunctionBody = visitFunctionBody;
    function visitEachChild(node, visitor, context, nodesVisitor, tokenVisitor) {
        if (nodesVisitor === void 0) { nodesVisitor = visitNodes; }
        if (node === undefined) {
            return undefined;
        }
        var kind = node.kind;
        // No need to visit nodes with no children.
        if ((kind > 0 /* FirstToken */ && kind <= 152 /* LastToken */) || kind === 183 /* ThisType */) {
            return node;
        }
        switch (kind) {
            // Names
            case 75 /* Identifier */:
                return ts.updateIdentifier(node, nodesVisitor(node.typeArguments, visitor, isTypeNodeOrTypeParameterDeclaration));
            case 153 /* QualifiedName */:
                return ts.updateQualifiedName(node, visitNode(node.left, visitor, ts.isEntityName), visitNode(node.right, visitor, ts.isIdentifier));
            case 154 /* ComputedPropertyName */:
                return ts.updateComputedPropertyName(node, visitNode(node.expression, visitor, ts.isExpression));
            // Signature elements
            case 155 /* TypeParameter */:
                return ts.updateTypeParameterDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.constraint, visitor, ts.isTypeNode), visitNode(node.default, visitor, ts.isTypeNode));
            case 156 /* Parameter */:
                return ts.updateParameter(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 157 /* Decorator */:
                return ts.updateDecorator(node, visitNode(node.expression, visitor, ts.isExpression));
            // Type elements
            case 158 /* PropertySignature */:
                return ts.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 159 /* PropertyDeclaration */:
                return ts.updateProperty(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), 
                // QuestionToken and ExclamationToken is uniqued in Property Declaration and the signature of 'updateProperty' is that too
                visitNode(node.questionToken || node.exclamationToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 160 /* MethodSignature */:
                return ts.updateMethodSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken));
            case 161 /* MethodDeclaration */:
                return ts.updateMethod(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 162 /* Constructor */:
                return ts.updateConstructor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
            case 163 /* GetAccessor */:
                return ts.updateGetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 164 /* SetAccessor */:
                return ts.updateSetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context));
            case 165 /* CallSignature */:
                return ts.updateCallSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 166 /* ConstructSignature */:
                return ts.updateConstructSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 167 /* IndexSignature */:
                return ts.updateIndexSignature(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            // Types
            case 168 /* TypePredicate */:
                return ts.updateTypePredicateNodeWithModifier(node, visitNode(node.assertsModifier, visitor), visitNode(node.parameterName, visitor), visitNode(node.type, visitor, ts.isTypeNode));
            case 169 /* TypeReference */:
                return ts.updateTypeReferenceNode(node, visitNode(node.typeName, visitor, ts.isEntityName), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode));
            case 170 /* FunctionType */:
                return ts.updateFunctionTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 171 /* ConstructorType */:
                return ts.updateConstructorTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 172 /* TypeQuery */:
                return ts.updateTypeQueryNode(node, visitNode(node.exprName, visitor, ts.isEntityName));
            case 173 /* TypeLiteral */:
                return ts.updateTypeLiteralNode(node, nodesVisitor(node.members, visitor, ts.isTypeElement));
            case 174 /* ArrayType */:
                return ts.updateArrayTypeNode(node, visitNode(node.elementType, visitor, ts.isTypeNode));
            case 175 /* TupleType */:
                return ts.updateTupleTypeNode(node, nodesVisitor(node.elementTypes, visitor, ts.isTypeNode));
            case 176 /* OptionalType */:
                return ts.updateOptionalTypeNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 177 /* RestType */:
                return ts.updateRestTypeNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 178 /* UnionType */:
                return ts.updateUnionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
            case 179 /* IntersectionType */:
                return ts.updateIntersectionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode));
            case 180 /* ConditionalType */:
                return ts.updateConditionalTypeNode(node, visitNode(node.checkType, visitor, ts.isTypeNode), visitNode(node.extendsType, visitor, ts.isTypeNode), visitNode(node.trueType, visitor, ts.isTypeNode), visitNode(node.falseType, visitor, ts.isTypeNode));
            case 181 /* InferType */:
                return ts.updateInferTypeNode(node, visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration));
            case 188 /* ImportType */:
                return ts.updateImportTypeNode(node, visitNode(node.argument, visitor, ts.isTypeNode), visitNode(node.qualifier, visitor, ts.isEntityName), visitNodes(node.typeArguments, visitor, ts.isTypeNode), node.isTypeOf);
            case 182 /* ParenthesizedType */:
                return ts.updateParenthesizedType(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 184 /* TypeOperator */:
                return ts.updateTypeOperatorNode(node, visitNode(node.type, visitor, ts.isTypeNode));
            case 185 /* IndexedAccessType */:
                return ts.updateIndexedAccessTypeNode(node, visitNode(node.objectType, visitor, ts.isTypeNode), visitNode(node.indexType, visitor, ts.isTypeNode));
            case 186 /* MappedType */:
                return ts.updateMappedTypeNode(node, visitNode(node.readonlyToken, tokenVisitor, ts.isToken), visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode));
            case 187 /* LiteralType */:
                return ts.updateLiteralTypeNode(node, visitNode(node.literal, visitor, ts.isExpression));
            // Binding patterns
            case 189 /* ObjectBindingPattern */:
                return ts.updateObjectBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isBindingElement));
            case 190 /* ArrayBindingPattern */:
                return ts.updateArrayBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isArrayBindingElement));
            case 191 /* BindingElement */:
                return ts.updateBindingElement(node, visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.propertyName, visitor, ts.isPropertyName), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.initializer, visitor, ts.isExpression));
            // Expression
            case 192 /* ArrayLiteralExpression */:
                return ts.updateArrayLiteral(node, nodesVisitor(node.elements, visitor, ts.isExpression));
            case 193 /* ObjectLiteralExpression */:
                return ts.updateObjectLiteral(node, nodesVisitor(node.properties, visitor, ts.isObjectLiteralElementLike));
            case 194 /* PropertyAccessExpression */:
                if (node.flags & 32 /* OptionalChain */) {
                    return ts.updatePropertyAccessChain(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.questionDotToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier));
                }
                return ts.updatePropertyAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.name, visitor, ts.isIdentifierOrPrivateIdentifier));
            case 195 /* ElementAccessExpression */:
                if (node.flags & 32 /* OptionalChain */) {
                    return ts.updateElementAccessChain(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.questionDotToken, tokenVisitor, ts.isToken), visitNode(node.argumentExpression, visitor, ts.isExpression));
                }
                return ts.updateElementAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.argumentExpression, visitor, ts.isExpression));
            case 196 /* CallExpression */:
                if (node.flags & 32 /* OptionalChain */) {
                    return ts.updateCallChain(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.questionDotToken, tokenVisitor, ts.isToken), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
                }
                return ts.updateCall(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
            case 197 /* NewExpression */:
                return ts.updateNew(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression));
            case 198 /* TaggedTemplateExpression */:
                return ts.updateTaggedTemplate(node, visitNode(node.tag, visitor, ts.isExpression), visitNodes(node.typeArguments, visitor, ts.isExpression), visitNode(node.template, visitor, ts.isTemplateLiteral));
            case 199 /* TypeAssertionExpression */:
                return ts.updateTypeAssertion(node, visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
            case 200 /* ParenthesizedExpression */:
                return ts.updateParen(node, visitNode(node.expression, visitor, ts.isExpression));
            case 201 /* FunctionExpression */:
                return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 202 /* ArrowFunction */:
                return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, tokenVisitor, ts.isToken), visitFunctionBody(node.body, visitor, context));
            case 203 /* DeleteExpression */:
                return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression));
            case 204 /* TypeOfExpression */:
                return ts.updateTypeOf(node, visitNode(node.expression, visitor, ts.isExpression));
            case 205 /* VoidExpression */:
                return ts.updateVoid(node, visitNode(node.expression, visitor, ts.isExpression));
            case 206 /* AwaitExpression */:
                return ts.updateAwait(node, visitNode(node.expression, visitor, ts.isExpression));
            case 207 /* PrefixUnaryExpression */:
                return ts.updatePrefix(node, visitNode(node.operand, visitor, ts.isExpression));
            case 208 /* PostfixUnaryExpression */:
                return ts.updatePostfix(node, visitNode(node.operand, visitor, ts.isExpression));
            case 209 /* BinaryExpression */:
                return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, tokenVisitor, ts.isToken));
            case 210 /* ConditionalExpression */:
                return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, tokenVisitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression));
            case 211 /* TemplateExpression */:
                return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan));
            case 212 /* YieldExpression */:
                return ts.updateYield(node, visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.expression, visitor, ts.isExpression));
            case 213 /* SpreadElement */:
                return ts.updateSpread(node, visitNode(node.expression, visitor, ts.isExpression));
            case 214 /* ClassExpression */:
                return ts.updateClassExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
            case 216 /* ExpressionWithTypeArguments */:
                return ts.updateExpressionWithTypeArguments(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression));
            case 217 /* AsExpression */:
                return ts.updateAsExpression(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.type, visitor, ts.isTypeNode));
            case 218 /* NonNullExpression */:
                return ts.updateNonNullExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            case 219 /* MetaProperty */:
                return ts.updateMetaProperty(node, visitNode(node.name, visitor, ts.isIdentifier));
            // Misc
            case 221 /* TemplateSpan */:
                return ts.updateTemplateSpan(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.literal, visitor, ts.isTemplateMiddleOrTemplateTail));
            // Element
            case 223 /* Block */:
                return ts.updateBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 225 /* VariableStatement */:
                return ts.updateVariableStatement(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.declarationList, visitor, ts.isVariableDeclarationList));
            case 226 /* ExpressionStatement */:
                return ts.updateExpressionStatement(node, visitNode(node.expression, visitor, ts.isExpression));
            case 227 /* IfStatement */:
                return ts.updateIf(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.thenStatement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.elseStatement, visitor, ts.isStatement, ts.liftToBlock));
            case 228 /* DoStatement */:
                return ts.updateDo(node, visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.expression, visitor, ts.isExpression));
            case 229 /* WhileStatement */:
                return ts.updateWhile(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 230 /* ForStatement */:
                return ts.updateFor(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.condition, visitor, ts.isExpression), visitNode(node.incrementor, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 231 /* ForInStatement */:
                return ts.updateForIn(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 232 /* ForOfStatement */:
                return ts.updateForOf(node, visitNode(node.awaitModifier, tokenVisitor, ts.isToken), visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 233 /* ContinueStatement */:
                return ts.updateContinue(node, visitNode(node.label, visitor, ts.isIdentifier));
            case 234 /* BreakStatement */:
                return ts.updateBreak(node, visitNode(node.label, visitor, ts.isIdentifier));
            case 235 /* ReturnStatement */:
                return ts.updateReturn(node, visitNode(node.expression, visitor, ts.isExpression));
            case 236 /* WithStatement */:
                return ts.updateWith(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 237 /* SwitchStatement */:
                return ts.updateSwitch(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.caseBlock, visitor, ts.isCaseBlock));
            case 238 /* LabeledStatement */:
                return ts.updateLabel(node, visitNode(node.label, visitor, ts.isIdentifier), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            case 239 /* ThrowStatement */:
                return ts.updateThrow(node, visitNode(node.expression, visitor, ts.isExpression));
            case 240 /* TryStatement */:
                return ts.updateTry(node, visitNode(node.tryBlock, visitor, ts.isBlock), visitNode(node.catchClause, visitor, ts.isCatchClause), visitNode(node.finallyBlock, visitor, ts.isBlock));
            case 242 /* VariableDeclaration */:
                return ts.updateTypeScriptVariableDeclaration(node, visitNode(node.name, visitor, ts.isBindingName), visitNode(node.exclamationToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression));
            case 243 /* VariableDeclarationList */:
                return ts.updateVariableDeclarationList(node, nodesVisitor(node.declarations, visitor, ts.isVariableDeclaration));
            case 244 /* FunctionDeclaration */:
                return ts.updateFunctionDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context));
            case 245 /* ClassDeclaration */:
                return ts.updateClassDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement));
            case 246 /* InterfaceDeclaration */:
                return ts.updateInterfaceDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isTypeElement));
            case 247 /* TypeAliasDeclaration */:
                return ts.updateTypeAliasDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode));
            case 248 /* EnumDeclaration */:
                return ts.updateEnumDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.members, visitor, ts.isEnumMember));
            case 249 /* ModuleDeclaration */:
                return ts.updateModuleDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.body, visitor, ts.isModuleBody));
            case 250 /* ModuleBlock */:
                return ts.updateModuleBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 251 /* CaseBlock */:
                return ts.updateCaseBlock(node, nodesVisitor(node.clauses, visitor, ts.isCaseOrDefaultClause));
            case 252 /* NamespaceExportDeclaration */:
                return ts.updateNamespaceExportDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 253 /* ImportEqualsDeclaration */:
                return ts.updateImportEqualsDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.moduleReference, visitor, ts.isModuleReference));
            case 254 /* ImportDeclaration */:
                return ts.updateImportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.importClause, visitor, ts.isImportClause), visitNode(node.moduleSpecifier, visitor, ts.isExpression));
            case 255 /* ImportClause */:
                return ts.updateImportClause(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.namedBindings, visitor, ts.isNamedImportBindings), node.isTypeOnly);
            case 256 /* NamespaceImport */:
                return ts.updateNamespaceImport(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 262 /* NamespaceExport */:
                return ts.updateNamespaceExport(node, visitNode(node.name, visitor, ts.isIdentifier));
            case 257 /* NamedImports */:
                return ts.updateNamedImports(node, nodesVisitor(node.elements, visitor, ts.isImportSpecifier));
            case 258 /* ImportSpecifier */:
                return ts.updateImportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
            case 259 /* ExportAssignment */:
                return ts.updateExportAssignment(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.expression, visitor, ts.isExpression));
            case 260 /* ExportDeclaration */:
                return ts.updateExportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.exportClause, visitor, ts.isNamedExportBindings), visitNode(node.moduleSpecifier, visitor, ts.isExpression), node.isTypeOnly);
            case 261 /* NamedExports */:
                return ts.updateNamedExports(node, nodesVisitor(node.elements, visitor, ts.isExportSpecifier));
            case 263 /* ExportSpecifier */:
                return ts.updateExportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier));
            // Module references
            case 265 /* ExternalModuleReference */:
                return ts.updateExternalModuleReference(node, visitNode(node.expression, visitor, ts.isExpression));
            // JSX
            case 266 /* JsxElement */:
                return ts.updateJsxElement(node, visitNode(node.openingElement, visitor, ts.isJsxOpeningElement), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingElement, visitor, ts.isJsxClosingElement));
            case 267 /* JsxSelfClosingElement */:
                return ts.updateJsxSelfClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.attributes, visitor, ts.isJsxAttributes));
            case 268 /* JsxOpeningElement */:
                return ts.updateJsxOpeningElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.attributes, visitor, ts.isJsxAttributes));
            case 269 /* JsxClosingElement */:
                return ts.updateJsxClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression));
            case 270 /* JsxFragment */:
                return ts.updateJsxFragment(node, visitNode(node.openingFragment, visitor, ts.isJsxOpeningFragment), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingFragment, visitor, ts.isJsxClosingFragment));
            case 273 /* JsxAttribute */:
                return ts.updateJsxAttribute(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.initializer, visitor, ts.isStringLiteralOrJsxExpression));
            case 274 /* JsxAttributes */:
                return ts.updateJsxAttributes(node, nodesVisitor(node.properties, visitor, ts.isJsxAttributeLike));
            case 275 /* JsxSpreadAttribute */:
                return ts.updateJsxSpreadAttribute(node, visitNode(node.expression, visitor, ts.isExpression));
            case 276 /* JsxExpression */:
                return ts.updateJsxExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            // Clauses
            case 277 /* CaseClause */:
                return ts.updateCaseClause(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.statements, visitor, ts.isStatement));
            case 278 /* DefaultClause */:
                return ts.updateDefaultClause(node, nodesVisitor(node.statements, visitor, ts.isStatement));
            case 279 /* HeritageClause */:
                return ts.updateHeritageClause(node, nodesVisitor(node.types, visitor, ts.isExpressionWithTypeArguments));
            case 280 /* CatchClause */:
                return ts.updateCatchClause(node, visitNode(node.variableDeclaration, visitor, ts.isVariableDeclaration), visitNode(node.block, visitor, ts.isBlock));
            // Property assignments
            case 281 /* PropertyAssignment */:
                return ts.updatePropertyAssignment(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
            case 282 /* ShorthandPropertyAssignment */:
                return ts.updateShorthandPropertyAssignment(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.objectAssignmentInitializer, visitor, ts.isExpression));
            case 283 /* SpreadAssignment */:
                return ts.updateSpreadAssignment(node, visitNode(node.expression, visitor, ts.isExpression));
            // Enum
            case 284 /* EnumMember */:
                return ts.updateEnumMember(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression));
            // Top-level nodes
            case 290 /* SourceFile */:
                return ts.updateSourceFileNode(node, visitLexicalEnvironment(node.statements, visitor, context));
            // Transformation nodes
            case 326 /* PartiallyEmittedExpression */:
                return ts.updatePartiallyEmittedExpression(node, visitNode(node.expression, visitor, ts.isExpression));
            case 327 /* CommaListExpression */:
                return ts.updateCommaList(node, nodesVisitor(node.elements, visitor, ts.isExpression));
            default:
                // No need to visit nodes with no children.
                return node;
        }
    }
    ts.visitEachChild = visitEachChild;
    /**
     * Extracts the single node from a NodeArray.
     *
     * @param nodes The NodeArray.
     */
    function extractSingleNode(nodes) {
        ts.Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
        return ts.singleOrUndefined(nodes);
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function reduceNode(node, f, initial) {
        return node ? f(initial, node) : initial;
    }
    function reduceNodeArray(nodes, f, initial) {
        return nodes ? f(initial, nodes) : initial;
    }
    /**
     * Similar to `reduceLeft`, performs a reduction against each child of a node.
     * NOTE: Unlike `forEachChild`, this does *not* visit every node.
     *
     * @param node The node containing the children to reduce.
     * @param initial The initial value to supply to the reduction.
     * @param f The callback function
     */
    function reduceEachChild(node, initial, cbNode, cbNodeArray) {
        if (node === undefined) {
            return initial;
        }
        var reduceNodes = cbNodeArray ? reduceNodeArray : ts.reduceLeft;
        var cbNodes = cbNodeArray || cbNode;
        var kind = node.kind;
        // No need to visit nodes with no children.
        if ((kind > 0 /* FirstToken */ && kind <= 152 /* LastToken */)) {
            return initial;
        }
        // We do not yet support types.
        if ((kind >= 168 /* TypePredicate */ && kind <= 187 /* LiteralType */)) {
            return initial;
        }
        var result = initial;
        switch (node.kind) {
            // Leaf nodes
            case 222 /* SemicolonClassElement */:
            case 224 /* EmptyStatement */:
            case 215 /* OmittedExpression */:
            case 241 /* DebuggerStatement */:
            case 325 /* NotEmittedStatement */:
                // No need to visit nodes with no children.
                break;
            // Names
            case 153 /* QualifiedName */:
                result = reduceNode(node.left, cbNode, result);
                result = reduceNode(node.right, cbNode, result);
                break;
            case 154 /* ComputedPropertyName */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Signature elements
            case 156 /* Parameter */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 157 /* Decorator */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Type member
            case 158 /* PropertySignature */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.questionToken, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 159 /* PropertyDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 161 /* MethodDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 162 /* Constructor */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 163 /* GetAccessor */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 164 /* SetAccessor */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            // Binding patterns
            case 189 /* ObjectBindingPattern */:
            case 190 /* ArrayBindingPattern */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 191 /* BindingElement */:
                result = reduceNode(node.propertyName, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            // Expression
            case 192 /* ArrayLiteralExpression */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 193 /* ObjectLiteralExpression */:
                result = reduceNodes(node.properties, cbNodes, result);
                break;
            case 194 /* PropertyAccessExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                break;
            case 195 /* ElementAccessExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.argumentExpression, cbNode, result);
                break;
            case 196 /* CallExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNodes(node.arguments, cbNodes, result);
                break;
            case 197 /* NewExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNodes(node.arguments, cbNodes, result);
                break;
            case 198 /* TaggedTemplateExpression */:
                result = reduceNode(node.tag, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                result = reduceNode(node.template, cbNode, result);
                break;
            case 199 /* TypeAssertionExpression */:
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 201 /* FunctionExpression */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 202 /* ArrowFunction */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 200 /* ParenthesizedExpression */:
            case 203 /* DeleteExpression */:
            case 204 /* TypeOfExpression */:
            case 205 /* VoidExpression */:
            case 206 /* AwaitExpression */:
            case 212 /* YieldExpression */:
            case 213 /* SpreadElement */:
            case 218 /* NonNullExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 207 /* PrefixUnaryExpression */:
            case 208 /* PostfixUnaryExpression */:
                result = reduceNode(node.operand, cbNode, result);
                break;
            case 209 /* BinaryExpression */:
                result = reduceNode(node.left, cbNode, result);
                result = reduceNode(node.right, cbNode, result);
                break;
            case 210 /* ConditionalExpression */:
                result = reduceNode(node.condition, cbNode, result);
                result = reduceNode(node.whenTrue, cbNode, result);
                result = reduceNode(node.whenFalse, cbNode, result);
                break;
            case 211 /* TemplateExpression */:
                result = reduceNode(node.head, cbNode, result);
                result = reduceNodes(node.templateSpans, cbNodes, result);
                break;
            case 214 /* ClassExpression */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.heritageClauses, cbNodes, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 216 /* ExpressionWithTypeArguments */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNodes, result);
                break;
            case 217 /* AsExpression */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                break;
            // Misc
            case 221 /* TemplateSpan */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.literal, cbNode, result);
                break;
            // Element
            case 223 /* Block */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 225 /* VariableStatement */:
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.declarationList, cbNode, result);
                break;
            case 226 /* ExpressionStatement */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 227 /* IfStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.thenStatement, cbNode, result);
                result = reduceNode(node.elseStatement, cbNode, result);
                break;
            case 228 /* DoStatement */:
                result = reduceNode(node.statement, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 229 /* WhileStatement */:
            case 236 /* WithStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 230 /* ForStatement */:
                result = reduceNode(node.initializer, cbNode, result);
                result = reduceNode(node.condition, cbNode, result);
                result = reduceNode(node.incrementor, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 231 /* ForInStatement */:
            case 232 /* ForOfStatement */:
                result = reduceNode(node.initializer, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 235 /* ReturnStatement */:
            case 239 /* ThrowStatement */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 237 /* SwitchStatement */:
                result = reduceNode(node.expression, cbNode, result);
                result = reduceNode(node.caseBlock, cbNode, result);
                break;
            case 238 /* LabeledStatement */:
                result = reduceNode(node.label, cbNode, result);
                result = reduceNode(node.statement, cbNode, result);
                break;
            case 240 /* TryStatement */:
                result = reduceNode(node.tryBlock, cbNode, result);
                result = reduceNode(node.catchClause, cbNode, result);
                result = reduceNode(node.finallyBlock, cbNode, result);
                break;
            case 242 /* VariableDeclaration */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 243 /* VariableDeclarationList */:
                result = reduceNodes(node.declarations, cbNodes, result);
                break;
            case 244 /* FunctionDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.parameters, cbNodes, result);
                result = reduceNode(node.type, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 245 /* ClassDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.typeParameters, cbNodes, result);
                result = reduceNodes(node.heritageClauses, cbNodes, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 248 /* EnumDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNodes(node.members, cbNodes, result);
                break;
            case 249 /* ModuleDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.body, cbNode, result);
                break;
            case 250 /* ModuleBlock */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 251 /* CaseBlock */:
                result = reduceNodes(node.clauses, cbNodes, result);
                break;
            case 253 /* ImportEqualsDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.moduleReference, cbNode, result);
                break;
            case 254 /* ImportDeclaration */:
                result = reduceNodes(node.decorators, cbNodes, result);
                result = reduceNodes(node.modifiers, cbNodes, result);
                result = reduceNode(node.importClause, cbNode, result);
                result = reduceNode(node.moduleSpecifier, cbNode, result);
                break;
            case 255 /* ImportClause */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.namedBindings, cbNode, result);
                break;
            case 256 /* NamespaceImport */:
                result = reduceNode(node.name, cbNode, result);
                break;
            case 262 /* NamespaceExport */:
                result = reduceNode(node.name, cbNode, result);
                break;
            case 257 /* NamedImports */:
            case 261 /* NamedExports */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            case 258 /* ImportSpecifier */:
            case 263 /* ExportSpecifier */:
                result = reduceNode(node.propertyName, cbNode, result);
                result = reduceNode(node.name, cbNode, result);
                break;
            case 259 /* ExportAssignment */:
                result = ts.reduceLeft(node.decorators, cbNode, result);
                result = ts.reduceLeft(node.modifiers, cbNode, result);
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 260 /* ExportDeclaration */:
                result = ts.reduceLeft(node.decorators, cbNode, result);
                result = ts.reduceLeft(node.modifiers, cbNode, result);
                result = reduceNode(node.exportClause, cbNode, result);
                result = reduceNode(node.moduleSpecifier, cbNode, result);
                break;
            // Module references
            case 265 /* ExternalModuleReference */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // JSX
            case 266 /* JsxElement */:
                result = reduceNode(node.openingElement, cbNode, result);
                result = ts.reduceLeft(node.children, cbNode, result);
                result = reduceNode(node.closingElement, cbNode, result);
                break;
            case 270 /* JsxFragment */:
                result = reduceNode(node.openingFragment, cbNode, result);
                result = ts.reduceLeft(node.children, cbNode, result);
                result = reduceNode(node.closingFragment, cbNode, result);
                break;
            case 267 /* JsxSelfClosingElement */:
            case 268 /* JsxOpeningElement */:
                result = reduceNode(node.tagName, cbNode, result);
                result = reduceNodes(node.typeArguments, cbNode, result);
                result = reduceNode(node.attributes, cbNode, result);
                break;
            case 274 /* JsxAttributes */:
                result = reduceNodes(node.properties, cbNodes, result);
                break;
            case 269 /* JsxClosingElement */:
                result = reduceNode(node.tagName, cbNode, result);
                break;
            case 273 /* JsxAttribute */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 275 /* JsxSpreadAttribute */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 276 /* JsxExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Clauses
            case 277 /* CaseClause */:
                result = reduceNode(node.expression, cbNode, result);
            // falls through
            case 278 /* DefaultClause */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            case 279 /* HeritageClause */:
                result = reduceNodes(node.types, cbNodes, result);
                break;
            case 280 /* CatchClause */:
                result = reduceNode(node.variableDeclaration, cbNode, result);
                result = reduceNode(node.block, cbNode, result);
                break;
            // Property assignments
            case 281 /* PropertyAssignment */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            case 282 /* ShorthandPropertyAssignment */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.objectAssignmentInitializer, cbNode, result);
                break;
            case 283 /* SpreadAssignment */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            // Enum
            case 284 /* EnumMember */:
                result = reduceNode(node.name, cbNode, result);
                result = reduceNode(node.initializer, cbNode, result);
                break;
            // Top-level nodes
            case 290 /* SourceFile */:
                result = reduceNodes(node.statements, cbNodes, result);
                break;
            // Transformation nodes
            case 326 /* PartiallyEmittedExpression */:
                result = reduceNode(node.expression, cbNode, result);
                break;
            case 327 /* CommaListExpression */:
                result = reduceNodes(node.elements, cbNodes, result);
                break;
            default:
                break;
        }
        return result;
    }
    ts.reduceEachChild = reduceEachChild;
    function findSpanEnd(array, test, start) {
        var i = start;
        while (i < array.length && test(array[i])) {
            i++;
        }
        return i;
    }
    function mergeLexicalEnvironment(statements, declarations) {
        if (!ts.some(declarations)) {
            return statements;
        }
        // When we merge new lexical statements into an existing statement list, we merge them in the following manner:
        //
        // Given:
        //
        // | Left                               | Right                               |
        // |------------------------------------|-------------------------------------|
        // | [standard prologues (left)]        | [standard prologues (right)]        |
        // | [hoisted functions (left)]         | [hoisted functions (right)]         |
        // | [hoisted variables (left)]         | [hoisted variables (right)]         |
        // | [lexical init statements (left)]   | [lexical init statements (right)]   |
        // | [other statements (left)]          |                                     |
        //
        // The resulting statement list will be:
        //
        // | Result                              |
        // |-------------------------------------|
        // | [standard prologues (right)]        |
        // | [standard prologues (left)]         |
        // | [hoisted functions (right)]         |
        // | [hoisted functions (left)]          |
        // | [hoisted variables (right)]         |
        // | [hoisted variables (left)]          |
        // | [lexical init statements (right)]   |
        // | [lexical init statements (left)]    |
        // | [other statements (left)]           |
        //
        // NOTE: It is expected that new lexical init statements must be evaluated before existing lexical init statements,
        // as the prior transformation may depend on the evaluation of the lexical init statements to be in the correct state.
        // find standard prologues on left in the following order: standard directives, hoisted functions, hoisted variables, other custom
        var leftStandardPrologueEnd = findSpanEnd(statements, ts.isPrologueDirective, 0);
        var leftHoistedFunctionsEnd = findSpanEnd(statements, ts.isHoistedFunction, leftStandardPrologueEnd);
        var leftHoistedVariablesEnd = findSpanEnd(statements, ts.isHoistedVariableStatement, leftHoistedFunctionsEnd);
        // find standard prologues on right in the following order: standard directives, hoisted functions, hoisted variables, other custom
        var rightStandardPrologueEnd = findSpanEnd(declarations, ts.isPrologueDirective, 0);
        var rightHoistedFunctionsEnd = findSpanEnd(declarations, ts.isHoistedFunction, rightStandardPrologueEnd);
        var rightHoistedVariablesEnd = findSpanEnd(declarations, ts.isHoistedVariableStatement, rightHoistedFunctionsEnd);
        var rightCustomPrologueEnd = findSpanEnd(declarations, ts.isCustomPrologue, rightHoistedVariablesEnd);
        ts.Debug.assert(rightCustomPrologueEnd === declarations.length, "Expected declarations to be valid standard or custom prologues");
        // splice prologues from the right into the left. We do this in reverse order
        // so that we don't need to recompute the index on the left when we insert items.
        var left = ts.isNodeArray(statements) ? statements.slice() : statements;
        // splice other custom prologues from right into left
        if (rightCustomPrologueEnd > rightHoistedVariablesEnd) {
            left.splice.apply(left, __spreadArrays([leftHoistedVariablesEnd, 0], declarations.slice(rightHoistedVariablesEnd, rightCustomPrologueEnd)));
        }
        // splice hoisted variables from right into left
        if (rightHoistedVariablesEnd > rightHoistedFunctionsEnd) {
            left.splice.apply(left, __spreadArrays([leftHoistedFunctionsEnd, 0], declarations.slice(rightHoistedFunctionsEnd, rightHoistedVariablesEnd)));
        }
        // splice hoisted functions from right into left
        if (rightHoistedFunctionsEnd > rightStandardPrologueEnd) {
            left.splice.apply(left, __spreadArrays([leftStandardPrologueEnd, 0], declarations.slice(rightStandardPrologueEnd, rightHoistedFunctionsEnd)));
        }
        // splice standard prologues from right into left (that are not already in left)
        if (rightStandardPrologueEnd > 0) {
            if (leftStandardPrologueEnd === 0) {
                left.splice.apply(left, __spreadArrays([0, 0], declarations.slice(0, rightStandardPrologueEnd)));
            }
            else {
                var leftPrologues = ts.createMap();
                for (var i = 0; i < leftStandardPrologueEnd; i++) {
                    var leftPrologue = statements[i];
                    leftPrologues.set(leftPrologue.expression.text, true);
                }
                for (var i = rightStandardPrologueEnd - 1; i >= 0; i--) {
                    var rightPrologue = declarations[i];
                    if (!leftPrologues.has(rightPrologue.expression.text)) {
                        left.unshift(rightPrologue);
                    }
                }
            }
        }
        if (ts.isNodeArray(statements)) {
            return ts.setTextRange(ts.createNodeArray(left, statements.hasTrailingComma), statements);
        }
        return statements;
    }
    ts.mergeLexicalEnvironment = mergeLexicalEnvironment;
    /**
     * Lifts a NodeArray containing only Statement nodes to a block.
     *
     * @param nodes The NodeArray.
     */
    function liftToBlock(nodes) {
        ts.Debug.assert(ts.every(nodes, ts.isStatement), "Cannot lift nodes to a Block.");
        return ts.singleOrUndefined(nodes) || ts.createBlock(nodes);
    }
    ts.liftToBlock = liftToBlock;
    /**
     * Aggregates the TransformFlags for a Node and its subtree.
     */
    function aggregateTransformFlags(node) {
        aggregateTransformFlagsForNode(node);
        return node;
    }
    ts.aggregateTransformFlags = aggregateTransformFlags;
    /**
     * Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are
     * computed first, then the transform flags for the current node are computed from the subtree
     * flags and the state of the current node. Finally, the transform flags of the node are
     * returned, excluding any flags that should not be included in its parent node's subtree
     * flags.
     */
    function aggregateTransformFlagsForNode(node) {
        if (node === undefined) {
            return 0 /* None */;
        }
        if (node.transformFlags & 536870912 /* HasComputedFlags */) {
            return node.transformFlags & ~ts.getTransformFlagsSubtreeExclusions(node.kind);
        }
        var subtreeFlags = aggregateTransformFlagsForSubtree(node);
        return ts.computeTransformFlagsForNode(node, subtreeFlags);
    }
    function aggregateTransformFlagsForNodeArray(nodes) {
        if (nodes === undefined) {
            return 0 /* None */;
        }
        var subtreeFlags = 0 /* None */;
        var nodeArrayFlags = 0 /* None */;
        for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) {
            var node = nodes_3[_i];
            subtreeFlags |= aggregateTransformFlagsForNode(node);
            nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */;
        }
        nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */;
        return subtreeFlags;
    }
    /**
     * Aggregates the transform flags for the subtree of a node.
     */
    function aggregateTransformFlagsForSubtree(node) {
        // We do not transform ambient declarations or types, so there is no need to
        // recursively aggregate transform flags.
        if (ts.hasModifier(node, 2 /* Ambient */) || (ts.isTypeNode(node) && node.kind !== 216 /* ExpressionWithTypeArguments */)) {
            return 0 /* None */;
        }
        // Aggregate the transform flags of each child.
        return reduceEachChild(node, 0 /* None */, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes);
    }
    /**
     * Aggregates the TransformFlags of a child node with the TransformFlags of its
     * siblings.
     */
    function aggregateTransformFlagsForChildNode(transformFlags, node) {
        return transformFlags | aggregateTransformFlagsForNode(node);
    }
    function aggregateTransformFlagsForChildNodes(transformFlags, nodes) {
        return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function createSourceMapGenerator(host, file, sourceRoot, sourcesDirectoryPath, generatorOptions) {
        var _a = generatorOptions.extendedDiagnostics
            ? ts.performance.createTimer("Source Map", "beforeSourcemap", "afterSourcemap")
            : ts.performance.nullTimer, enter = _a.enter, exit = _a.exit;
        // Current source map file and its index in the sources list
        var rawSources = [];
        var sources = [];
        var sourceToSourceIndexMap = ts.createMap();
        var sourcesContent;
        var names = [];
        var nameToNameIndexMap;
        var mappings = "";
        // Last recorded and encoded mappings
        var lastGeneratedLine = 0;
        var lastGeneratedCharacter = 0;
        var lastSourceIndex = 0;
        var lastSourceLine = 0;
        var lastSourceCharacter = 0;
        var lastNameIndex = 0;
        var hasLast = false;
        var pendingGeneratedLine = 0;
        var pendingGeneratedCharacter = 0;
        var pendingSourceIndex = 0;
        var pendingSourceLine = 0;
        var pendingSourceCharacter = 0;
        var pendingNameIndex = 0;
        var hasPending = false;
        var hasPendingSource = false;
        var hasPendingName = false;
        return {
            getSources: function () { return rawSources; },
            addSource: addSource,
            setSourceContent: setSourceContent,
            addName: addName,
            addMapping: addMapping,
            appendSourceMap: appendSourceMap,
            toJSON: toJSON,
            toString: function () { return JSON.stringify(toJSON()); }
        };
        function addSource(fileName) {
            enter();
            var source = ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, fileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
            /*isAbsolutePathAnUrl*/ true);
            var sourceIndex = sourceToSourceIndexMap.get(source);
            if (sourceIndex === undefined) {
                sourceIndex = sources.length;
                sources.push(source);
                rawSources.push(fileName);
                sourceToSourceIndexMap.set(source, sourceIndex);
            }
            exit();
            return sourceIndex;
        }
        /* eslint-disable boolean-trivia, no-null/no-null */
        function setSourceContent(sourceIndex, content) {
            enter();
            if (content !== null) {
                if (!sourcesContent)
                    sourcesContent = [];
                while (sourcesContent.length < sourceIndex) {
                    sourcesContent.push(null);
                }
                sourcesContent[sourceIndex] = content;
            }
            exit();
        }
        /* eslint-enable boolean-trivia, no-null/no-null */
        function addName(name) {
            enter();
            if (!nameToNameIndexMap)
                nameToNameIndexMap = ts.createMap();
            var nameIndex = nameToNameIndexMap.get(name);
            if (nameIndex === undefined) {
                nameIndex = names.length;
                names.push(name);
                nameToNameIndexMap.set(name, nameIndex);
            }
            exit();
            return nameIndex;
        }
        function isNewGeneratedPosition(generatedLine, generatedCharacter) {
            return !hasPending
                || pendingGeneratedLine !== generatedLine
                || pendingGeneratedCharacter !== generatedCharacter;
        }
        function isBacktrackingSourcePosition(sourceIndex, sourceLine, sourceCharacter) {
            return sourceIndex !== undefined
                && sourceLine !== undefined
                && sourceCharacter !== undefined
                && pendingSourceIndex === sourceIndex
                && (pendingSourceLine > sourceLine
                    || pendingSourceLine === sourceLine && pendingSourceCharacter > sourceCharacter);
        }
        function addMapping(generatedLine, generatedCharacter, sourceIndex, sourceLine, sourceCharacter, nameIndex) {
            ts.Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack");
            ts.Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative");
            ts.Debug.assert(sourceIndex === undefined || sourceIndex >= 0, "sourceIndex cannot be negative");
            ts.Debug.assert(sourceLine === undefined || sourceLine >= 0, "sourceLine cannot be negative");
            ts.Debug.assert(sourceCharacter === undefined || sourceCharacter >= 0, "sourceCharacter cannot be negative");
            enter();
            // If this location wasn't recorded or the location in source is going backwards, record the mapping
            if (isNewGeneratedPosition(generatedLine, generatedCharacter) ||
                isBacktrackingSourcePosition(sourceIndex, sourceLine, sourceCharacter)) {
                commitPendingMapping();
                pendingGeneratedLine = generatedLine;
                pendingGeneratedCharacter = generatedCharacter;
                hasPendingSource = false;
                hasPendingName = false;
                hasPending = true;
            }
            if (sourceIndex !== undefined && sourceLine !== undefined && sourceCharacter !== undefined) {
                pendingSourceIndex = sourceIndex;
                pendingSourceLine = sourceLine;
                pendingSourceCharacter = sourceCharacter;
                hasPendingSource = true;
                if (nameIndex !== undefined) {
                    pendingNameIndex = nameIndex;
                    hasPendingName = true;
                }
            }
            exit();
        }
        function appendSourceMap(generatedLine, generatedCharacter, map, sourceMapPath, start, end) {
            ts.Debug.assert(generatedLine >= pendingGeneratedLine, "generatedLine cannot backtrack");
            ts.Debug.assert(generatedCharacter >= 0, "generatedCharacter cannot be negative");
            enter();
            // First, decode the old component sourcemap
            var sourceIndexToNewSourceIndexMap = [];
            var nameIndexToNewNameIndexMap;
            var mappingIterator = decodeMappings(map.mappings);
            for (var iterResult = mappingIterator.next(); !iterResult.done; iterResult = mappingIterator.next()) {
                var raw = iterResult.value;
                if (end && (raw.generatedLine > end.line ||
                    (raw.generatedLine === end.line && raw.generatedCharacter > end.character))) {
                    break;
                }
                if (start && (raw.generatedLine < start.line ||
                    (start.line === raw.generatedLine && raw.generatedCharacter < start.character))) {
                    continue;
                }
                // Then reencode all the updated mappings into the overall map
                var newSourceIndex = void 0;
                var newSourceLine = void 0;
                var newSourceCharacter = void 0;
                var newNameIndex = void 0;
                if (raw.sourceIndex !== undefined) {
                    newSourceIndex = sourceIndexToNewSourceIndexMap[raw.sourceIndex];
                    if (newSourceIndex === undefined) {
                        // Apply offsets to each position and fixup source entries
                        var rawPath = map.sources[raw.sourceIndex];
                        var relativePath = map.sourceRoot ? ts.combinePaths(map.sourceRoot, rawPath) : rawPath;
                        var combinedPath = ts.combinePaths(ts.getDirectoryPath(sourceMapPath), relativePath);
                        sourceIndexToNewSourceIndexMap[raw.sourceIndex] = newSourceIndex = addSource(combinedPath);
                        if (map.sourcesContent && typeof map.sourcesContent[raw.sourceIndex] === "string") {
                            setSourceContent(newSourceIndex, map.sourcesContent[raw.sourceIndex]);
                        }
                    }
                    newSourceLine = raw.sourceLine;
                    newSourceCharacter = raw.sourceCharacter;
                    if (map.names && raw.nameIndex !== undefined) {
                        if (!nameIndexToNewNameIndexMap)
                            nameIndexToNewNameIndexMap = [];
                        newNameIndex = nameIndexToNewNameIndexMap[raw.nameIndex];
                        if (newNameIndex === undefined) {
                            nameIndexToNewNameIndexMap[raw.nameIndex] = newNameIndex = addName(map.names[raw.nameIndex]);
                        }
                    }
                }
                var rawGeneratedLine = raw.generatedLine - (start ? start.line : 0);
                var newGeneratedLine = rawGeneratedLine + generatedLine;
                var rawGeneratedCharacter = start && start.line === raw.generatedLine ? raw.generatedCharacter - start.character : raw.generatedCharacter;
                var newGeneratedCharacter = rawGeneratedLine === 0 ? rawGeneratedCharacter + generatedCharacter : rawGeneratedCharacter;
                addMapping(newGeneratedLine, newGeneratedCharacter, newSourceIndex, newSourceLine, newSourceCharacter, newNameIndex);
            }
            exit();
        }
        function shouldCommitMapping() {
            return !hasLast
                || lastGeneratedLine !== pendingGeneratedLine
                || lastGeneratedCharacter !== pendingGeneratedCharacter
                || lastSourceIndex !== pendingSourceIndex
                || lastSourceLine !== pendingSourceLine
                || lastSourceCharacter !== pendingSourceCharacter
                || lastNameIndex !== pendingNameIndex;
        }
        function commitPendingMapping() {
            if (!hasPending || !shouldCommitMapping()) {
                return;
            }
            enter();
            // Line/Comma delimiters
            if (lastGeneratedLine < pendingGeneratedLine) {
                // Emit line delimiters
                do {
                    mappings += ";";
                    lastGeneratedLine++;
                    lastGeneratedCharacter = 0;
                } while (lastGeneratedLine < pendingGeneratedLine);
            }
            else {
                ts.Debug.assertEqual(lastGeneratedLine, pendingGeneratedLine, "generatedLine cannot backtrack");
                // Emit comma to separate the entry
                if (hasLast) {
                    mappings += ",";
                }
            }
            // 1. Relative generated character
            mappings += base64VLQFormatEncode(pendingGeneratedCharacter - lastGeneratedCharacter);
            lastGeneratedCharacter = pendingGeneratedCharacter;
            if (hasPendingSource) {
                // 2. Relative sourceIndex
                mappings += base64VLQFormatEncode(pendingSourceIndex - lastSourceIndex);
                lastSourceIndex = pendingSourceIndex;
                // 3. Relative source line
                mappings += base64VLQFormatEncode(pendingSourceLine - lastSourceLine);
                lastSourceLine = pendingSourceLine;
                // 4. Relative source character
                mappings += base64VLQFormatEncode(pendingSourceCharacter - lastSourceCharacter);
                lastSourceCharacter = pendingSourceCharacter;
                if (hasPendingName) {
                    // 5. Relative nameIndex
                    mappings += base64VLQFormatEncode(pendingNameIndex - lastNameIndex);
                    lastNameIndex = pendingNameIndex;
                }
            }
            hasLast = true;
            exit();
        }
        function toJSON() {
            commitPendingMapping();
            return {
                version: 3,
                file: file,
                sourceRoot: sourceRoot,
                sources: sources,
                names: names,
                mappings: mappings,
                sourcesContent: sourcesContent,
            };
        }
    }
    ts.createSourceMapGenerator = createSourceMapGenerator;
    // Sometimes tools can see the following line as a source mapping url comment, so we mangle it a bit (the [M])
    var sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\s*$/;
    var whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;
    function getLineInfo(text, lineStarts) {
        return {
            getLineCount: function () { return lineStarts.length; },
            getLineText: function (line) { return text.substring(lineStarts[line], lineStarts[line + 1]); }
        };
    }
    ts.getLineInfo = getLineInfo;
    /**
     * Tries to find the sourceMappingURL comment at the end of a file.
     */
    function tryGetSourceMappingURL(lineInfo) {
        for (var index = lineInfo.getLineCount() - 1; index >= 0; index--) {
            var line = lineInfo.getLineText(index);
            var comment = sourceMapCommentRegExp.exec(line);
            if (comment) {
                return comment[1];
            }
            // If we see a non-whitespace/map comment-like line, break, to avoid scanning up the entire file
            else if (!line.match(whitespaceOrMapCommentRegExp)) {
                break;
            }
        }
    }
    ts.tryGetSourceMappingURL = tryGetSourceMappingURL;
    /* eslint-disable no-null/no-null */
    function isStringOrNull(x) {
        return typeof x === "string" || x === null;
    }
    function isRawSourceMap(x) {
        return x !== null
            && typeof x === "object"
            && x.version === 3
            && typeof x.file === "string"
            && typeof x.mappings === "string"
            && ts.isArray(x.sources) && ts.every(x.sources, ts.isString)
            && (x.sourceRoot === undefined || x.sourceRoot === null || typeof x.sourceRoot === "string")
            && (x.sourcesContent === undefined || x.sourcesContent === null || ts.isArray(x.sourcesContent) && ts.every(x.sourcesContent, isStringOrNull))
            && (x.names === undefined || x.names === null || ts.isArray(x.names) && ts.every(x.names, ts.isString));
    }
    ts.isRawSourceMap = isRawSourceMap;
    /* eslint-enable no-null/no-null */
    function tryParseRawSourceMap(text) {
        try {
            var parsed = JSON.parse(text);
            if (isRawSourceMap(parsed)) {
                return parsed;
            }
        }
        catch (_a) {
            // empty
        }
        return undefined;
    }
    ts.tryParseRawSourceMap = tryParseRawSourceMap;
    function decodeMappings(mappings) {
        var done = false;
        var pos = 0;
        var generatedLine = 0;
        var generatedCharacter = 0;
        var sourceIndex = 0;
        var sourceLine = 0;
        var sourceCharacter = 0;
        var nameIndex = 0;
        var error;
        return {
            get pos() { return pos; },
            get error() { return error; },
            get state() { return captureMapping(/*hasSource*/ true, /*hasName*/ true); },
            next: function () {
                while (!done && pos < mappings.length) {
                    var ch = mappings.charCodeAt(pos);
                    if (ch === 59 /* semicolon */) {
                        // new line
                        generatedLine++;
                        generatedCharacter = 0;
                        pos++;
                        continue;
                    }
                    if (ch === 44 /* comma */) {
                        // Next entry is on same line - no action needed
                        pos++;
                        continue;
                    }
                    var hasSource = false;
                    var hasName = false;
                    generatedCharacter += base64VLQFormatDecode();
                    if (hasReportedError())
                        return stopIterating();
                    if (generatedCharacter < 0)
                        return setErrorAndStopIterating("Invalid generatedCharacter found");
                    if (!isSourceMappingSegmentEnd()) {
                        hasSource = true;
                        sourceIndex += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceIndex < 0)
                            return setErrorAndStopIterating("Invalid sourceIndex found");
                        if (isSourceMappingSegmentEnd())
                            return setErrorAndStopIterating("Unsupported Format: No entries after sourceIndex");
                        sourceLine += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceLine < 0)
                            return setErrorAndStopIterating("Invalid sourceLine found");
                        if (isSourceMappingSegmentEnd())
                            return setErrorAndStopIterating("Unsupported Format: No entries after sourceLine");
                        sourceCharacter += base64VLQFormatDecode();
                        if (hasReportedError())
                            return stopIterating();
                        if (sourceCharacter < 0)
                            return setErrorAndStopIterating("Invalid sourceCharacter found");
                        if (!isSourceMappingSegmentEnd()) {
                            hasName = true;
                            nameIndex += base64VLQFormatDecode();
                            if (hasReportedError())
                                return stopIterating();
                            if (nameIndex < 0)
                                return setErrorAndStopIterating("Invalid nameIndex found");
                            if (!isSourceMappingSegmentEnd())
                                return setErrorAndStopIterating("Unsupported Error Format: Entries after nameIndex");
                        }
                    }
                    return { value: captureMapping(hasSource, hasName), done: done };
                }
                return stopIterating();
            }
        };
        function captureMapping(hasSource, hasName) {
            return {
                generatedLine: generatedLine,
                generatedCharacter: generatedCharacter,
                sourceIndex: hasSource ? sourceIndex : undefined,
                sourceLine: hasSource ? sourceLine : undefined,
                sourceCharacter: hasSource ? sourceCharacter : undefined,
                nameIndex: hasName ? nameIndex : undefined
            };
        }
        function stopIterating() {
            done = true;
            return { value: undefined, done: true };
        }
        function setError(message) {
            if (error === undefined) {
                error = message;
            }
        }
        function setErrorAndStopIterating(message) {
            setError(message);
            return stopIterating();
        }
        function hasReportedError() {
            return error !== undefined;
        }
        function isSourceMappingSegmentEnd() {
            return (pos === mappings.length ||
                mappings.charCodeAt(pos) === 44 /* comma */ ||
                mappings.charCodeAt(pos) === 59 /* semicolon */);
        }
        function base64VLQFormatDecode() {
            var moreDigits = true;
            var shiftCount = 0;
            var value = 0;
            for (; moreDigits; pos++) {
                if (pos >= mappings.length)
                    return setError("Error in decoding base64VLQFormatDecode, past the mapping string"), -1;
                // 6 digit number
                var currentByte = base64FormatDecode(mappings.charCodeAt(pos));
                if (currentByte === -1)
                    return setError("Invalid character in VLQ"), -1;
                // If msb is set, we still have more bits to continue
                moreDigits = (currentByte & 32) !== 0;
                // least significant 5 bits are the next msbs in the final value.
                value = value | ((currentByte & 31) << shiftCount);
                shiftCount += 5;
            }
            // Least significant bit if 1 represents negative and rest of the msb is actual absolute value
            if ((value & 1) === 0) {
                // + number
                value = value >> 1;
            }
            else {
                // - number
                value = value >> 1;
                value = -value;
            }
            return value;
        }
    }
    ts.decodeMappings = decodeMappings;
    function sameMapping(left, right) {
        return left === right
            || left.generatedLine === right.generatedLine
                && left.generatedCharacter === right.generatedCharacter
                && left.sourceIndex === right.sourceIndex
                && left.sourceLine === right.sourceLine
                && left.sourceCharacter === right.sourceCharacter
                && left.nameIndex === right.nameIndex;
    }
    ts.sameMapping = sameMapping;
    function isSourceMapping(mapping) {
        return mapping.sourceIndex !== undefined
            && mapping.sourceLine !== undefined
            && mapping.sourceCharacter !== undefined;
    }
    ts.isSourceMapping = isSourceMapping;
    function base64FormatEncode(value) {
        return value >= 0 && value < 26 ? 65 /* A */ + value :
            value >= 26 && value < 52 ? 97 /* a */ + value - 26 :
                value >= 52 && value < 62 ? 48 /* _0 */ + value - 52 :
                    value === 62 ? 43 /* plus */ :
                        value === 63 ? 47 /* slash */ :
                            ts.Debug.fail(value + ": not a base64 value");
    }
    function base64FormatDecode(ch) {
        return ch >= 65 /* A */ && ch <= 90 /* Z */ ? ch - 65 /* A */ :
            ch >= 97 /* a */ && ch <= 122 /* z */ ? ch - 97 /* a */ + 26 :
                ch >= 48 /* _0 */ && ch <= 57 /* _9 */ ? ch - 48 /* _0 */ + 52 :
                    ch === 43 /* plus */ ? 62 :
                        ch === 47 /* slash */ ? 63 :
                            -1;
    }
    function base64VLQFormatEncode(inValue) {
        // Add a new least significant bit that has the sign of the value.
        // if negative number the least significant bit that gets added to the number has value 1
        // else least significant bit value that gets added is 0
        // eg. -1 changes to binary : 01 [1] => 3
        //     +1 changes to binary : 01 [0] => 2
        if (inValue < 0) {
            inValue = ((-inValue) << 1) + 1;
        }
        else {
            inValue = inValue << 1;
        }
        // Encode 5 bits at a time starting from least significant bits
        var encodedStr = "";
        do {
            var currentDigit = inValue & 31; // 11111
            inValue = inValue >> 5;
            if (inValue > 0) {
                // There are still more digits to decode, set the msb (6th bit)
                currentDigit = currentDigit | 32;
            }
            encodedStr = encodedStr + String.fromCharCode(base64FormatEncode(currentDigit));
        } while (inValue > 0);
        return encodedStr;
    }
    function isSourceMappedPosition(value) {
        return value.sourceIndex !== undefined
            && value.sourcePosition !== undefined;
    }
    function sameMappedPosition(left, right) {
        return left.generatedPosition === right.generatedPosition
            && left.sourceIndex === right.sourceIndex
            && left.sourcePosition === right.sourcePosition;
    }
    function compareSourcePositions(left, right) {
        // Compares sourcePosition without comparing sourceIndex
        // since the mappings are grouped by sourceIndex
        ts.Debug.assert(left.sourceIndex === right.sourceIndex);
        return ts.compareValues(left.sourcePosition, right.sourcePosition);
    }
    function compareGeneratedPositions(left, right) {
        return ts.compareValues(left.generatedPosition, right.generatedPosition);
    }
    function getSourcePositionOfMapping(value) {
        return value.sourcePosition;
    }
    function getGeneratedPositionOfMapping(value) {
        return value.generatedPosition;
    }
    function createDocumentPositionMapper(host, map, mapPath) {
        var mapDirectory = ts.getDirectoryPath(mapPath);
        var sourceRoot = map.sourceRoot ? ts.getNormalizedAbsolutePath(map.sourceRoot, mapDirectory) : mapDirectory;
        var generatedAbsoluteFilePath = ts.getNormalizedAbsolutePath(map.file, mapDirectory);
        var generatedFile = host.getSourceFileLike(generatedAbsoluteFilePath);
        var sourceFileAbsolutePaths = map.sources.map(function (source) { return ts.getNormalizedAbsolutePath(source, sourceRoot); });
        var sourceToSourceIndexMap = ts.createMapFromEntries(sourceFileAbsolutePaths.map(function (source, i) { return [host.getCanonicalFileName(source), i]; }));
        var decodedMappings;
        var generatedMappings;
        var sourceMappings;
        return {
            getSourcePosition: getSourcePosition,
            getGeneratedPosition: getGeneratedPosition
        };
        function processMapping(mapping) {
            var generatedPosition = generatedFile !== undefined
                ? ts.getPositionOfLineAndCharacter(generatedFile, mapping.generatedLine, mapping.generatedCharacter, /*allowEdits*/ true)
                : -1;
            var source;
            var sourcePosition;
            if (isSourceMapping(mapping)) {
                var sourceFile = host.getSourceFileLike(sourceFileAbsolutePaths[mapping.sourceIndex]);
                source = map.sources[mapping.sourceIndex];
                sourcePosition = sourceFile !== undefined
                    ? ts.getPositionOfLineAndCharacter(sourceFile, mapping.sourceLine, mapping.sourceCharacter, /*allowEdits*/ true)
                    : -1;
            }
            return {
                generatedPosition: generatedPosition,
                source: source,
                sourceIndex: mapping.sourceIndex,
                sourcePosition: sourcePosition,
                nameIndex: mapping.nameIndex
            };
        }
        function getDecodedMappings() {
            if (decodedMappings === undefined) {
                var decoder = decodeMappings(map.mappings);
                var mappings = ts.arrayFrom(decoder, processMapping);
                if (decoder.error !== undefined) {
                    if (host.log) {
                        host.log("Encountered error while decoding sourcemap: " + decoder.error);
                    }
                    decodedMappings = ts.emptyArray;
                }
                else {
                    decodedMappings = mappings;
                }
            }
            return decodedMappings;
        }
        function getSourceMappings(sourceIndex) {
            if (sourceMappings === undefined) {
                var lists = [];
                for (var _i = 0, _a = getDecodedMappings(); _i < _a.length; _i++) {
                    var mapping = _a[_i];
                    if (!isSourceMappedPosition(mapping))
                        continue;
                    var list = lists[mapping.sourceIndex];
                    if (!list)
                        lists[mapping.sourceIndex] = list = [];
                    list.push(mapping);
                }
                sourceMappings = lists.map(function (list) { return ts.sortAndDeduplicate(list, compareSourcePositions, sameMappedPosition); });
            }
            return sourceMappings[sourceIndex];
        }
        function getGeneratedMappings() {
            if (generatedMappings === undefined) {
                var list = [];
                for (var _i = 0, _a = getDecodedMappings(); _i < _a.length; _i++) {
                    var mapping = _a[_i];
                    list.push(mapping);
                }
                generatedMappings = ts.sortAndDeduplicate(list, compareGeneratedPositions, sameMappedPosition);
            }
            return generatedMappings;
        }
        function getGeneratedPosition(loc) {
            var sourceIndex = sourceToSourceIndexMap.get(host.getCanonicalFileName(loc.fileName));
            if (sourceIndex === undefined)
                return loc;
            var sourceMappings = getSourceMappings(sourceIndex);
            if (!ts.some(sourceMappings))
                return loc;
            var targetIndex = ts.binarySearchKey(sourceMappings, loc.pos, getSourcePositionOfMapping, ts.compareValues);
            if (targetIndex < 0) {
                // if no exact match, closest is 2's complement of result
                targetIndex = ~targetIndex;
            }
            var mapping = sourceMappings[targetIndex];
            if (mapping === undefined || mapping.sourceIndex !== sourceIndex) {
                return loc;
            }
            return { fileName: generatedAbsoluteFilePath, pos: mapping.generatedPosition }; // Closest pos
        }
        function getSourcePosition(loc) {
            var generatedMappings = getGeneratedMappings();
            if (!ts.some(generatedMappings))
                return loc;
            var targetIndex = ts.binarySearchKey(generatedMappings, loc.pos, getGeneratedPositionOfMapping, ts.compareValues);
            if (targetIndex < 0) {
                // if no exact match, closest is 2's complement of result
                targetIndex = ~targetIndex;
            }
            var mapping = generatedMappings[targetIndex];
            if (mapping === undefined || !isSourceMappedPosition(mapping)) {
                return loc;
            }
            return { fileName: sourceFileAbsolutePaths[mapping.sourceIndex], pos: mapping.sourcePosition }; // Closest pos
        }
    }
    ts.createDocumentPositionMapper = createDocumentPositionMapper;
    ts.identitySourceMapConsumer = {
        getSourcePosition: ts.identity,
        getGeneratedPosition: ts.identity
    };
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getOriginalNodeId(node) {
        node = ts.getOriginalNode(node);
        return node ? ts.getNodeId(node) : 0;
    }
    ts.getOriginalNodeId = getOriginalNodeId;
    function containsDefaultReference(node) {
        if (!node)
            return false;
        if (!ts.isNamedImports(node))
            return false;
        return ts.some(node.elements, isNamedDefaultReference);
    }
    function isNamedDefaultReference(e) {
        return e.propertyName !== undefined && e.propertyName.escapedText === "default" /* Default */;
    }
    function chainBundle(transformSourceFile) {
        return transformSourceFileOrBundle;
        function transformSourceFileOrBundle(node) {
            return node.kind === 290 /* SourceFile */ ? transformSourceFile(node) : transformBundle(node);
        }
        function transformBundle(node) {
            return ts.createBundle(ts.map(node.sourceFiles, transformSourceFile), node.prepends);
        }
    }
    ts.chainBundle = chainBundle;
    function getExportNeedsImportStarHelper(node) {
        return !!ts.getNamespaceDeclarationNode(node);
    }
    ts.getExportNeedsImportStarHelper = getExportNeedsImportStarHelper;
    function getImportNeedsImportStarHelper(node) {
        if (!!ts.getNamespaceDeclarationNode(node)) {
            return true;
        }
        var bindings = node.importClause && node.importClause.namedBindings;
        if (!bindings) {
            return false;
        }
        if (!ts.isNamedImports(bindings))
            return false;
        var defaultRefCount = 0;
        for (var _i = 0, _a = bindings.elements; _i < _a.length; _i++) {
            var binding = _a[_i];
            if (isNamedDefaultReference(binding)) {
                defaultRefCount++;
            }
        }
        // Import star is required if there's default named refs mixed with non-default refs, or if theres non-default refs and it has a default import
        return (defaultRefCount > 0 && defaultRefCount !== bindings.elements.length) || (!!(bindings.elements.length - defaultRefCount) && ts.isDefaultImport(node));
    }
    ts.getImportNeedsImportStarHelper = getImportNeedsImportStarHelper;
    function getImportNeedsImportDefaultHelper(node) {
        // Import default is needed if there's a default import or a default ref and no other refs (meaning an import star helper wasn't requested)
        return !getImportNeedsImportStarHelper(node) && (ts.isDefaultImport(node) || (!!node.importClause && ts.isNamedImports(node.importClause.namedBindings) && containsDefaultReference(node.importClause.namedBindings))); // TODO: GH#18217
    }
    ts.getImportNeedsImportDefaultHelper = getImportNeedsImportDefaultHelper;
    function collectExternalModuleInfo(sourceFile, resolver, compilerOptions) {
        var externalImports = [];
        var exportSpecifiers = ts.createMultiMap();
        var exportedBindings = [];
        var uniqueExports = ts.createMap();
        var exportedNames;
        var hasExportDefault = false;
        var exportEquals;
        var hasExportStarsToExportValues = false;
        var hasImportStar = false;
        var hasImportDefault = false;
        for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
            var node = _a[_i];
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    // import "mod"
                    // import x from "mod"
                    // import * as x from "mod"
                    // import { x, y } from "mod"
                    externalImports.push(node);
                    if (!hasImportStar && getImportNeedsImportStarHelper(node)) {
                        hasImportStar = true;
                    }
                    if (!hasImportDefault && getImportNeedsImportDefaultHelper(node)) {
                        hasImportDefault = true;
                    }
                    break;
                case 253 /* ImportEqualsDeclaration */:
                    if (node.moduleReference.kind === 265 /* ExternalModuleReference */) {
                        // import x = require("mod")
                        externalImports.push(node);
                    }
                    break;
                case 260 /* ExportDeclaration */:
                    if (node.moduleSpecifier) {
                        if (!node.exportClause) {
                            // export * from "mod"
                            externalImports.push(node);
                            hasExportStarsToExportValues = true;
                        }
                        else {
                            // export * as ns from "mod"
                            // export { x, y } from "mod"
                            externalImports.push(node);
                        }
                    }
                    else {
                        // export { x, y }
                        for (var _b = 0, _c = ts.cast(node.exportClause, ts.isNamedExports).elements; _b < _c.length; _b++) {
                            var specifier = _c[_b];
                            if (!uniqueExports.get(ts.idText(specifier.name))) {
                                var name = specifier.propertyName || specifier.name;
                                exportSpecifiers.add(ts.idText(name), specifier);
                                var decl = resolver.getReferencedImportDeclaration(name)
                                    || resolver.getReferencedValueDeclaration(name);
                                if (decl) {
                                    multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
                                }
                                uniqueExports.set(ts.idText(specifier.name), true);
                                exportedNames = ts.append(exportedNames, specifier.name);
                            }
                        }
                    }
                    break;
                case 259 /* ExportAssignment */:
                    if (node.isExportEquals && !exportEquals) {
                        // export = x
                        exportEquals = node;
                    }
                    break;
                case 225 /* VariableStatement */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        for (var _d = 0, _e = node.declarationList.declarations; _d < _e.length; _d++) {
                            var decl = _e[_d];
                            exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames);
                        }
                    }
                    break;
                case 244 /* FunctionDeclaration */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        if (ts.hasModifier(node, 512 /* Default */)) {
                            // export default function() { }
                            if (!hasExportDefault) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
                                hasExportDefault = true;
                            }
                        }
                        else {
                            // export function x() { }
                            var name = node.name;
                            if (!uniqueExports.get(ts.idText(name))) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                uniqueExports.set(ts.idText(name), true);
                                exportedNames = ts.append(exportedNames, name);
                            }
                        }
                    }
                    break;
                case 245 /* ClassDeclaration */:
                    if (ts.hasModifier(node, 1 /* Export */)) {
                        if (ts.hasModifier(node, 512 /* Default */)) {
                            // export default class { }
                            if (!hasExportDefault) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node));
                                hasExportDefault = true;
                            }
                        }
                        else {
                            // export class x { }
                            var name = node.name;
                            if (name && !uniqueExports.get(ts.idText(name))) {
                                multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
                                uniqueExports.set(ts.idText(name), true);
                                exportedNames = ts.append(exportedNames, name);
                            }
                        }
                    }
                    break;
            }
        }
        var externalHelpersImportDeclaration = ts.createExternalHelpersImportDeclarationIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar, hasImportDefault);
        if (externalHelpersImportDeclaration) {
            externalImports.unshift(externalHelpersImportDeclaration);
        }
        return { externalImports: externalImports, exportSpecifiers: exportSpecifiers, exportEquals: exportEquals, hasExportStarsToExportValues: hasExportStarsToExportValues, exportedBindings: exportedBindings, exportedNames: exportedNames, externalHelpersImportDeclaration: externalHelpersImportDeclaration };
    }
    ts.collectExternalModuleInfo = collectExternalModuleInfo;
    function collectExportedVariableInfo(decl, uniqueExports, exportedNames) {
        if (ts.isBindingPattern(decl.name)) {
            for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                var element = _a[_i];
                if (!ts.isOmittedExpression(element)) {
                    exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames);
                }
            }
        }
        else if (!ts.isGeneratedIdentifier(decl.name)) {
            var text = ts.idText(decl.name);
            if (!uniqueExports.get(text)) {
                uniqueExports.set(text, true);
                exportedNames = ts.append(exportedNames, decl.name);
            }
        }
        return exportedNames;
    }
    /** Use a sparse array as a multi-map. */
    function multiMapSparseArrayAdd(map, key, value) {
        var values = map[key];
        if (values) {
            values.push(value);
        }
        else {
            map[key] = values = [value];
        }
        return values;
    }
    /**
     * Used in the module transformer to check if an expression is reasonably without sideeffect,
     *  and thus better to copy into multiple places rather than to cache in a temporary variable
     *  - this is mostly subjective beyond the requirement that the expression not be sideeffecting
     */
    function isSimpleCopiableExpression(expression) {
        return ts.isStringLiteralLike(expression) ||
            expression.kind === 8 /* NumericLiteral */ ||
            ts.isKeyword(expression.kind) ||
            ts.isIdentifier(expression);
    }
    ts.isSimpleCopiableExpression = isSimpleCopiableExpression;
    /**
     * A simple inlinable expression is an expression which can be copied into multiple locations
     * without risk of repeating any sideeffects and whose value could not possibly change between
     * any such locations
     */
    function isSimpleInlineableExpression(expression) {
        return !ts.isIdentifier(expression) && isSimpleCopiableExpression(expression) ||
            ts.isWellKnownSymbolSyntactically(expression);
    }
    ts.isSimpleInlineableExpression = isSimpleInlineableExpression;
    function isCompoundAssignment(kind) {
        return kind >= 63 /* FirstCompoundAssignment */
            && kind <= 74 /* LastCompoundAssignment */;
    }
    ts.isCompoundAssignment = isCompoundAssignment;
    function getNonAssignmentOperatorForCompoundAssignment(kind) {
        switch (kind) {
            case 63 /* PlusEqualsToken */: return 39 /* PlusToken */;
            case 64 /* MinusEqualsToken */: return 40 /* MinusToken */;
            case 65 /* AsteriskEqualsToken */: return 41 /* AsteriskToken */;
            case 66 /* AsteriskAsteriskEqualsToken */: return 42 /* AsteriskAsteriskToken */;
            case 67 /* SlashEqualsToken */: return 43 /* SlashToken */;
            case 68 /* PercentEqualsToken */: return 44 /* PercentToken */;
            case 69 /* LessThanLessThanEqualsToken */: return 47 /* LessThanLessThanToken */;
            case 70 /* GreaterThanGreaterThanEqualsToken */: return 48 /* GreaterThanGreaterThanToken */;
            case 71 /* GreaterThanGreaterThanGreaterThanEqualsToken */: return 49 /* GreaterThanGreaterThanGreaterThanToken */;
            case 72 /* AmpersandEqualsToken */: return 50 /* AmpersandToken */;
            case 73 /* BarEqualsToken */: return 51 /* BarToken */;
            case 74 /* CaretEqualsToken */: return 52 /* CaretToken */;
        }
    }
    ts.getNonAssignmentOperatorForCompoundAssignment = getNonAssignmentOperatorForCompoundAssignment;
    /**
     * Adds super call and preceding prologue directives into the list of statements.
     *
     * @param ctor The constructor node.
     * @param result The list of statements.
     * @param visitor The visitor to apply to each node added to the result array.
     * @returns index of the statement that follows super call
     */
    function addPrologueDirectivesAndInitialSuperCall(ctor, result, visitor) {
        if (ctor.body) {
            var statements = ctor.body.statements;
            // add prologue directives to the list (if any)
            var index = ts.addPrologue(result, statements, /*ensureUseStrict*/ false, visitor);
            if (index === statements.length) {
                // list contains nothing but prologue directives (or empty) - exit
                return index;
            }
            var superIndex = ts.findIndex(statements, function (s) { return ts.isExpressionStatement(s) && ts.isSuperCall(s.expression); }, index);
            if (superIndex > -1) {
                for (var i = index; i <= superIndex; i++) {
                    result.push(ts.visitNode(statements[i], visitor, ts.isStatement));
                }
                return superIndex + 1;
            }
            return index;
        }
        return 0;
    }
    ts.addPrologueDirectivesAndInitialSuperCall = addPrologueDirectivesAndInitialSuperCall;
    /**
     * @param input Template string input strings
     * @param args Names which need to be made file-level unique
     */
    function helperString(input) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return function (uniqueName) {
            var result = "";
            for (var i = 0; i < args.length; i++) {
                result += input[i];
                result += uniqueName(args[i]);
            }
            result += input[input.length - 1];
            return result;
        };
    }
    ts.helperString = helperString;
    /**
     * Gets all the static or all the instance property declarations of a class
     *
     * @param node The class node.
     * @param isStatic A value indicating whether to get properties from the static or instance side of the class.
     */
    function getProperties(node, requireInitializer, isStatic) {
        return ts.filter(node.members, function (m) { return isInitializedOrStaticProperty(m, requireInitializer, isStatic); });
    }
    ts.getProperties = getProperties;
    /**
     * Is a class element either a static or an instance property declaration with an initializer?
     *
     * @param member The class element node.
     * @param isStatic A value indicating whether the member should be a static or instance member.
     */
    function isInitializedOrStaticProperty(member, requireInitializer, isStatic) {
        return ts.isPropertyDeclaration(member)
            && (!!member.initializer || !requireInitializer)
            && ts.hasStaticModifier(member) === isStatic;
    }
    /**
     * Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer.
     *
     * @param member The class element node.
     * @param isStatic A value indicating whether the member should be a static or instance member.
     */
    function isInitializedProperty(member) {
        return member.kind === 159 /* PropertyDeclaration */
            && member.initializer !== undefined;
    }
    ts.isInitializedProperty = isInitializedProperty;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var FlattenLevel;
    (function (FlattenLevel) {
        FlattenLevel[FlattenLevel["All"] = 0] = "All";
        FlattenLevel[FlattenLevel["ObjectRest"] = 1] = "ObjectRest";
    })(FlattenLevel = ts.FlattenLevel || (ts.FlattenLevel = {}));
    /**
     * Flattens a DestructuringAssignment or a VariableDeclaration to an expression.
     *
     * @param node The node to flatten.
     * @param visitor An optional visitor used to visit initializers.
     * @param context The transformation context.
     * @param level Indicates the extent to which flattening should occur.
     * @param needsValue An optional value indicating whether the value from the right-hand-side of
     * the destructuring assignment is needed as part of a larger expression.
     * @param createAssignmentCallback An optional callback used to create the assignment expression.
     */
    function flattenDestructuringAssignment(node, visitor, context, level, needsValue, createAssignmentCallback) {
        var location = node;
        var value;
        if (ts.isDestructuringAssignment(node)) {
            value = node.right;
            while (ts.isEmptyArrayLiteral(node.left) || ts.isEmptyObjectLiteral(node.left)) {
                if (ts.isDestructuringAssignment(value)) {
                    location = node = value;
                    value = node.right;
                }
                else {
                    return ts.visitNode(value, visitor, ts.isExpression);
                }
            }
        }
        var expressions;
        var flattenContext = {
            context: context,
            level: level,
            downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
            hoistTempVariables: true,
            emitExpression: emitExpression,
            emitBindingOrAssignment: emitBindingOrAssignment,
            createArrayBindingOrAssignmentPattern: makeArrayAssignmentPattern,
            createObjectBindingOrAssignmentPattern: makeObjectAssignmentPattern,
            createArrayBindingOrAssignmentElement: makeAssignmentElement,
            visitor: visitor
        };
        if (value) {
            value = ts.visitNode(value, visitor, ts.isExpression);
            if (ts.isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText) ||
                bindingOrAssignmentElementContainsNonLiteralComputedName(node)) {
                // If the right-hand value of the assignment is also an assignment target then
                // we need to cache the right-hand value.
                value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ false, location);
            }
            else if (needsValue) {
                // If the right-hand value of the destructuring assignment needs to be preserved (as
                // is the case when the destructuring assignment is part of a larger expression),
                // then we need to cache the right-hand value.
                //
                // The source map location for the assignment should point to the entire binary
                // expression.
                value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
            }
            else if (ts.nodeIsSynthesized(node)) {
                // Generally, the source map location for a destructuring assignment is the root
                // expression.
                //
                // However, if the root expression is synthesized (as in the case
                // of the initializer when transforming a ForOfStatement), then the source map
                // location should point to the right-hand value of the expression.
                location = value;
            }
        }
        flattenBindingOrAssignmentElement(flattenContext, node, value, location, /*skipInitializer*/ ts.isDestructuringAssignment(node));
        if (value && needsValue) {
            if (!ts.some(expressions)) {
                return value;
            }
            expressions.push(value);
        }
        return ts.aggregateTransformFlags(ts.inlineExpressions(expressions)) || ts.createOmittedExpression();
        function emitExpression(expression) {
            ts.aggregateTransformFlags(expression);
            expressions = ts.append(expressions, expression);
        }
        function emitBindingOrAssignment(target, value, location, original) {
            ts.Debug.assertNode(target, createAssignmentCallback ? ts.isIdentifier : ts.isExpression);
            var expression = createAssignmentCallback
                ? createAssignmentCallback(target, value, location)
                : ts.setTextRange(ts.createAssignment(ts.visitNode(target, visitor, ts.isExpression), value), location);
            expression.original = original;
            emitExpression(expression);
        }
    }
    ts.flattenDestructuringAssignment = flattenDestructuringAssignment;
    function bindingOrAssignmentElementAssignsToName(element, escapedName) {
        var target = ts.getTargetOfBindingOrAssignmentElement(element); // TODO: GH#18217
        if (ts.isBindingOrAssignmentPattern(target)) {
            return bindingOrAssignmentPatternAssignsToName(target, escapedName);
        }
        else if (ts.isIdentifier(target)) {
            return target.escapedText === escapedName;
        }
        return false;
    }
    function bindingOrAssignmentPatternAssignsToName(pattern, escapedName) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        for (var _i = 0, elements_3 = elements; _i < elements_3.length; _i++) {
            var element = elements_3[_i];
            if (bindingOrAssignmentElementAssignsToName(element, escapedName)) {
                return true;
            }
        }
        return false;
    }
    function bindingOrAssignmentElementContainsNonLiteralComputedName(element) {
        var propertyName = ts.tryGetPropertyNameOfBindingOrAssignmentElement(element);
        if (propertyName && ts.isComputedPropertyName(propertyName) && !ts.isLiteralExpression(propertyName.expression)) {
            return true;
        }
        var target = ts.getTargetOfBindingOrAssignmentElement(element);
        return !!target && ts.isBindingOrAssignmentPattern(target) && bindingOrAssignmentPatternContainsNonLiteralComputedName(target);
    }
    function bindingOrAssignmentPatternContainsNonLiteralComputedName(pattern) {
        return !!ts.forEach(ts.getElementsOfBindingOrAssignmentPattern(pattern), bindingOrAssignmentElementContainsNonLiteralComputedName);
    }
    /**
     * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations.
     *
     * @param node The node to flatten.
     * @param visitor An optional visitor used to visit initializers.
     * @param context The transformation context.
     * @param boundValue The value bound to the declaration.
     * @param skipInitializer A value indicating whether to ignore the initializer of `node`.
     * @param hoistTempVariables Indicates whether temporary variables should not be recorded in-line.
     * @param level Indicates the extent to which flattening should occur.
     */
    function flattenDestructuringBinding(node, visitor, context, level, rval, hoistTempVariables, skipInitializer) {
        if (hoistTempVariables === void 0) { hoistTempVariables = false; }
        var pendingExpressions;
        var pendingDeclarations = [];
        var declarations = [];
        var flattenContext = {
            context: context,
            level: level,
            downlevelIteration: !!context.getCompilerOptions().downlevelIteration,
            hoistTempVariables: hoistTempVariables,
            emitExpression: emitExpression,
            emitBindingOrAssignment: emitBindingOrAssignment,
            createArrayBindingOrAssignmentPattern: makeArrayBindingPattern,
            createObjectBindingOrAssignmentPattern: makeObjectBindingPattern,
            createArrayBindingOrAssignmentElement: makeBindingElement,
            visitor: visitor
        };
        if (ts.isVariableDeclaration(node)) {
            var initializer = ts.getInitializerOfBindingOrAssignmentElement(node);
            if (initializer && (ts.isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText) ||
                bindingOrAssignmentElementContainsNonLiteralComputedName(node))) {
                // If the right-hand value of the assignment is also an assignment target then
                // we need to cache the right-hand value.
                initializer = ensureIdentifier(flattenContext, initializer, /*reuseIdentifierExpressions*/ false, initializer);
                node = ts.updateVariableDeclaration(node, node.name, node.type, initializer);
            }
        }
        flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer);
        if (pendingExpressions) {
            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
            if (hoistTempVariables) {
                var value = ts.inlineExpressions(pendingExpressions);
                pendingExpressions = undefined;
                emitBindingOrAssignment(temp, value, /*location*/ undefined, /*original*/ undefined);
            }
            else {
                context.hoistVariableDeclaration(temp);
                var pendingDeclaration = ts.last(pendingDeclarations);
                pendingDeclaration.pendingExpressions = ts.append(pendingDeclaration.pendingExpressions, ts.createAssignment(temp, pendingDeclaration.value));
                ts.addRange(pendingDeclaration.pendingExpressions, pendingExpressions);
                pendingDeclaration.value = temp;
            }
        }
        for (var _i = 0, pendingDeclarations_1 = pendingDeclarations; _i < pendingDeclarations_1.length; _i++) {
            var _a = pendingDeclarations_1[_i], pendingExpressions_1 = _a.pendingExpressions, name = _a.name, value = _a.value, location = _a.location, original = _a.original;
            var variable = ts.createVariableDeclaration(name, 
            /*type*/ undefined, pendingExpressions_1 ? ts.inlineExpressions(ts.append(pendingExpressions_1, value)) : value);
            variable.original = original;
            ts.setTextRange(variable, location);
            ts.aggregateTransformFlags(variable);
            declarations.push(variable);
        }
        return declarations;
        function emitExpression(value) {
            pendingExpressions = ts.append(pendingExpressions, value);
        }
        function emitBindingOrAssignment(target, value, location, original) {
            ts.Debug.assertNode(target, ts.isBindingName);
            if (pendingExpressions) {
                value = ts.inlineExpressions(ts.append(pendingExpressions, value));
                pendingExpressions = undefined;
            }
            pendingDeclarations.push({ pendingExpressions: pendingExpressions, name: target, value: value, location: location, original: original });
        }
    }
    ts.flattenDestructuringBinding = flattenDestructuringBinding;
    /**
     * Flattens a BindingOrAssignmentElement into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param element The element to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     * @param skipInitializer An optional value indicating whether to include the initializer
     * for the element.
     */
    function flattenBindingOrAssignmentElement(flattenContext, element, value, location, skipInitializer) {
        if (!skipInitializer) {
            var initializer = ts.visitNode(ts.getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, ts.isExpression);
            if (initializer) {
                // Combine value and initializer
                value = value ? createDefaultValueCheck(flattenContext, value, initializer, location) : initializer;
            }
            else if (!value) {
                // Use 'void 0' in absence of value and initializer
                value = ts.createVoidZero();
            }
        }
        var bindingTarget = ts.getTargetOfBindingOrAssignmentElement(element); // TODO: GH#18217
        if (ts.isObjectBindingOrAssignmentPattern(bindingTarget)) {
            flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
        }
        else if (ts.isArrayBindingOrAssignmentPattern(bindingTarget)) {
            flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location);
        }
        else {
            flattenContext.emitBindingOrAssignment(bindingTarget, value, location, /*original*/ element); // TODO: GH#18217
        }
    }
    /**
     * Flattens an ObjectBindingOrAssignmentPattern into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param parent The parent element of the pattern.
     * @param pattern The ObjectBindingOrAssignmentPattern to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     */
    function flattenObjectBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        var numElements = elements.length;
        if (numElements !== 1) {
            // For anything other than a single-element destructuring we need to generate a temporary
            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
            // so in that case, we'll intentionally create that temporary.
            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
        }
        var bindingElements;
        var computedTempVariables;
        for (var i = 0; i < numElements; i++) {
            var element = elements[i];
            if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
                var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(element);
                if (flattenContext.level >= 1 /* ObjectRest */
                    && !(element.transformFlags & (8192 /* ContainsRestOrSpread */ | 16384 /* ContainsObjectRestOrSpread */))
                    && !(ts.getTargetOfBindingOrAssignmentElement(element).transformFlags & (8192 /* ContainsRestOrSpread */ | 16384 /* ContainsObjectRestOrSpread */))
                    && !ts.isComputedPropertyName(propertyName)) {
                    bindingElements = ts.append(bindingElements, ts.visitNode(element, flattenContext.visitor));
                }
                else {
                    if (bindingElements) {
                        flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
                        bindingElements = undefined;
                    }
                    var rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName);
                    if (ts.isComputedPropertyName(propertyName)) {
                        computedTempVariables = ts.append(computedTempVariables, rhsValue.argumentExpression);
                    }
                    flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
                }
            }
            else if (i === numElements - 1) {
                if (bindingElements) {
                    flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
                    bindingElements = undefined;
                }
                var rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables, pattern); // TODO: GH#18217
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element);
            }
        }
        if (bindingElements) {
            flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        }
    }
    /**
     * Flattens an ArrayBindingOrAssignmentPattern into zero or more bindings or assignments.
     *
     * @param flattenContext Options used to control flattening.
     * @param parent The parent element of the pattern.
     * @param pattern The ArrayBindingOrAssignmentPattern to flatten.
     * @param value The current RHS value to assign to the element.
     * @param location The location to use for source maps and comments.
     */
    function flattenArrayBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) {
        var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern);
        var numElements = elements.length;
        if (flattenContext.level < 1 /* ObjectRest */ && flattenContext.downlevelIteration) {
            // Read the elements of the iterable into an array
            value = ensureIdentifier(flattenContext, ts.createReadHelper(flattenContext.context, value, numElements > 0 && ts.getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1])
                ? undefined
                : numElements, location), 
            /*reuseIdentifierExpressions*/ false, location);
        }
        else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0)
            || ts.every(elements, ts.isOmittedExpression)) {
            // For anything other than a single-element destructuring we need to generate a temporary
            // to ensure value is evaluated exactly once. Additionally, if we have zero elements
            // we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
            // so in that case, we'll intentionally create that temporary.
            // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]",
            // then we will create temporary variable.
            var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0;
            value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location);
        }
        var bindingElements;
        var restContainingElements;
        for (var i = 0; i < numElements; i++) {
            var element = elements[i];
            if (flattenContext.level >= 1 /* ObjectRest */) {
                // If an array pattern contains an ObjectRest, we must cache the result so that we
                // can perform the ObjectRest destructuring in a different declaration
                if (element.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                    var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                    if (flattenContext.hoistTempVariables) {
                        flattenContext.context.hoistVariableDeclaration(temp);
                    }
                    restContainingElements = ts.append(restContainingElements, [temp, element]);
                    bindingElements = ts.append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp));
                }
                else {
                    bindingElements = ts.append(bindingElements, element);
                }
            }
            else if (ts.isOmittedExpression(element)) {
                continue;
            }
            else if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) {
                var rhsValue = ts.createElementAccess(value, i);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
            }
            else if (i === numElements - 1) {
                var rhsValue = ts.createArraySlice(value, i);
                flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element);
            }
        }
        if (bindingElements) {
            flattenContext.emitBindingOrAssignment(flattenContext.createArrayBindingOrAssignmentPattern(bindingElements), value, location, pattern);
        }
        if (restContainingElements) {
            for (var _i = 0, restContainingElements_1 = restContainingElements; _i < restContainingElements_1.length; _i++) {
                var _a = restContainingElements_1[_i], id = _a[0], element = _a[1];
                flattenBindingOrAssignmentElement(flattenContext, element, id, element);
            }
        }
    }
    /**
     * Creates an expression used to provide a default value if a value is `undefined` at runtime.
     *
     * @param flattenContext Options used to control flattening.
     * @param value The RHS value to test.
     * @param defaultValue The default value to use if `value` is `undefined` at runtime.
     * @param location The location to use for source maps and comments.
     */
    function createDefaultValueCheck(flattenContext, value, defaultValue, location) {
        value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location);
        return ts.createConditional(ts.createTypeCheck(value, "undefined"), defaultValue, value);
    }
    /**
     * Creates either a PropertyAccessExpression or an ElementAccessExpression for the
     * right-hand side of a transformed destructuring assignment.
     *
     * @link https://tc39.github.io/ecma262/#sec-runtime-semantics-keyeddestructuringassignmentevaluation
     *
     * @param flattenContext Options used to control flattening.
     * @param value The RHS value that is the source of the property.
     * @param propertyName The destructuring property name.
     */
    function createDestructuringPropertyAccess(flattenContext, value, propertyName) {
        if (ts.isComputedPropertyName(propertyName)) {
            var argumentExpression = ensureIdentifier(flattenContext, ts.visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName);
            return ts.createElementAccess(value, argumentExpression);
        }
        else if (ts.isStringOrNumericLiteralLike(propertyName)) {
            var argumentExpression = ts.getSynthesizedClone(propertyName);
            argumentExpression.text = argumentExpression.text;
            return ts.createElementAccess(value, argumentExpression);
        }
        else {
            var name = ts.createIdentifier(ts.idText(propertyName));
            return ts.createPropertyAccess(value, name);
        }
    }
    /**
     * Ensures that there exists a declared identifier whose value holds the given expression.
     * This function is useful to ensure that the expression's value can be read from in subsequent expressions.
     * Unless 'reuseIdentifierExpressions' is false, 'value' will be returned if it is just an identifier.
     *
     * @param flattenContext Options used to control flattening.
     * @param value the expression whose value needs to be bound.
     * @param reuseIdentifierExpressions true if identifier expressions can simply be returned;
     * false if it is necessary to always emit an identifier.
     * @param location The location to use for source maps and comments.
     */
    function ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location) {
        if (ts.isIdentifier(value) && reuseIdentifierExpressions) {
            return value;
        }
        else {
            var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
            if (flattenContext.hoistTempVariables) {
                flattenContext.context.hoistVariableDeclaration(temp);
                flattenContext.emitExpression(ts.setTextRange(ts.createAssignment(temp, value), location));
            }
            else {
                flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined);
            }
            return temp;
        }
    }
    function makeArrayBindingPattern(elements) {
        ts.Debug.assertEachNode(elements, ts.isArrayBindingElement);
        return ts.createArrayBindingPattern(elements);
    }
    function makeArrayAssignmentPattern(elements) {
        return ts.createArrayLiteral(ts.map(elements, ts.convertToArrayAssignmentElement));
    }
    function makeObjectBindingPattern(elements) {
        ts.Debug.assertEachNode(elements, ts.isBindingElement);
        return ts.createObjectBindingPattern(elements);
    }
    function makeObjectAssignmentPattern(elements) {
        return ts.createObjectLiteral(ts.map(elements, ts.convertToObjectAssignmentElement));
    }
    function makeBindingElement(name) {
        return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name);
    }
    function makeAssignmentElement(name) {
        return name;
    }
    ts.restHelper = {
        name: "typescript:rest",
        importName: "__rest",
        scoped: false,
        text: "\n            var __rest = (this && this.__rest) || function (s, e) {\n                var t = {};\n                for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n                    t[p] = s[p];\n                if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n                    for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n                        if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n                            t[p[i]] = s[p[i]];\n                    }\n                return t;\n            };"
    };
    /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
     * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`
     */
    function createRestCall(context, value, elements, computedTempVariables, location) {
        context.requestEmitHelper(ts.restHelper);
        var propertyNames = [];
        var computedTempVariableOffset = 0;
        for (var i = 0; i < elements.length - 1; i++) {
            var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(elements[i]);
            if (propertyName) {
                if (ts.isComputedPropertyName(propertyName)) {
                    var temp = computedTempVariables[computedTempVariableOffset];
                    computedTempVariableOffset++;
                    // typeof _tmp === "symbol" ? _tmp : _tmp + ""
                    propertyNames.push(ts.createConditional(ts.createTypeCheck(temp, "symbol"), temp, ts.createAdd(temp, ts.createLiteral(""))));
                }
                else {
                    propertyNames.push(ts.createLiteral(propertyName));
                }
            }
        }
        return ts.createCall(ts.getUnscopedHelperName("__rest"), 
        /*typeArguments*/ undefined, [
            value,
            ts.setTextRange(ts.createArrayLiteral(propertyNames), location)
        ]);
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ProcessLevel;
    (function (ProcessLevel) {
        ProcessLevel[ProcessLevel["LiftRestriction"] = 0] = "LiftRestriction";
        ProcessLevel[ProcessLevel["All"] = 1] = "All";
    })(ProcessLevel = ts.ProcessLevel || (ts.ProcessLevel = {}));
    function processTaggedTemplateExpression(context, node, visitor, currentSourceFile, recordTaggedTemplateString, level) {
        // Visit the tag expression
        var tag = ts.visitNode(node.tag, visitor, ts.isExpression);
        // Build up the template arguments and the raw and cooked strings for the template.
        // We start out with 'undefined' for the first argument and revisit later
        // to avoid walking over the template string twice and shifting all our arguments over after the fact.
        var templateArguments = [undefined];
        var cookedStrings = [];
        var rawStrings = [];
        var template = node.template;
        if (level === ProcessLevel.LiftRestriction && !ts.hasInvalidEscape(template))
            return node;
        if (ts.isNoSubstitutionTemplateLiteral(template)) {
            cookedStrings.push(createTemplateCooked(template));
            rawStrings.push(getRawLiteral(template, currentSourceFile));
        }
        else {
            cookedStrings.push(createTemplateCooked(template.head));
            rawStrings.push(getRawLiteral(template.head, currentSourceFile));
            for (var _i = 0, _a = template.templateSpans; _i < _a.length; _i++) {
                var templateSpan = _a[_i];
                cookedStrings.push(createTemplateCooked(templateSpan.literal));
                rawStrings.push(getRawLiteral(templateSpan.literal, currentSourceFile));
                templateArguments.push(ts.visitNode(templateSpan.expression, visitor, ts.isExpression));
            }
        }
        var helperCall = createTemplateObjectHelper(context, ts.createArrayLiteral(cookedStrings), ts.createArrayLiteral(rawStrings));
        // Create a variable to cache the template object if we're in a module.
        // Do not do this in the global scope, as any variable we currently generate could conflict with
        // variables from outside of the current compilation. In the future, we can revisit this behavior.
        if (ts.isExternalModule(currentSourceFile)) {
            var tempVar = ts.createUniqueName("templateObject");
            recordTaggedTemplateString(tempVar);
            templateArguments[0] = ts.createLogicalOr(tempVar, ts.createAssignment(tempVar, helperCall));
        }
        else {
            templateArguments[0] = helperCall;
        }
        return ts.createCall(tag, /*typeArguments*/ undefined, templateArguments);
    }
    ts.processTaggedTemplateExpression = processTaggedTemplateExpression;
    function createTemplateCooked(template) {
        return template.templateFlags ? ts.createIdentifier("undefined") : ts.createLiteral(template.text);
    }
    /**
     * Creates an ES5 compatible literal from an ES6 template literal.
     *
     * @param node The ES6 template literal.
     */
    function getRawLiteral(node, currentSourceFile) {
        // Find original source text, since we need to emit the raw strings of the tagged template.
        // The raw strings contain the (escaped) strings of what the user wrote.
        // Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
        var text = node.rawText;
        if (text === undefined) {
            text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
            // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
            // thus we need to remove those characters.
            // First template piece starts with "`", others with "}"
            // Last template piece ends with "`", others with "${"
            var isLast = node.kind === 14 /* NoSubstitutionTemplateLiteral */ || node.kind === 17 /* TemplateTail */;
            text = text.substring(1, text.length - (isLast ? 1 : 2));
        }
        // Newline normalization:
        // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
        // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
        text = text.replace(/\r\n?/g, "\n");
        return ts.setTextRange(ts.createLiteral(text), node);
    }
    function createTemplateObjectHelper(context, cooked, raw) {
        context.requestEmitHelper(ts.templateObjectHelper);
        return ts.createCall(ts.getUnscopedHelperName("__makeTemplateObject"), 
        /*typeArguments*/ undefined, [
            cooked,
            raw
        ]);
    }
    ts.templateObjectHelper = {
        name: "typescript:makeTemplateObject",
        importName: "__makeTemplateObject",
        scoped: false,
        priority: 0,
        text: "\n            var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {\n                if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n                return cooked;\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /**
     * Indicates whether to emit type metadata in the new format.
     */
    var USE_NEW_TYPE_METADATA_FORMAT = false;
    var TypeScriptSubstitutionFlags;
    (function (TypeScriptSubstitutionFlags) {
        /** Enables substitutions for decorated classes. */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["ClassAliases"] = 1] = "ClassAliases";
        /** Enables substitutions for namespace exports. */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NamespaceExports"] = 2] = "NamespaceExports";
        /* Enables substitutions for unqualified enum members */
        TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NonQualifiedEnumMembers"] = 8] = "NonQualifiedEnumMembers";
    })(TypeScriptSubstitutionFlags || (TypeScriptSubstitutionFlags = {}));
    var ClassFacts;
    (function (ClassFacts) {
        ClassFacts[ClassFacts["None"] = 0] = "None";
        ClassFacts[ClassFacts["HasStaticInitializedProperties"] = 1] = "HasStaticInitializedProperties";
        ClassFacts[ClassFacts["HasConstructorDecorators"] = 2] = "HasConstructorDecorators";
        ClassFacts[ClassFacts["HasMemberDecorators"] = 4] = "HasMemberDecorators";
        ClassFacts[ClassFacts["IsExportOfNamespace"] = 8] = "IsExportOfNamespace";
        ClassFacts[ClassFacts["IsNamedExternalExport"] = 16] = "IsNamedExternalExport";
        ClassFacts[ClassFacts["IsDefaultExternalExport"] = 32] = "IsDefaultExternalExport";
        ClassFacts[ClassFacts["IsDerivedClass"] = 64] = "IsDerivedClass";
        ClassFacts[ClassFacts["UseImmediatelyInvokedFunctionExpression"] = 128] = "UseImmediatelyInvokedFunctionExpression";
        ClassFacts[ClassFacts["HasAnyDecorators"] = 6] = "HasAnyDecorators";
        ClassFacts[ClassFacts["NeedsName"] = 5] = "NeedsName";
        ClassFacts[ClassFacts["MayNeedImmediatelyInvokedFunctionExpression"] = 7] = "MayNeedImmediatelyInvokedFunctionExpression";
        ClassFacts[ClassFacts["IsExported"] = 56] = "IsExported";
    })(ClassFacts || (ClassFacts = {}));
    function transformTypeScript(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks");
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        // Save the previous transformation hooks.
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        // Set new transformation hooks.
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        // Enable substitution for property/element access to emit const enum values.
        context.enableSubstitution(194 /* PropertyAccessExpression */);
        context.enableSubstitution(195 /* ElementAccessExpression */);
        // These variables contain state that changes as we descend into the tree.
        var currentSourceFile;
        var currentNamespace;
        var currentNamespaceContainerName;
        var currentLexicalScope;
        var currentNameScope;
        var currentScopeFirstDeclarationsOfName;
        var currentClassHasParameterProperties;
        /**
         * Keeps track of whether expression substitution has been enabled for specific edge cases.
         * They are persisted between each SourceFile transformation and should not be reset.
         */
        var enabledSubstitutions;
        /**
         * A map that keeps track of aliases created for classes with decorators to avoid issues
         * with the double-binding behavior of classes.
         */
        var classAliases;
        /**
         * Keeps track of whether we are within any containing namespaces when performing
         * just-in-time substitution while printing an expression identifier.
         */
        var applicableSubstitutions;
        return transformSourceFileOrBundle;
        function transformSourceFileOrBundle(node) {
            if (node.kind === 291 /* Bundle */) {
                return transformBundle(node);
            }
            return transformSourceFile(node);
        }
        function transformBundle(node) {
            return ts.createBundle(node.sourceFiles.map(transformSourceFile), ts.mapDefined(node.prepends, function (prepend) {
                if (prepend.kind === 293 /* InputFiles */) {
                    return ts.createUnparsedSourceFile(prepend, "js");
                }
                return prepend;
            }));
        }
        /**
         * Transform TypeScript-specific syntax in a SourceFile.
         *
         * @param node A SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = saveStateAndInvoke(node, visitSourceFile);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            return visited;
        }
        /**
         * Visits a node, saving and restoring state variables on the stack.
         *
         * @param node The node to visit.
         */
        function saveStateAndInvoke(node, f) {
            // Save state
            var savedCurrentScope = currentLexicalScope;
            var savedCurrentNameScope = currentNameScope;
            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
            var savedCurrentClassHasParameterProperties = currentClassHasParameterProperties;
            // Handle state changes before visiting a node.
            onBeforeVisitNode(node);
            var visited = f(node);
            // Restore state
            if (currentLexicalScope !== savedCurrentScope) {
                currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
            }
            currentLexicalScope = savedCurrentScope;
            currentNameScope = savedCurrentNameScope;
            currentClassHasParameterProperties = savedCurrentClassHasParameterProperties;
            return visited;
        }
        /**
         * Performs actions that should always occur immediately before visiting a node.
         *
         * @param node The node to visit.
         */
        function onBeforeVisitNode(node) {
            switch (node.kind) {
                case 290 /* SourceFile */:
                case 251 /* CaseBlock */:
                case 250 /* ModuleBlock */:
                case 223 /* Block */:
                    currentLexicalScope = node;
                    currentNameScope = undefined;
                    currentScopeFirstDeclarationsOfName = undefined;
                    break;
                case 245 /* ClassDeclaration */:
                case 244 /* FunctionDeclaration */:
                    if (ts.hasModifier(node, 2 /* Ambient */)) {
                        break;
                    }
                    // Record these declarations provided that they have a name.
                    if (node.name) {
                        recordEmittedDeclarationInScope(node);
                    }
                    else {
                        // These nodes should always have names unless they are default-exports;
                        // however, class declaration parsing allows for undefined names, so syntactically invalid
                        // programs may also have an undefined name.
                        ts.Debug.assert(node.kind === 245 /* ClassDeclaration */ || ts.hasModifier(node, 512 /* Default */));
                    }
                    if (ts.isClassDeclaration(node)) {
                        // XXX: should probably also cover interfaces and type aliases that can have type variables?
                        currentNameScope = node;
                    }
                    break;
            }
        }
        /**
         * General-purpose node visitor.
         *
         * @param node The node to visit.
         */
        function visitor(node) {
            return saveStateAndInvoke(node, visitorWorker);
        }
        /**
         * Visits and possibly transforms any node.
         *
         * @param node The node to visit.
         */
        function visitorWorker(node) {
            if (node.transformFlags & 1 /* ContainsTypeScript */) {
                return visitTypeScript(node);
            }
            return node;
        }
        /**
         * Specialized visitor that visits the immediate children of a SourceFile.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            return saveStateAndInvoke(node, sourceElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a SourceFile.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitorWorker(node) {
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                case 253 /* ImportEqualsDeclaration */:
                case 259 /* ExportAssignment */:
                case 260 /* ExportDeclaration */:
                    return visitEllidableStatement(node);
                default:
                    return visitorWorker(node);
            }
        }
        function visitEllidableStatement(node) {
            var parsed = ts.getParseTreeNode(node);
            if (parsed !== node) {
                // If the node has been transformed by a `before` transformer, perform no ellision on it
                // As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
                // We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by the switch-case in `visitTypeScript`,
                // and will trigger debug failures when debug verbosity is turned up
                if (node.transformFlags & 1 /* ContainsTypeScript */) {
                    // This node contains TypeScript, so we should visit its children.
                    return ts.visitEachChild(node, visitor, context);
                }
                // Otherwise, we can just return the node
                return node;
            }
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 259 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 260 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                default:
                    ts.Debug.fail("Unhandled ellided statement");
            }
        }
        /**
         * Specialized visitor that visits the immediate children of a namespace.
         *
         * @param node The node to visit.
         */
        function namespaceElementVisitor(node) {
            return saveStateAndInvoke(node, namespaceElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a namespace.
         *
         * @param node The node to visit.
         */
        function namespaceElementVisitorWorker(node) {
            if (node.kind === 260 /* ExportDeclaration */ ||
                node.kind === 254 /* ImportDeclaration */ ||
                node.kind === 255 /* ImportClause */ ||
                (node.kind === 253 /* ImportEqualsDeclaration */ &&
                    node.moduleReference.kind === 265 /* ExternalModuleReference */)) {
                // do not emit ES6 imports and exports since they are illegal inside a namespace
                return undefined;
            }
            else if (node.transformFlags & 1 /* ContainsTypeScript */ || ts.hasModifier(node, 1 /* Export */)) {
                return visitTypeScript(node);
            }
            return node;
        }
        /**
         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
         *
         * @param node The node to visit.
         */
        function classElementVisitor(node) {
            return saveStateAndInvoke(node, classElementVisitorWorker);
        }
        /**
         * Specialized visitor that visits the immediate children of a class with TypeScript syntax.
         *
         * @param node The node to visit.
         */
        function classElementVisitorWorker(node) {
            switch (node.kind) {
                case 162 /* Constructor */:
                    return visitConstructor(node);
                case 159 /* PropertyDeclaration */:
                    // Property declarations are not TypeScript syntax, but they must be visited
                    // for the decorator transformation.
                    return visitPropertyDeclaration(node);
                case 167 /* IndexSignature */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 161 /* MethodDeclaration */:
                    // Fallback to the default visit behavior.
                    return visitorWorker(node);
                case 222 /* SemicolonClassElement */:
                    return node;
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function modifierVisitor(node) {
            if (ts.modifierToFlag(node.kind) & 2270 /* TypeScriptModifier */) {
                return undefined;
            }
            else if (currentNamespace && node.kind === 89 /* ExportKeyword */) {
                return undefined;
            }
            return node;
        }
        /**
         * Branching visitor, visits a TypeScript syntax node.
         *
         * @param node The node to visit.
         */
        function visitTypeScript(node) {
            if (ts.isStatement(node) && ts.hasModifier(node, 2 /* Ambient */)) {
                // TypeScript ambient declarations are elided, but some comments may be preserved.
                // See the implementation of `getLeadingComments` in comments.ts for more details.
                return ts.createNotEmittedStatement(node);
            }
            switch (node.kind) {
                case 89 /* ExportKeyword */:
                case 84 /* DefaultKeyword */:
                    // ES6 export and default modifiers are elided when inside a namespace.
                    return currentNamespace ? undefined : node;
                case 119 /* PublicKeyword */:
                case 117 /* PrivateKeyword */:
                case 118 /* ProtectedKeyword */:
                case 122 /* AbstractKeyword */:
                case 81 /* ConstKeyword */:
                case 130 /* DeclareKeyword */:
                case 138 /* ReadonlyKeyword */:
                // TypeScript accessibility and readonly modifiers are elided
                // falls through
                case 174 /* ArrayType */:
                case 175 /* TupleType */:
                case 176 /* OptionalType */:
                case 177 /* RestType */:
                case 173 /* TypeLiteral */:
                case 168 /* TypePredicate */:
                case 155 /* TypeParameter */:
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 128 /* BooleanKeyword */:
                case 143 /* StringKeyword */:
                case 140 /* NumberKeyword */:
                case 137 /* NeverKeyword */:
                case 110 /* VoidKeyword */:
                case 144 /* SymbolKeyword */:
                case 171 /* ConstructorType */:
                case 170 /* FunctionType */:
                case 172 /* TypeQuery */:
                case 169 /* TypeReference */:
                case 178 /* UnionType */:
                case 179 /* IntersectionType */:
                case 180 /* ConditionalType */:
                case 182 /* ParenthesizedType */:
                case 183 /* ThisType */:
                case 184 /* TypeOperator */:
                case 185 /* IndexedAccessType */:
                case 186 /* MappedType */:
                case 187 /* LiteralType */:
                // TypeScript type nodes are elided.
                // falls through
                case 167 /* IndexSignature */:
                // TypeScript index signatures are elided.
                // falls through
                case 157 /* Decorator */:
                // TypeScript decorators are elided. They will be emitted as part of visitClassDeclaration.
                // falls through
                case 247 /* TypeAliasDeclaration */:
                    // TypeScript type-only declarations are elided.
                    return undefined;
                case 159 /* PropertyDeclaration */:
                    // TypeScript property declarations are elided. However their names are still visited, and can potentially be retained if they could have sideeffects
                    return visitPropertyDeclaration(node);
                case 252 /* NamespaceExportDeclaration */:
                    // TypeScript namespace export declarations are elided.
                    return undefined;
                case 162 /* Constructor */:
                    return visitConstructor(node);
                case 246 /* InterfaceDeclaration */:
                    // TypeScript interfaces are elided, but some comments may be preserved.
                    // See the implementation of `getLeadingComments` in comments.ts for more details.
                    return ts.createNotEmittedStatement(node);
                case 245 /* ClassDeclaration */:
                    // This may be a class declaration with TypeScript syntax extensions.
                    //
                    // TypeScript class syntax extensions include:
                    // - decorators
                    // - optional `implements` heritage clause
                    // - parameter property assignments in the constructor
                    // - index signatures
                    // - method overload signatures
                    return visitClassDeclaration(node);
                case 214 /* ClassExpression */:
                    // This may be a class expression with TypeScript syntax extensions.
                    //
                    // TypeScript class syntax extensions include:
                    // - decorators
                    // - optional `implements` heritage clause
                    // - parameter property assignments in the constructor
                    // - index signatures
                    // - method overload signatures
                    return visitClassExpression(node);
                case 279 /* HeritageClause */:
                    // This may be a heritage clause with TypeScript syntax extensions.
                    //
                    // TypeScript heritage clause extensions include:
                    // - `implements` clause
                    return visitHeritageClause(node);
                case 216 /* ExpressionWithTypeArguments */:
                    // TypeScript supports type arguments on an expression in an `extends` heritage clause.
                    return visitExpressionWithTypeArguments(node);
                case 161 /* MethodDeclaration */:
                    // TypeScript method declarations may have decorators, modifiers
                    // or type annotations.
                    return visitMethodDeclaration(node);
                case 163 /* GetAccessor */:
                    // Get Accessors can have TypeScript modifiers, decorators, and type annotations.
                    return visitGetAccessor(node);
                case 164 /* SetAccessor */:
                    // Set Accessors can have TypeScript modifiers and type annotations.
                    return visitSetAccessor(node);
                case 244 /* FunctionDeclaration */:
                    // Typescript function declarations can have modifiers, decorators, and type annotations.
                    return visitFunctionDeclaration(node);
                case 201 /* FunctionExpression */:
                    // TypeScript function expressions can have modifiers and type annotations.
                    return visitFunctionExpression(node);
                case 202 /* ArrowFunction */:
                    // TypeScript arrow functions can have modifiers and type annotations.
                    return visitArrowFunction(node);
                case 156 /* Parameter */:
                    // This may be a parameter declaration with TypeScript syntax extensions.
                    //
                    // TypeScript parameter declaration syntax extensions include:
                    // - decorators
                    // - accessibility modifiers
                    // - the question mark (?) token for optional parameters
                    // - type annotations
                    // - this parameters
                    return visitParameter(node);
                case 200 /* ParenthesizedExpression */:
                    // ParenthesizedExpressions are TypeScript if their expression is a
                    // TypeAssertion or AsExpression
                    return visitParenthesizedExpression(node);
                case 199 /* TypeAssertionExpression */:
                case 217 /* AsExpression */:
                    // TypeScript type assertions are removed, but their subtrees are preserved.
                    return visitAssertionExpression(node);
                case 196 /* CallExpression */:
                    return visitCallExpression(node);
                case 197 /* NewExpression */:
                    return visitNewExpression(node);
                case 198 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 218 /* NonNullExpression */:
                    // TypeScript non-null expressions are removed, but their subtrees are preserved.
                    return visitNonNullExpression(node);
                case 248 /* EnumDeclaration */:
                    // TypeScript enum declarations do not exist in ES6 and must be rewritten.
                    return visitEnumDeclaration(node);
                case 225 /* VariableStatement */:
                    // TypeScript namespace exports for variable statements must be transformed.
                    return visitVariableStatement(node);
                case 242 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 249 /* ModuleDeclaration */:
                    // TypeScript namespace declarations must be transformed.
                    return visitModuleDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    // TypeScript namespace or external module import.
                    return visitImportEqualsDeclaration(node);
                case 267 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node);
                case 268 /* JsxOpeningElement */:
                    return visitJsxJsxOpeningElement(node);
                default:
                    // node contains some other TypeScript syntax
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitSourceFile(node) {
            var alwaysStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") &&
                !(ts.isExternalModule(node) && moduleKind >= ts.ModuleKind.ES2015) &&
                !ts.isJsonSourceFile(node);
            return ts.updateSourceFileNode(node, ts.visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict));
        }
        /**
         * Tests whether we should emit a __decorate call for a class declaration.
         */
        function shouldEmitDecorateCallForClass(node) {
            if (node.decorators && node.decorators.length > 0) {
                return true;
            }
            var constructor = ts.getFirstConstructorWithBody(node);
            if (constructor) {
                return ts.forEach(constructor.parameters, shouldEmitDecorateCallForParameter);
            }
            return false;
        }
        /**
         * Tests whether we should emit a __decorate call for a parameter declaration.
         */
        function shouldEmitDecorateCallForParameter(parameter) {
            return parameter.decorators !== undefined && parameter.decorators.length > 0;
        }
        function getClassFacts(node, staticProperties) {
            var facts = 0 /* None */;
            if (ts.some(staticProperties))
                facts |= 1 /* HasStaticInitializedProperties */;
            var extendsClauseElement = ts.getEffectiveBaseTypeNode(node);
            if (extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 100 /* NullKeyword */)
                facts |= 64 /* IsDerivedClass */;
            if (shouldEmitDecorateCallForClass(node))
                facts |= 2 /* HasConstructorDecorators */;
            if (ts.childIsDecorated(node))
                facts |= 4 /* HasMemberDecorators */;
            if (isExportOfNamespace(node))
                facts |= 8 /* IsExportOfNamespace */;
            else if (isDefaultExternalModuleExport(node))
                facts |= 32 /* IsDefaultExternalExport */;
            else if (isNamedExternalModuleExport(node))
                facts |= 16 /* IsNamedExternalExport */;
            if (languageVersion <= 1 /* ES5 */ && (facts & 7 /* MayNeedImmediatelyInvokedFunctionExpression */))
                facts |= 128 /* UseImmediatelyInvokedFunctionExpression */;
            return facts;
        }
        function hasTypeScriptClassSyntax(node) {
            return !!(node.transformFlags & 2048 /* ContainsTypeScriptClassSyntax */);
        }
        function isClassLikeDeclarationWithTypeScriptSyntax(node) {
            return ts.some(node.decorators)
                || ts.some(node.typeParameters)
                || ts.some(node.heritageClauses, hasTypeScriptClassSyntax)
                || ts.some(node.members, hasTypeScriptClassSyntax);
        }
        function visitClassDeclaration(node) {
            if (!isClassLikeDeclarationWithTypeScriptSyntax(node) && !(currentNamespace && ts.hasModifier(node, 1 /* Export */))) {
                return ts.visitEachChild(node, visitor, context);
            }
            var staticProperties = ts.getProperties(node, /*requireInitializer*/ true, /*isStatic*/ true);
            var facts = getClassFacts(node, staticProperties);
            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
                context.startLexicalEnvironment();
            }
            var name = node.name || (facts & 5 /* NeedsName */ ? ts.getGeneratedNameForNode(node) : undefined);
            var classStatement = facts & 2 /* HasConstructorDecorators */
                ? createClassDeclarationHeadWithDecorators(node, name)
                : createClassDeclarationHeadWithoutDecorators(node, name, facts);
            var statements = [classStatement];
            // Write any decorators of the node.
            addClassElementDecorationStatements(statements, node, /*isStatic*/ false);
            addClassElementDecorationStatements(statements, node, /*isStatic*/ true);
            addConstructorDecorationStatement(statements, node);
            if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) {
                // When we emit a TypeScript class down to ES5, we must wrap it in an IIFE so that the
                // 'es2015' transformer can properly nest static initializers and decorators. The result
                // looks something like:
                //
                //  var C = function () {
                //      class C {
                //      }
                //      C.static_prop = 1;
                //      return C;
                //  }();
                //
                var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentSourceFile.text, node.members.end), 19 /* CloseBraceToken */);
                var localName = ts.getInternalName(node);
                // The following partially-emitted expression exists purely to align our sourcemap
                // emit with the original emitter.
                var outer = ts.createPartiallyEmittedExpression(localName);
                outer.end = closingBraceLocation.end;
                ts.setEmitFlags(outer, 1536 /* NoComments */);
                var statement = ts.createReturn(outer);
                statement.pos = closingBraceLocation.pos;
                ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
                statements.push(statement);
                ts.insertStatementsAfterStandardPrologue(statements, context.endLexicalEnvironment());
                var iife = ts.createImmediatelyInvokedArrowFunction(statements);
                ts.setEmitFlags(iife, 33554432 /* TypeScriptClassWrapper */);
                var varStatement = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), 
                    /*type*/ undefined, iife)
                ]));
                ts.setOriginalNode(varStatement, node);
                ts.setCommentRange(varStatement, node);
                ts.setSourceMapRange(varStatement, ts.moveRangePastDecorators(node));
                ts.startOnNewLine(varStatement);
                statements = [varStatement];
            }
            // If the class is exported as part of a TypeScript namespace, emit the namespace export.
            // Otherwise, if the class was exported at the top level and was decorated, emit an export
            // declaration or export default for the class.
            if (facts & 8 /* IsExportOfNamespace */) {
                addExportMemberAssignment(statements, node);
            }
            else if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */ || facts & 2 /* HasConstructorDecorators */) {
                if (facts & 32 /* IsDefaultExternalExport */) {
                    statements.push(ts.createExportDefault(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
                }
                else if (facts & 16 /* IsNamedExternalExport */) {
                    statements.push(ts.createExternalModuleExport(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)));
                }
            }
            if (statements.length > 1) {
                // Add a DeclarationMarker as a marker for the end of the declaration
                statements.push(ts.createEndOfDeclarationMarker(node));
                ts.setEmitFlags(classStatement, ts.getEmitFlags(classStatement) | 4194304 /* HasEndOfDeclarationMarker */);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Transforms a non-decorated class declaration and appends the resulting statements.
         *
         * @param node A ClassDeclaration node.
         * @param name The name of the class.
         * @param facts Precomputed facts about the class.
         */
        function createClassDeclarationHeadWithoutDecorators(node, name, facts) {
            //  ${modifiers} class ${name} ${heritageClauses} {
            //      ${members}
            //  }
            // we do not emit modifiers on the declaration if we are emitting an IIFE
            var modifiers = !(facts & 128 /* UseImmediatelyInvokedFunctionExpression */)
                ? ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier)
                : undefined;
            var classDeclaration = ts.createClassDeclaration(
            /*decorators*/ undefined, modifiers, name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node));
            // To better align with the old emitter, we should not emit a trailing source map
            // entry if the class has static properties.
            var emitFlags = ts.getEmitFlags(node);
            if (facts & 1 /* HasStaticInitializedProperties */) {
                emitFlags |= 32 /* NoTrailingSourceMap */;
            }
            ts.aggregateTransformFlags(classDeclaration);
            ts.setTextRange(classDeclaration, node);
            ts.setOriginalNode(classDeclaration, node);
            ts.setEmitFlags(classDeclaration, emitFlags);
            return classDeclaration;
        }
        /**
         * Transforms a decorated class declaration and appends the resulting statements. If
         * the class requires an alias to avoid issues with double-binding, the alias is returned.
         */
        function createClassDeclarationHeadWithDecorators(node, name) {
            // When we emit an ES6 class that has a class decorator, we must tailor the
            // emit to certain specific cases.
            //
            // In the simplest case, we emit the class declaration as a let declaration, and
            // evaluate decorators after the close of the class body:
            //
            //  [Example 1]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  class C {                       | }
            //  }                               | C = __decorate([dec], C);
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export class C {                | }
            //  }                               | C = __decorate([dec], C);
            //                                  | export { C };
            //  ---------------------------------------------------------------------
            //
            // If a class declaration contains a reference to itself *inside* of the class body,
            // this introduces two bindings to the class: One outside of the class body, and one
            // inside of the class body. If we apply decorators as in [Example 1] above, there
            // is the possibility that the decorator `dec` will return a new value for the
            // constructor, which would result in the binding inside of the class no longer
            // pointing to the same reference as the binding outside of the class.
            //
            // As a result, we must instead rewrite all references to the class *inside* of the
            // class body to instead point to a local temporary alias for the class:
            //
            //  [Example 2]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = C_1 = class C {
            //  class C {                       |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export class C {                |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | export { C };
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //
            // If a class declaration is the default export of a module, we instead emit
            // the export after the decorated declaration:
            //
            //  [Example 3]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let default_1 = class {
            //  export default class {          | }
            //  }                               | default_1 = __decorate([dec], default_1);
            //                                  | export default default_1;
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export default class C {        | }
            //  }                               | C = __decorate([dec], C);
            //                                  | export default C;
            //  ---------------------------------------------------------------------
            //
            // If the class declaration is the default export and a reference to itself
            // inside of the class body, we must emit both an alias for the class *and*
            // move the export after the declaration:
            //
            //  [Example 4]
            //  ---------------------------------------------------------------------
            //  TypeScript                      | Javascript
            //  ---------------------------------------------------------------------
            //  @dec                            | let C = class C {
            //  export default class C {        |   static x() { return C_1.y; }
            //    static x() { return C.y; }    | }
            //    static y = 1;                 | C.y = 1;
            //  }                               | C = C_1 = __decorate([dec], C);
            //                                  | export default C;
            //                                  | var C_1;
            //  ---------------------------------------------------------------------
            //
            var location = ts.moveRangePastDecorators(node);
            var classAlias = getClassAliasIfNeeded(node);
            var declName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  ... = class ${name} ${heritageClauses} {
            //      ${members}
            //  }
            var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause);
            var members = transformClassMembers(node);
            var classExpression = ts.createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members);
            ts.aggregateTransformFlags(classExpression);
            ts.setOriginalNode(classExpression, node);
            ts.setTextRange(classExpression, location);
            //  let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
            //                                         or decoratedClassAlias if the class contain self-reference.
            var statement = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(declName, 
                /*type*/ undefined, classAlias ? ts.createAssignment(classAlias, classExpression) : classExpression)
            ], 1 /* Let */));
            ts.setOriginalNode(statement, node);
            ts.setTextRange(statement, location);
            ts.setCommentRange(statement, node);
            return statement;
        }
        function visitClassExpression(node) {
            if (!isClassLikeDeclarationWithTypeScriptSyntax(node)) {
                return ts.visitEachChild(node, visitor, context);
            }
            var classExpression = ts.createClassExpression(
            /*modifiers*/ undefined, node.name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node));
            ts.aggregateTransformFlags(classExpression);
            ts.setOriginalNode(classExpression, node);
            ts.setTextRange(classExpression, node);
            return classExpression;
        }
        /**
         * Transforms the members of a class.
         *
         * @param node The current class.
         */
        function transformClassMembers(node) {
            var members = [];
            var constructor = ts.getFirstConstructorWithBody(node);
            var parametersWithPropertyAssignments = constructor &&
                ts.filter(constructor.parameters, function (p) { return ts.isParameterPropertyDeclaration(p, constructor); });
            if (parametersWithPropertyAssignments) {
                for (var _i = 0, parametersWithPropertyAssignments_1 = parametersWithPropertyAssignments; _i < parametersWithPropertyAssignments_1.length; _i++) {
                    var parameter = parametersWithPropertyAssignments_1[_i];
                    if (ts.isIdentifier(parameter.name)) {
                        members.push(ts.setOriginalNode(ts.aggregateTransformFlags(ts.createProperty(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, parameter.name, 
                        /*questionOrExclamationToken*/ undefined, 
                        /*type*/ undefined, 
                        /*initializer*/ undefined)), parameter));
                    }
                }
            }
            ts.addRange(members, ts.visitNodes(node.members, classElementVisitor, ts.isClassElement));
            return ts.setTextRange(ts.createNodeArray(members), /*location*/ node.members);
        }
        /**
         * Gets either the static or instance members of a class that are decorated, or have
         * parameters that are decorated.
         *
         * @param node The class containing the member.
         * @param isStatic A value indicating whether to retrieve static or instance members of
         *                 the class.
         */
        function getDecoratedClassElements(node, isStatic) {
            return ts.filter(node.members, isStatic ? function (m) { return isStaticDecoratedClassElement(m, node); } : function (m) { return isInstanceDecoratedClassElement(m, node); });
        }
        /**
         * Determines whether a class member is a static member of a class that is decorated, or
         * has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isStaticDecoratedClassElement(member, parent) {
            return isDecoratedClassElement(member, /*isStatic*/ true, parent);
        }
        /**
         * Determines whether a class member is an instance member of a class that is decorated,
         * or has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isInstanceDecoratedClassElement(member, parent) {
            return isDecoratedClassElement(member, /*isStatic*/ false, parent);
        }
        /**
         * Determines whether a class member is either a static or an instance member of a class
         * that is decorated, or has parameters that are decorated.
         *
         * @param member The class member.
         */
        function isDecoratedClassElement(member, isStatic, parent) {
            return ts.nodeOrChildIsDecorated(member, parent)
                && isStatic === ts.hasModifier(member, 32 /* Static */);
        }
        /**
         * Gets an array of arrays of decorators for the parameters of a function-like node.
         * The offset into the result array should correspond to the offset of the parameter.
         *
         * @param node The function-like node.
         */
        function getDecoratorsOfParameters(node) {
            var decorators;
            if (node) {
                var parameters = node.parameters;
                var firstParameterIsThis = parameters.length > 0 && ts.parameterIsThisKeyword(parameters[0]);
                var firstParameterOffset = firstParameterIsThis ? 1 : 0;
                var numParameters = firstParameterIsThis ? parameters.length - 1 : parameters.length;
                for (var i = 0; i < numParameters; i++) {
                    var parameter = parameters[i + firstParameterOffset];
                    if (decorators || parameter.decorators) {
                        if (!decorators) {
                            decorators = new Array(numParameters);
                        }
                        decorators[i] = parameter.decorators;
                    }
                }
            }
            return decorators;
        }
        /**
         * Gets an AllDecorators object containing the decorators for the class and the decorators for the
         * parameters of the constructor of the class.
         *
         * @param node The class node.
         */
        function getAllDecoratorsOfConstructor(node) {
            var decorators = node.decorators;
            var parameters = getDecoratorsOfParameters(ts.getFirstConstructorWithBody(node));
            if (!decorators && !parameters) {
                return undefined;
            }
            return {
                decorators: decorators,
                parameters: parameters
            };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the member and its parameters.
         *
         * @param node The class node that contains the member.
         * @param member The class member.
         */
        function getAllDecoratorsOfClassElement(node, member) {
            switch (member.kind) {
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return getAllDecoratorsOfAccessors(node, member);
                case 161 /* MethodDeclaration */:
                    return getAllDecoratorsOfMethod(member);
                case 159 /* PropertyDeclaration */:
                    return getAllDecoratorsOfProperty(member);
                default:
                    return undefined;
            }
        }
        /**
         * Gets an AllDecorators object containing the decorators for the accessor and its parameters.
         *
         * @param node The class node that contains the accessor.
         * @param accessor The class accessor member.
         */
        function getAllDecoratorsOfAccessors(node, accessor) {
            if (!accessor.body) {
                return undefined;
            }
            var _a = ts.getAllAccessorDeclarations(node.members, accessor), firstAccessor = _a.firstAccessor, secondAccessor = _a.secondAccessor, setAccessor = _a.setAccessor;
            var firstAccessorWithDecorators = firstAccessor.decorators ? firstAccessor : secondAccessor && secondAccessor.decorators ? secondAccessor : undefined;
            if (!firstAccessorWithDecorators || accessor !== firstAccessorWithDecorators) {
                return undefined;
            }
            var decorators = firstAccessorWithDecorators.decorators;
            var parameters = getDecoratorsOfParameters(setAccessor);
            if (!decorators && !parameters) {
                return undefined;
            }
            return { decorators: decorators, parameters: parameters };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the method and its parameters.
         *
         * @param method The class method member.
         */
        function getAllDecoratorsOfMethod(method) {
            if (!method.body) {
                return undefined;
            }
            var decorators = method.decorators;
            var parameters = getDecoratorsOfParameters(method);
            if (!decorators && !parameters) {
                return undefined;
            }
            return { decorators: decorators, parameters: parameters };
        }
        /**
         * Gets an AllDecorators object containing the decorators for the property.
         *
         * @param property The class property member.
         */
        function getAllDecoratorsOfProperty(property) {
            var decorators = property.decorators;
            if (!decorators) {
                return undefined;
            }
            return { decorators: decorators };
        }
        /**
         * Transforms all of the decorators for a declaration into an array of expressions.
         *
         * @param node The declaration node.
         * @param allDecorators An object containing all of the decorators for the declaration.
         */
        function transformAllDecoratorsOfDeclaration(node, container, allDecorators) {
            if (!allDecorators) {
                return undefined;
            }
            var decoratorExpressions = [];
            ts.addRange(decoratorExpressions, ts.map(allDecorators.decorators, transformDecorator));
            ts.addRange(decoratorExpressions, ts.flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
            addTypeMetadata(node, container, decoratorExpressions);
            return decoratorExpressions;
        }
        /**
         * Generates statements used to apply decorators to either the static or instance members
         * of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to generate statements for static or
         *                 instance members.
         */
        function addClassElementDecorationStatements(statements, node, isStatic) {
            ts.addRange(statements, ts.map(generateClassElementDecorationExpressions(node, isStatic), expressionToStatement));
        }
        /**
         * Generates expressions used to apply decorators to either the static or instance members
         * of a class.
         *
         * @param node The class node.
         * @param isStatic A value indicating whether to generate expressions for static or
         *                 instance members.
         */
        function generateClassElementDecorationExpressions(node, isStatic) {
            var members = getDecoratedClassElements(node, isStatic);
            var expressions;
            for (var _i = 0, members_6 = members; _i < members_6.length; _i++) {
                var member = members_6[_i];
                var expression = generateClassElementDecorationExpression(node, member);
                if (expression) {
                    if (!expressions) {
                        expressions = [expression];
                    }
                    else {
                        expressions.push(expression);
                    }
                }
            }
            return expressions;
        }
        /**
         * Generates an expression used to evaluate class element decorators at runtime.
         *
         * @param node The class node that contains the member.
         * @param member The class member.
         */
        function generateClassElementDecorationExpression(node, member) {
            var allDecorators = getAllDecoratorsOfClassElement(node, member);
            var decoratorExpressions = transformAllDecoratorsOfDeclaration(member, node, allDecorators);
            if (!decoratorExpressions) {
                return undefined;
            }
            // Emit the call to __decorate. Given the following:
            //
            //   class C {
            //     @dec method(@dec2 x) {}
            //     @dec get accessor() {}
            //     @dec prop;
            //   }
            //
            // The emit for a method is:
            //
            //   __decorate([
            //       dec,
            //       __param(0, dec2),
            //       __metadata("design:type", Function),
            //       __metadata("design:paramtypes", [Object]),
            //       __metadata("design:returntype", void 0)
            //   ], C.prototype, "method", null);
            //
            // The emit for an accessor is:
            //
            //   __decorate([
            //       dec
            //   ], C.prototype, "accessor", null);
            //
            // The emit for a property is:
            //
            //   __decorate([
            //       dec
            //   ], C.prototype, "prop");
            //
            var prefix = getClassMemberPrefix(node, member);
            var memberName = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ true);
            var descriptor = languageVersion > 0 /* ES3 */
                ? member.kind === 159 /* PropertyDeclaration */
                    // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it
                    // should not invoke `Object.getOwnPropertyDescriptor`.
                    ? ts.createVoidZero()
                    // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly.
                    // We have this extra argument here so that we can inject an explicit property descriptor at a later date.
                    : ts.createNull()
                : undefined;
            var helper = createDecorateHelper(context, decoratorExpressions, prefix, memberName, descriptor, ts.moveRangePastDecorators(member));
            ts.setEmitFlags(helper, 1536 /* NoComments */);
            return helper;
        }
        /**
         * Generates a __decorate helper call for a class constructor.
         *
         * @param node The class node.
         */
        function addConstructorDecorationStatement(statements, node) {
            var expression = generateConstructorDecorationExpression(node);
            if (expression) {
                statements.push(ts.setOriginalNode(ts.createExpressionStatement(expression), node));
            }
        }
        /**
         * Generates a __decorate helper call for a class constructor.
         *
         * @param node The class node.
         */
        function generateConstructorDecorationExpression(node) {
            var allDecorators = getAllDecoratorsOfConstructor(node);
            var decoratorExpressions = transformAllDecoratorsOfDeclaration(node, node, allDecorators);
            if (!decoratorExpressions) {
                return undefined;
            }
            var classAlias = classAliases && classAliases[ts.getOriginalNodeId(node)];
            var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            var decorate = createDecorateHelper(context, decoratorExpressions, localName);
            var expression = ts.createAssignment(localName, classAlias ? ts.createAssignment(classAlias, decorate) : decorate);
            ts.setEmitFlags(expression, 1536 /* NoComments */);
            ts.setSourceMapRange(expression, ts.moveRangePastDecorators(node));
            return expression;
        }
        /**
         * Transforms a decorator into an expression.
         *
         * @param decorator The decorator node.
         */
        function transformDecorator(decorator) {
            return ts.visitNode(decorator.expression, visitor, ts.isExpression);
        }
        /**
         * Transforms the decorators of a parameter.
         *
         * @param decorators The decorators for the parameter at the provided offset.
         * @param parameterOffset The offset of the parameter.
         */
        function transformDecoratorsOfParameter(decorators, parameterOffset) {
            var expressions;
            if (decorators) {
                expressions = [];
                for (var _i = 0, decorators_1 = decorators; _i < decorators_1.length; _i++) {
                    var decorator = decorators_1[_i];
                    var helper = createParamHelper(context, transformDecorator(decorator), parameterOffset, 
                    /*location*/ decorator.expression);
                    ts.setEmitFlags(helper, 1536 /* NoComments */);
                    expressions.push(helper);
                }
            }
            return expressions;
        }
        /**
         * Adds optional type metadata for a declaration.
         *
         * @param node The declaration node.
         * @param decoratorExpressions The destination array to which to add new decorator expressions.
         */
        function addTypeMetadata(node, container, decoratorExpressions) {
            if (USE_NEW_TYPE_METADATA_FORMAT) {
                addNewTypeMetadata(node, container, decoratorExpressions);
            }
            else {
                addOldTypeMetadata(node, container, decoratorExpressions);
            }
        }
        function addOldTypeMetadata(node, container, decoratorExpressions) {
            if (compilerOptions.emitDecoratorMetadata) {
                if (shouldAddTypeMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node)));
                }
                if (shouldAddParamTypesMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node, container)));
                }
                if (shouldAddReturnTypeMetadata(node)) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node)));
                }
            }
        }
        function addNewTypeMetadata(node, container, decoratorExpressions) {
            if (compilerOptions.emitDecoratorMetadata) {
                var properties = void 0;
                if (shouldAddTypeMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("type", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(38 /* EqualsGreaterThanToken */), serializeTypeOfNode(node))));
                }
                if (shouldAddParamTypesMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("paramTypes", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(38 /* EqualsGreaterThanToken */), serializeParameterTypesOfNode(node, container))));
                }
                if (shouldAddReturnTypeMetadata(node)) {
                    (properties || (properties = [])).push(ts.createPropertyAssignment("returnType", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(38 /* EqualsGreaterThanToken */), serializeReturnTypeOfNode(node))));
                }
                if (properties) {
                    decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", ts.createObjectLiteral(properties, /*multiLine*/ true)));
                }
            }
        }
        /**
         * Determines whether to emit the "design:type" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddTypeMetadata(node) {
            var kind = node.kind;
            return kind === 161 /* MethodDeclaration */
                || kind === 163 /* GetAccessor */
                || kind === 164 /* SetAccessor */
                || kind === 159 /* PropertyDeclaration */;
        }
        /**
         * Determines whether to emit the "design:returntype" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddReturnTypeMetadata(node) {
            return node.kind === 161 /* MethodDeclaration */;
        }
        /**
         * Determines whether to emit the "design:paramtypes" metadata based on the node's kind.
         * The caller should have already tested whether the node has decorators and whether the
         * emitDecoratorMetadata compiler option is set.
         *
         * @param node The node to test.
         */
        function shouldAddParamTypesMetadata(node) {
            switch (node.kind) {
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return ts.getFirstConstructorWithBody(node) !== undefined;
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return true;
            }
            return false;
        }
        function getAccessorTypeNode(node) {
            var accessors = resolver.getAllAccessorDeclarations(node);
            return accessors.setAccessor && ts.getSetAccessorTypeAnnotationNode(accessors.setAccessor)
                || accessors.getAccessor && ts.getEffectiveReturnTypeNode(accessors.getAccessor);
        }
        /**
         * Serializes the type of a node for use with decorator type metadata.
         *
         * @param node The node that should have its type serialized.
         */
        function serializeTypeOfNode(node) {
            switch (node.kind) {
                case 159 /* PropertyDeclaration */:
                case 156 /* Parameter */:
                    return serializeTypeNode(node.type);
                case 164 /* SetAccessor */:
                case 163 /* GetAccessor */:
                    return serializeTypeNode(getAccessorTypeNode(node));
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                case 161 /* MethodDeclaration */:
                    return ts.createIdentifier("Function");
                default:
                    return ts.createVoidZero();
            }
        }
        /**
         * Serializes the types of the parameters of a node for use with decorator type metadata.
         *
         * @param node The node that should have its parameter types serialized.
         */
        function serializeParameterTypesOfNode(node, container) {
            var valueDeclaration = ts.isClassLike(node)
                ? ts.getFirstConstructorWithBody(node)
                : ts.isFunctionLike(node) && ts.nodeIsPresent(node.body)
                    ? node
                    : undefined;
            var expressions = [];
            if (valueDeclaration) {
                var parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container);
                var numParameters = parameters.length;
                for (var i = 0; i < numParameters; i++) {
                    var parameter = parameters[i];
                    if (i === 0 && ts.isIdentifier(parameter.name) && parameter.name.escapedText === "this") {
                        continue;
                    }
                    if (parameter.dotDotDotToken) {
                        expressions.push(serializeTypeNode(ts.getRestParameterElementType(parameter.type)));
                    }
                    else {
                        expressions.push(serializeTypeOfNode(parameter));
                    }
                }
            }
            return ts.createArrayLiteral(expressions);
        }
        function getParametersOfDecoratedDeclaration(node, container) {
            if (container && node.kind === 163 /* GetAccessor */) {
                var setAccessor = ts.getAllAccessorDeclarations(container.members, node).setAccessor;
                if (setAccessor) {
                    return setAccessor.parameters;
                }
            }
            return node.parameters;
        }
        /**
         * Serializes the return type of a node for use with decorator type metadata.
         *
         * @param node The node that should have its return type serialized.
         */
        function serializeReturnTypeOfNode(node) {
            if (ts.isFunctionLike(node) && node.type) {
                return serializeTypeNode(node.type);
            }
            else if (ts.isAsyncFunction(node)) {
                return ts.createIdentifier("Promise");
            }
            return ts.createVoidZero();
        }
        /**
         * Serializes a type node for use with decorator type metadata.
         *
         * Types are serialized in the following fashion:
         * - Void types point to "undefined" (e.g. "void 0")
         * - Function and Constructor types point to the global "Function" constructor.
         * - Interface types with a call or construct signature types point to the global
         *   "Function" constructor.
         * - Array and Tuple types point to the global "Array" constructor.
         * - Type predicates and booleans point to the global "Boolean" constructor.
         * - String literal types and strings point to the global "String" constructor.
         * - Enum and number types point to the global "Number" constructor.
         * - Symbol types point to the global "Symbol" constructor.
         * - Type references to classes (or class-like variables) point to the constructor for the class.
         * - Anything else points to the global "Object" constructor.
         *
         * @param node The type node to serialize.
         */
        function serializeTypeNode(node) {
            if (node === undefined) {
                return ts.createIdentifier("Object");
            }
            switch (node.kind) {
                case 110 /* VoidKeyword */:
                case 146 /* UndefinedKeyword */:
                case 100 /* NullKeyword */:
                case 137 /* NeverKeyword */:
                    return ts.createVoidZero();
                case 182 /* ParenthesizedType */:
                    return serializeTypeNode(node.type);
                case 170 /* FunctionType */:
                case 171 /* ConstructorType */:
                    return ts.createIdentifier("Function");
                case 174 /* ArrayType */:
                case 175 /* TupleType */:
                    return ts.createIdentifier("Array");
                case 168 /* TypePredicate */:
                case 128 /* BooleanKeyword */:
                    return ts.createIdentifier("Boolean");
                case 143 /* StringKeyword */:
                    return ts.createIdentifier("String");
                case 141 /* ObjectKeyword */:
                    return ts.createIdentifier("Object");
                case 187 /* LiteralType */:
                    switch (node.literal.kind) {
                        case 10 /* StringLiteral */:
                            return ts.createIdentifier("String");
                        case 207 /* PrefixUnaryExpression */:
                        case 8 /* NumericLiteral */:
                            return ts.createIdentifier("Number");
                        case 9 /* BigIntLiteral */:
                            return getGlobalBigIntNameWithFallback();
                        case 106 /* TrueKeyword */:
                        case 91 /* FalseKeyword */:
                            return ts.createIdentifier("Boolean");
                        default:
                            return ts.Debug.failBadSyntaxKind(node.literal);
                    }
                case 140 /* NumberKeyword */:
                    return ts.createIdentifier("Number");
                case 151 /* BigIntKeyword */:
                    return getGlobalBigIntNameWithFallback();
                case 144 /* SymbolKeyword */:
                    return languageVersion < 2 /* ES2015 */
                        ? getGlobalSymbolNameWithFallback()
                        : ts.createIdentifier("Symbol");
                case 169 /* TypeReference */:
                    return serializeTypeReferenceNode(node);
                case 179 /* IntersectionType */:
                case 178 /* UnionType */:
                    return serializeTypeList(node.types);
                case 180 /* ConditionalType */:
                    return serializeTypeList([node.trueType, node.falseType]);
                case 184 /* TypeOperator */:
                    if (node.operator === 138 /* ReadonlyKeyword */) {
                        return serializeTypeNode(node.type);
                    }
                    break;
                case 172 /* TypeQuery */:
                case 185 /* IndexedAccessType */:
                case 186 /* MappedType */:
                case 173 /* TypeLiteral */:
                case 125 /* AnyKeyword */:
                case 148 /* UnknownKeyword */:
                case 183 /* ThisType */:
                case 188 /* ImportType */:
                    break;
                // handle JSDoc types from an invalid parse
                case 295 /* JSDocAllType */:
                case 296 /* JSDocUnknownType */:
                case 300 /* JSDocFunctionType */:
                case 301 /* JSDocVariadicType */:
                case 302 /* JSDocNamepathType */:
                    break;
                case 297 /* JSDocNullableType */:
                case 298 /* JSDocNonNullableType */:
                case 299 /* JSDocOptionalType */:
                    return serializeTypeNode(node.type);
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
            return ts.createIdentifier("Object");
        }
        function serializeTypeList(types) {
            // Note when updating logic here also update getEntityNameForDecoratorMetadata
            // so that aliases can be marked as referenced
            var serializedUnion;
            for (var _i = 0, types_21 = types; _i < types_21.length; _i++) {
                var typeNode = types_21[_i];
                while (typeNode.kind === 182 /* ParenthesizedType */) {
                    typeNode = typeNode.type; // Skip parens if need be
                }
                if (typeNode.kind === 137 /* NeverKeyword */) {
                    continue; // Always elide `never` from the union/intersection if possible
                }
                if (!strictNullChecks && (typeNode.kind === 100 /* NullKeyword */ || typeNode.kind === 146 /* UndefinedKeyword */)) {
                    continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
                }
                var serializedIndividual = serializeTypeNode(typeNode);
                if (ts.isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") {
                    // One of the individual is global object, return immediately
                    return serializedIndividual;
                }
                // If there exists union that is not void 0 expression, check if the the common type is identifier.
                // anything more complex and we will just default to Object
                else if (serializedUnion) {
                    // Different types
                    if (!ts.isIdentifier(serializedUnion) ||
                        !ts.isIdentifier(serializedIndividual) ||
                        serializedUnion.escapedText !== serializedIndividual.escapedText) {
                        return ts.createIdentifier("Object");
                    }
                }
                else {
                    // Initialize the union type
                    serializedUnion = serializedIndividual;
                }
            }
            // If we were able to find common type, use it
            return serializedUnion || ts.createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never
        }
        /**
         * Serializes a TypeReferenceNode to an appropriate JS constructor value for use with
         * decorator type metadata.
         *
         * @param node The type reference node.
         */
        function serializeTypeReferenceNode(node) {
            var kind = resolver.getTypeReferenceSerializationKind(node.typeName, currentNameScope || currentLexicalScope);
            switch (kind) {
                case ts.TypeReferenceSerializationKind.Unknown:
                    // From conditional type type reference that cannot be resolved is Similar to any or unknown
                    if (ts.findAncestor(node, function (n) { return n.parent && ts.isConditionalTypeNode(n.parent) && (n.parent.trueType === n || n.parent.falseType === n); })) {
                        return ts.createIdentifier("Object");
                    }
                    var serialized = serializeEntityNameAsExpressionFallback(node.typeName);
                    var temp = ts.createTempVariable(hoistVariableDeclaration);
                    return ts.createConditional(ts.createTypeCheck(ts.createAssignment(temp, serialized), "function"), temp, ts.createIdentifier("Object"));
                case ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
                    return serializeEntityNameAsExpression(node.typeName);
                case ts.TypeReferenceSerializationKind.VoidNullableOrNeverType:
                    return ts.createVoidZero();
                case ts.TypeReferenceSerializationKind.BigIntLikeType:
                    return getGlobalBigIntNameWithFallback();
                case ts.TypeReferenceSerializationKind.BooleanType:
                    return ts.createIdentifier("Boolean");
                case ts.TypeReferenceSerializationKind.NumberLikeType:
                    return ts.createIdentifier("Number");
                case ts.TypeReferenceSerializationKind.StringLikeType:
                    return ts.createIdentifier("String");
                case ts.TypeReferenceSerializationKind.ArrayLikeType:
                    return ts.createIdentifier("Array");
                case ts.TypeReferenceSerializationKind.ESSymbolType:
                    return languageVersion < 2 /* ES2015 */
                        ? getGlobalSymbolNameWithFallback()
                        : ts.createIdentifier("Symbol");
                case ts.TypeReferenceSerializationKind.TypeWithCallSignature:
                    return ts.createIdentifier("Function");
                case ts.TypeReferenceSerializationKind.Promise:
                    return ts.createIdentifier("Promise");
                case ts.TypeReferenceSerializationKind.ObjectType:
                    return ts.createIdentifier("Object");
                default:
                    return ts.Debug.assertNever(kind);
            }
        }
        function createCheckedValue(left, right) {
            return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(left), ts.createLiteral("undefined")), right);
        }
        /**
         * Serializes an entity name which may not exist at runtime, but whose access shouldn't throw
         *
         * @param node The entity name to serialize.
         */
        function serializeEntityNameAsExpressionFallback(node) {
            if (node.kind === 75 /* Identifier */) {
                // A -> typeof A !== undefined && A
                var copied = serializeEntityNameAsExpression(node);
                return createCheckedValue(copied, copied);
            }
            if (node.left.kind === 75 /* Identifier */) {
                // A.B -> typeof A !== undefined && A.B
                return createCheckedValue(serializeEntityNameAsExpression(node.left), serializeEntityNameAsExpression(node));
            }
            // A.B.C -> typeof A !== undefined && (_a = A.B) !== void 0 && _a.C
            var left = serializeEntityNameAsExpressionFallback(node.left);
            var temp = ts.createTempVariable(hoistVariableDeclaration);
            return ts.createLogicalAnd(ts.createLogicalAnd(left.left, ts.createStrictInequality(ts.createAssignment(temp, left.right), ts.createVoidZero())), ts.createPropertyAccess(temp, node.right));
        }
        /**
         * Serializes an entity name as an expression for decorator type metadata.
         *
         * @param node The entity name to serialize.
         */
        function serializeEntityNameAsExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    // Create a clone of the name with a new parent, and treat it as if it were
                    // a source tree node for the purposes of the checker.
                    var name = ts.getMutableClone(node);
                    name.flags &= ~8 /* Synthesized */;
                    name.original = undefined;
                    name.parent = ts.getParseTreeNode(currentLexicalScope); // ensure the parent is set to a parse tree node.
                    return name;
                case 153 /* QualifiedName */:
                    return serializeQualifiedNameAsExpression(node);
            }
        }
        /**
         * Serializes an qualified name as an expression for decorator type metadata.
         *
         * @param node The qualified name to serialize.
         * @param useFallback A value indicating whether to use logical operators to test for the
         *                    qualified name at runtime.
         */
        function serializeQualifiedNameAsExpression(node) {
            return ts.createPropertyAccess(serializeEntityNameAsExpression(node.left), node.right);
        }
        /**
         * Gets an expression that points to the global "Symbol" constructor at runtime if it is
         * available.
         */
        function getGlobalSymbolNameWithFallback() {
            return ts.createConditional(ts.createTypeCheck(ts.createIdentifier("Symbol"), "function"), ts.createIdentifier("Symbol"), ts.createIdentifier("Object"));
        }
        /**
         * Gets an expression that points to the global "BigInt" constructor at runtime if it is
         * available.
         */
        function getGlobalBigIntNameWithFallback() {
            return languageVersion < 99 /* ESNext */
                ? ts.createConditional(ts.createTypeCheck(ts.createIdentifier("BigInt"), "function"), ts.createIdentifier("BigInt"), ts.createIdentifier("Object"))
                : ts.createIdentifier("BigInt");
        }
        /**
         * Gets an expression that represents a property name (for decorated properties or enums).
         * For a computed property, a name is generated for the node.
         *
         * @param member The member whose name should be converted into an expression.
         */
        function getExpressionForPropertyName(member, generateNameForComputedPropertyName) {
            var name = member.name;
            if (ts.isPrivateIdentifier(name)) {
                return ts.createIdentifier("");
            }
            else if (ts.isComputedPropertyName(name)) {
                return generateNameForComputedPropertyName && !ts.isSimpleInlineableExpression(name.expression)
                    ? ts.getGeneratedNameForNode(name)
                    : name.expression;
            }
            else if (ts.isIdentifier(name)) {
                return ts.createLiteral(ts.idText(name));
            }
            else {
                return ts.getSynthesizedClone(name);
            }
        }
        /**
         * Visits the property name of a class element, for use when emitting property
         * initializers. For a computed property on a node with decorators, a temporary
         * value is stored for later use.
         *
         * @param member The member whose name should be visited.
         */
        function visitPropertyNameOfClassElement(member) {
            var name = member.name;
            // Computed property names need to be transformed into a hoisted variable when they are used more than once.
            // The names are used more than once when:
            //   - the property is non-static and its initializer is moved to the constructor (when there are parameter property assignments).
            //   - the property has a decorator.
            if (ts.isComputedPropertyName(name) && ((!ts.hasStaticModifier(member) && currentClassHasParameterProperties) || ts.some(member.decorators))) {
                var expression = ts.visitNode(name.expression, visitor, ts.isExpression);
                var innerExpression = ts.skipPartiallyEmittedExpressions(expression);
                if (!ts.isSimpleInlineableExpression(innerExpression)) {
                    var generatedName = ts.getGeneratedNameForNode(name);
                    hoistVariableDeclaration(generatedName);
                    return ts.updateComputedPropertyName(name, ts.createAssignment(generatedName, expression));
                }
            }
            return ts.visitNode(name, visitor, ts.isPropertyName);
        }
        /**
         * Transforms a HeritageClause with TypeScript syntax.
         *
         * This function will only be called when one of the following conditions are met:
         * - The node is a non-`extends` heritage clause that should be elided.
         * - The node is an `extends` heritage clause that should be visited, but only allow a single type.
         *
         * @param node The HeritageClause to transform.
         */
        function visitHeritageClause(node) {
            if (node.token === 113 /* ImplementsKeyword */) {
                // implements clauses are elided
                return undefined;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Transforms an ExpressionWithTypeArguments with TypeScript syntax.
         *
         * This function will only be called when one of the following conditions are met:
         * - The node contains type arguments that should be elided.
         *
         * @param node The ExpressionWithTypeArguments to transform.
         */
        function visitExpressionWithTypeArguments(node) {
            return ts.updateExpressionWithTypeArguments(node, 
            /*typeArguments*/ undefined, ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
        }
        /**
         * Determines whether to emit a function-like declaration. We should not emit the
         * declaration if it does not have a body.
         *
         * @param node The declaration node.
         */
        function shouldEmitFunctionLikeDeclaration(node) {
            return !ts.nodeIsMissing(node.body);
        }
        function visitPropertyDeclaration(node) {
            if (node.flags & 8388608 /* Ambient */) {
                return undefined;
            }
            var updated = ts.updateProperty(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), visitPropertyNameOfClassElement(node), 
            /*questionOrExclamationToken*/ undefined, 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        function visitConstructor(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return undefined;
            }
            return ts.updateConstructor(node, 
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, ts.visitParameterList(node.parameters, visitor, context), transformConstructorBody(node.body, node));
        }
        function transformConstructorBody(body, constructor) {
            var parametersWithPropertyAssignments = constructor &&
                ts.filter(constructor.parameters, function (p) { return ts.isParameterPropertyDeclaration(p, constructor); });
            if (!ts.some(parametersWithPropertyAssignments)) {
                return ts.visitFunctionBody(body, visitor, context);
            }
            var statements = [];
            var indexOfFirstStatement = 0;
            resumeLexicalEnvironment();
            indexOfFirstStatement = ts.addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor);
            // Add parameters with property assignments. Transforms this:
            //
            //  constructor (public x, public y) {
            //  }
            //
            // Into this:
            //
            //  constructor (x, y) {
            //      this.x = x;
            //      this.y = y;
            //  }
            //
            ts.addRange(statements, ts.map(parametersWithPropertyAssignments, transformParameterWithPropertyAssignment));
            // Add the existing statements, skipping the initial super call.
            ts.addRange(statements, ts.visitNodes(body.statements, visitor, ts.isStatement, indexOfFirstStatement));
            // End the lexical environment.
            statements = ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), body.statements), /*multiLine*/ true);
            ts.setTextRange(block, /*location*/ body);
            ts.setOriginalNode(block, body);
            return block;
        }
        /**
         * Transforms a parameter into a property assignment statement.
         *
         * @param node The parameter declaration.
         */
        function transformParameterWithPropertyAssignment(node) {
            var name = node.name;
            if (!ts.isIdentifier(name)) {
                return undefined;
            }
            var propertyName = ts.getMutableClone(name);
            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 48 /* NoSourceMap */);
            var localName = ts.getMutableClone(name);
            ts.setEmitFlags(localName, 1536 /* NoComments */);
            return ts.startOnNewLine(ts.removeAllComments(ts.setTextRange(ts.setOriginalNode(ts.createExpressionStatement(ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createThis(), propertyName), node.name), localName)), node), ts.moveRangePos(node, -1))));
        }
        function visitMethodDeclaration(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateMethod(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, visitPropertyNameOfClassElement(node), 
            /*questionToken*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        /**
         * Determines whether to emit an accessor declaration. We should not emit the
         * declaration if it does not have a body and is abstract.
         *
         * @param node The declaration node.
         */
        function shouldEmitAccessorDeclaration(node) {
            return !(ts.nodeIsMissing(node.body) && ts.hasModifier(node, 128 /* Abstract */));
        }
        function visitGetAccessor(node) {
            if (!shouldEmitAccessorDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateGetAccessor(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        function visitSetAccessor(node) {
            if (!shouldEmitAccessorDeclaration(node)) {
                return undefined;
            }
            var updated = ts.updateSetAccessor(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node));
            }
            return updated;
        }
        function visitFunctionDeclaration(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            var updated = ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            if (isExportOfNamespace(node)) {
                var statements = [updated];
                addExportMemberAssignment(statements, node);
                return statements;
            }
            return updated;
        }
        function visitFunctionExpression(node) {
            if (!shouldEmitFunctionLikeDeclaration(node)) {
                return ts.createOmittedExpression();
            }
            var updated = ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([]));
            return updated;
        }
        function visitArrowFunction(node) {
            var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context));
            return updated;
        }
        function visitParameter(node) {
            if (ts.parameterIsThisKeyword(node)) {
                return undefined;
            }
            var updated = ts.updateParameter(node, 
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, node.dotDotDotToken, ts.visitNode(node.name, visitor, ts.isBindingName), 
            /*questionToken*/ undefined, 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
            if (updated !== node) {
                // While we emit the source map for the node after skipping decorators and modifiers,
                // we need to emit the comments for the original range.
                ts.setCommentRange(updated, node);
                ts.setTextRange(updated, ts.moveRangePastModifiers(node));
                ts.setSourceMapRange(updated, ts.moveRangePastModifiers(node));
                ts.setEmitFlags(updated.name, 32 /* NoTrailingSourceMap */);
            }
            return updated;
        }
        function visitVariableStatement(node) {
            if (isExportOfNamespace(node)) {
                var variables = ts.getInitializedVariables(node.declarationList);
                if (variables.length === 0) {
                    // elide statement if there are no initialized variables.
                    return undefined;
                }
                return ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformInitializedVariable(node) {
            var name = node.name;
            if (ts.isBindingPattern(name)) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, 
                /*needsValue*/ false, createNamespaceExportExpression);
            }
            else {
                return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), ts.visitNode(node.initializer, visitor, ts.isExpression)), 
                /*location*/ node);
            }
        }
        function visitVariableDeclaration(node) {
            return ts.updateTypeScriptVariableDeclaration(node, ts.visitNode(node.name, visitor, ts.isBindingName), 
            /*exclaimationToken*/ undefined, 
            /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
        }
        function visitParenthesizedExpression(node) {
            var innerExpression = ts.skipOuterExpressions(node.expression, ~6 /* Assertions */);
            if (ts.isAssertionExpression(innerExpression)) {
                // Make sure we consider all nested cast expressions, e.g.:
                // (<any><number><any>-A).x;
                var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
                // We have an expression of the form: (<Type>SubExpr). Emitting this as (SubExpr)
                // is really not desirable. We would like to emit the subexpression as-is. Omitting
                // the parentheses, however, could cause change in the semantics of the generated
                // code if the casted expression has a lower precedence than the rest of the
                // expression.
                //
                // To preserve comments, we return a "PartiallyEmittedExpression" here which will
                // preserve the position information of the original expression.
                //
                // Due to the auto-parenthesization rules used by the visitor and factory functions
                // we can safely elide the parentheses here, as a new synthetic
                // ParenthesizedExpression will be inserted if we remove parentheses too
                // aggressively.
                // HOWEVER - if there are leading comments on the expression itself, to handle ASI
                // correctly for return and throw, we must keep the parenthesis
                if (ts.length(ts.getLeadingCommentRangesOfNode(expression, currentSourceFile))) {
                    return ts.updateParen(node, expression);
                }
                return ts.createPartiallyEmittedExpression(expression, node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitAssertionExpression(node) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            return ts.createPartiallyEmittedExpression(expression, node);
        }
        function visitNonNullExpression(node) {
            var expression = ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression);
            return ts.createPartiallyEmittedExpression(expression, node);
        }
        function visitCallExpression(node) {
            return ts.updateCall(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitNewExpression(node) {
            return ts.updateNew(node, ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitTaggedTemplateExpression(node) {
            return ts.updateTaggedTemplate(node, ts.visitNode(node.tag, visitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNode(node.template, visitor, ts.isExpression));
        }
        function visitJsxSelfClosingElement(node) {
            return ts.updateJsxSelfClosingElement(node, ts.visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), 
            /*typeArguments*/ undefined, ts.visitNode(node.attributes, visitor, ts.isJsxAttributes));
        }
        function visitJsxJsxOpeningElement(node) {
            return ts.updateJsxOpeningElement(node, ts.visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), 
            /*typeArguments*/ undefined, ts.visitNode(node.attributes, visitor, ts.isJsxAttributes));
        }
        /**
         * Determines whether to emit an enum declaration.
         *
         * @param node The enum declaration node.
         */
        function shouldEmitEnumDeclaration(node) {
            return !ts.isEnumConst(node)
                || compilerOptions.preserveConstEnums
                || compilerOptions.isolatedModules;
        }
        /**
         * Visits an enum declaration.
         *
         * This function will be called any time a TypeScript enum is encountered.
         *
         * @param node The enum declaration node.
         */
        function visitEnumDeclaration(node) {
            if (!shouldEmitEnumDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            var statements = [];
            // We request to be advised when the printer is about to print this node. This allows
            // us to set up the correct state for later substitutions.
            var emitFlags = 2 /* AdviseOnEmitNode */;
            // If needed, we should emit a variable declaration for the enum. If we emit
            // a leading variable declaration, we should not emit leading comments for the
            // enum body.
            var varAdded = addVarForEnumOrModuleDeclaration(statements, node);
            if (varAdded) {
                // We should still emit the comments if we are emitting a system module.
                if (moduleKind !== ts.ModuleKind.System || currentLexicalScope !== currentSourceFile) {
                    emitFlags |= 512 /* NoLeadingComments */;
                }
            }
            // `parameterName` is the declaration name used inside of the enum.
            var parameterName = getNamespaceParameterName(node);
            // `containerName` is the expression used inside of the enum for assignments.
            var containerName = getNamespaceContainerName(node);
            // `exportName` is the expression used within this node's container for any exported references.
            var exportName = ts.hasModifier(node, 1 /* Export */)
                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  x || (x = {})
            //  exports.x || (exports.x = {})
            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
            if (hasNamespaceQualifiedExportName(node)) {
                // `localName` is the expression used within this node's containing scope for any local references.
                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
                //  x = (exports.x || (exports.x = {}))
                moduleArg = ts.createAssignment(localName, moduleArg);
            }
            //  (function (x) {
            //      x[x["y"] = 0] = "y";
            //      ...
            //  })(x || (x = {}));
            var enumStatement = ts.createExpressionStatement(ts.createCall(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
            /*type*/ undefined, transformEnumBody(node, containerName)), 
            /*typeArguments*/ undefined, [moduleArg]));
            ts.setOriginalNode(enumStatement, node);
            if (varAdded) {
                // If a variable was added, synthetic comments are emitted on it, not on the moduleStatement.
                ts.setSyntheticLeadingComments(enumStatement, undefined);
                ts.setSyntheticTrailingComments(enumStatement, undefined);
            }
            ts.setTextRange(enumStatement, node);
            ts.addEmitFlags(enumStatement, emitFlags);
            statements.push(enumStatement);
            // Add a DeclarationMarker for the enum to preserve trailing comments and mark
            // the end of the declaration.
            statements.push(ts.createEndOfDeclarationMarker(node));
            return statements;
        }
        /**
         * Transforms the body of an enum declaration.
         *
         * @param node The enum declaration node.
         */
        function transformEnumBody(node, localName) {
            var savedCurrentNamespaceLocalName = currentNamespaceContainerName;
            currentNamespaceContainerName = localName;
            var statements = [];
            startLexicalEnvironment();
            var members = ts.map(node.members, transformEnumMember);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            ts.addRange(statements, members);
            currentNamespaceContainerName = savedCurrentNamespaceLocalName;
            return ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), 
            /*multiLine*/ true);
        }
        /**
         * Transforms an enum member into a statement.
         *
         * @param member The enum member node.
         */
        function transformEnumMember(member) {
            // enums don't support computed properties
            // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes
            // old emitter always generate 'expression' part of the name as-is.
            var name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false);
            var valueExpression = transformEnumMemberDeclarationValue(member);
            var innerAssignment = ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, name), valueExpression);
            var outerAssignment = valueExpression.kind === 10 /* StringLiteral */ ?
                innerAssignment :
                ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, innerAssignment), name);
            return ts.setTextRange(ts.createExpressionStatement(ts.setTextRange(outerAssignment, member)), member);
        }
        /**
         * Transforms the value of an enum member.
         *
         * @param member The enum member node.
         */
        function transformEnumMemberDeclarationValue(member) {
            var value = resolver.getConstantValue(member);
            if (value !== undefined) {
                return ts.createLiteral(value);
            }
            else {
                enableSubstitutionForNonQualifiedEnumMembers();
                if (member.initializer) {
                    return ts.visitNode(member.initializer, visitor, ts.isExpression);
                }
                else {
                    return ts.createVoidZero();
                }
            }
        }
        /**
         * Determines whether to elide a module declaration.
         *
         * @param node The module declaration node.
         */
        function shouldEmitModuleDeclaration(nodeIn) {
            var node = ts.getParseTreeNode(nodeIn, ts.isModuleDeclaration);
            if (!node) {
                // If we can't find a parse tree node, assume the node is instantiated.
                return true;
            }
            return ts.isInstantiatedModule(node, !!compilerOptions.preserveConstEnums || !!compilerOptions.isolatedModules);
        }
        /**
         * Determines whether an exported declaration will have a qualified export name (e.g. `f.x`
         * or `exports.x`).
         */
        function hasNamespaceQualifiedExportName(node) {
            return isExportOfNamespace(node)
                || (isExternalModuleExport(node)
                    && moduleKind !== ts.ModuleKind.ES2015
                    && moduleKind !== ts.ModuleKind.ES2020
                    && moduleKind !== ts.ModuleKind.ESNext
                    && moduleKind !== ts.ModuleKind.System);
        }
        /**
         * Records that a declaration was emitted in the current scope, if it was the first
         * declaration for the provided symbol.
         */
        function recordEmittedDeclarationInScope(node) {
            if (!currentScopeFirstDeclarationsOfName) {
                currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap();
            }
            var name = declaredNameInScope(node);
            if (!currentScopeFirstDeclarationsOfName.has(name)) {
                currentScopeFirstDeclarationsOfName.set(name, node);
            }
        }
        /**
         * Determines whether a declaration is the first declaration with
         * the same name emitted in the current scope.
         */
        function isFirstEmittedDeclarationInScope(node) {
            if (currentScopeFirstDeclarationsOfName) {
                var name = declaredNameInScope(node);
                return currentScopeFirstDeclarationsOfName.get(name) === node;
            }
            return true;
        }
        function declaredNameInScope(node) {
            ts.Debug.assertNode(node.name, ts.isIdentifier);
            return node.name.escapedText;
        }
        /**
         * Adds a leading VariableStatement for a enum or module declaration.
         */
        function addVarForEnumOrModuleDeclaration(statements, node) {
            // Emit a variable statement for the module. We emit top-level enums as a `var`
            // declaration to avoid static errors in global scripts scripts due to redeclaration.
            // enums in any other scope are emitted as a `let` declaration.
            var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
                ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))
            ], currentLexicalScope.kind === 290 /* SourceFile */ ? 0 /* None */ : 1 /* Let */));
            ts.setOriginalNode(statement, node);
            recordEmittedDeclarationInScope(node);
            if (isFirstEmittedDeclarationInScope(node)) {
                // Adjust the source map emit to match the old emitter.
                if (node.kind === 248 /* EnumDeclaration */) {
                    ts.setSourceMapRange(statement.declarationList, node);
                }
                else {
                    ts.setSourceMapRange(statement, node);
                }
                // Trailing comments for module declaration should be emitted after the function closure
                // instead of the variable statement:
                //
                //     /** Module comment*/
                //     module m1 {
                //         function foo4Export() {
                //         }
                //     } // trailing comment module
                //
                // Should emit:
                //
                //     /** Module comment*/
                //     var m1;
                //     (function (m1) {
                //         function foo4Export() {
                //         }
                //     })(m1 || (m1 = {})); // trailing comment module
                //
                ts.setCommentRange(statement, node);
                ts.addEmitFlags(statement, 1024 /* NoTrailingComments */ | 4194304 /* HasEndOfDeclarationMarker */);
                statements.push(statement);
                return true;
            }
            else {
                // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
                // declaration we do not emit a leading variable declaration. To preserve the
                // begin/end semantics of the declararation and to properly handle exports
                // we wrap the leading variable declaration in a `MergeDeclarationMarker`.
                var mergeMarker = ts.createMergeDeclarationMarker(statement);
                ts.setEmitFlags(mergeMarker, 1536 /* NoComments */ | 4194304 /* HasEndOfDeclarationMarker */);
                statements.push(mergeMarker);
                return false;
            }
        }
        /**
         * Visits a module declaration node.
         *
         * This function will be called any time a TypeScript namespace (ModuleDeclaration) is encountered.
         *
         * @param node The module declaration node.
         */
        function visitModuleDeclaration(node) {
            if (!shouldEmitModuleDeclaration(node)) {
                return ts.createNotEmittedStatement(node);
            }
            ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name.");
            enableSubstitutionForNamespaceExports();
            var statements = [];
            // We request to be advised when the printer is about to print this node. This allows
            // us to set up the correct state for later substitutions.
            var emitFlags = 2 /* AdviseOnEmitNode */;
            // If needed, we should emit a variable declaration for the module. If we emit
            // a leading variable declaration, we should not emit leading comments for the
            // module body.
            var varAdded = addVarForEnumOrModuleDeclaration(statements, node);
            if (varAdded) {
                // We should still emit the comments if we are emitting a system module.
                if (moduleKind !== ts.ModuleKind.System || currentLexicalScope !== currentSourceFile) {
                    emitFlags |= 512 /* NoLeadingComments */;
                }
            }
            // `parameterName` is the declaration name used inside of the namespace.
            var parameterName = getNamespaceParameterName(node);
            // `containerName` is the expression used inside of the namespace for exports.
            var containerName = getNamespaceContainerName(node);
            // `exportName` is the expression used within this node's container for any exported references.
            var exportName = ts.hasModifier(node, 1 /* Export */)
                ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true)
                : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
            //  x || (x = {})
            //  exports.x || (exports.x = {})
            var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral()));
            if (hasNamespaceQualifiedExportName(node)) {
                // `localName` is the expression used within this node's containing scope for any local references.
                var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true);
                //  x = (exports.x || (exports.x = {}))
                moduleArg = ts.createAssignment(localName, moduleArg);
            }
            //  (function (x_1) {
            //      x_1.y = ...;
            //  })(x || (x = {}));
            var moduleStatement = ts.createExpressionStatement(ts.createCall(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
            /*type*/ undefined, transformModuleBody(node, containerName)), 
            /*typeArguments*/ undefined, [moduleArg]));
            ts.setOriginalNode(moduleStatement, node);
            if (varAdded) {
                // If a variable was added, synthetic comments are emitted on it, not on the moduleStatement.
                ts.setSyntheticLeadingComments(moduleStatement, undefined);
                ts.setSyntheticTrailingComments(moduleStatement, undefined);
            }
            ts.setTextRange(moduleStatement, node);
            ts.addEmitFlags(moduleStatement, emitFlags);
            statements.push(moduleStatement);
            // Add a DeclarationMarker for the namespace to preserve trailing comments and mark
            // the end of the declaration.
            statements.push(ts.createEndOfDeclarationMarker(node));
            return statements;
        }
        /**
         * Transforms the body of a module declaration.
         *
         * @param node The module declaration node.
         */
        function transformModuleBody(node, namespaceLocalName) {
            var savedCurrentNamespaceContainerName = currentNamespaceContainerName;
            var savedCurrentNamespace = currentNamespace;
            var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName;
            currentNamespaceContainerName = namespaceLocalName;
            currentNamespace = node;
            currentScopeFirstDeclarationsOfName = undefined;
            var statements = [];
            startLexicalEnvironment();
            var statementsLocation;
            var blockLocation;
            if (node.body) {
                if (node.body.kind === 250 /* ModuleBlock */) {
                    saveStateAndInvoke(node.body, function (body) { return ts.addRange(statements, ts.visitNodes(body.statements, namespaceElementVisitor, ts.isStatement)); });
                    statementsLocation = node.body.statements;
                    blockLocation = node.body;
                }
                else {
                    var result = visitModuleDeclaration(node.body);
                    if (result) {
                        if (ts.isArray(result)) {
                            ts.addRange(statements, result);
                        }
                        else {
                            statements.push(result);
                        }
                    }
                    var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
                    statementsLocation = ts.moveRangePos(moduleBlock.statements, -1);
                }
            }
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            currentNamespaceContainerName = savedCurrentNamespaceContainerName;
            currentNamespace = savedCurrentNamespace;
            currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName;
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ statementsLocation), 
            /*multiLine*/ true);
            ts.setTextRange(block, blockLocation);
            // namespace hello.hi.world {
            //      function foo() {}
            //
            //      // TODO, blah
            // }
            //
            // should be emitted as
            //
            // var hello;
            // (function (hello) {
            //     var hi;
            //     (function (hi) {
            //         var world;
            //         (function (world) {
            //             function foo() { }
            //             // TODO, blah
            //         })(world = hi.world || (hi.world = {}));
            //     })(hi = hello.hi || (hello.hi = {}));
            // })(hello || (hello = {}));
            // We only want to emit comment on the namespace which contains block body itself, not the containing namespaces.
            if (!node.body || node.body.kind !== 250 /* ModuleBlock */) {
                ts.setEmitFlags(block, ts.getEmitFlags(block) | 1536 /* NoComments */);
            }
            return block;
        }
        function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
            if (moduleDeclaration.body.kind === 249 /* ModuleDeclaration */) {
                var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
                return recursiveInnerModule || moduleDeclaration.body;
            }
        }
        /**
         * Visits an import declaration, eliding it if it is not referenced and `importsNotUsedAsValues` is not 'preserve'.
         *
         * @param node The import declaration node.
         */
        function visitImportDeclaration(node) {
            if (!node.importClause) {
                // Do not elide a side-effect only import declaration.
                //  import "foo";
                return node;
            }
            if (node.importClause.isTypeOnly) {
                // Always elide type-only imports
                return undefined;
            }
            // Elide the declaration if the import clause was elided.
            var importClause = ts.visitNode(node.importClause, visitImportClause, ts.isImportClause);
            return importClause ||
                compilerOptions.importsNotUsedAsValues === 1 /* Preserve */ ||
                compilerOptions.importsNotUsedAsValues === 2 /* Error */
                ? ts.updateImportDeclaration(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, importClause, node.moduleSpecifier)
                : undefined;
        }
        /**
         * Visits an import clause, eliding it if it is not referenced.
         *
         * @param node The import clause node.
         */
        function visitImportClause(node) {
            if (node.isTypeOnly) {
                return undefined;
            }
            // Elide the import clause if we elide both its name and its named bindings.
            var name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
            var namedBindings = ts.visitNode(node.namedBindings, visitNamedImportBindings, ts.isNamedImportBindings);
            return (name || namedBindings) ? ts.updateImportClause(node, name, namedBindings, /*isTypeOnly*/ false) : undefined;
        }
        /**
         * Visits named import bindings, eliding it if it is not referenced.
         *
         * @param node The named import bindings node.
         */
        function visitNamedImportBindings(node) {
            if (node.kind === 256 /* NamespaceImport */) {
                // Elide a namespace import if it is not referenced.
                return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
            }
            else {
                // Elide named imports if all of its import specifiers are elided.
                var elements = ts.visitNodes(node.elements, visitImportSpecifier, ts.isImportSpecifier);
                return ts.some(elements) ? ts.updateNamedImports(node, elements) : undefined;
            }
        }
        /**
         * Visits an import specifier, eliding it if it is not referenced.
         *
         * @param node The import specifier node.
         */
        function visitImportSpecifier(node) {
            // Elide an import specifier if it is not referenced.
            return resolver.isReferencedAliasDeclaration(node) ? node : undefined;
        }
        /**
         * Visits an export assignment, eliding it if it does not contain a clause that resolves
         * to a value.
         *
         * @param node The export assignment node.
         */
        function visitExportAssignment(node) {
            // Elide the export assignment if it does not reference a value.
            return resolver.isValueAliasDeclaration(node)
                ? ts.visitEachChild(node, visitor, context)
                : undefined;
        }
        /**
         * Visits an export declaration, eliding it if it does not contain a clause that resolves
         * to a value.
         *
         * @param node The export declaration node.
         */
        function visitExportDeclaration(node) {
            if (node.isTypeOnly) {
                return undefined;
            }
            if (!node.exportClause || ts.isNamespaceExport(node.exportClause)) {
                // never elide `export <whatever> from <whereever>` declarations -
                // they should be kept for sideffects/untyped exports, even when the
                // type checker doesn't know about any exports
                return node;
            }
            if (!resolver.isValueAliasDeclaration(node)) {
                // Elide the export declaration if it does not export a value.
                return undefined;
            }
            // Elide the export declaration if all of its named exports are elided.
            var exportClause = ts.visitNode(node.exportClause, visitNamedExportBindings, ts.isNamedExportBindings);
            return exportClause
                ? ts.updateExportDeclaration(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, exportClause, node.moduleSpecifier, node.isTypeOnly)
                : undefined;
        }
        /**
         * Visits named exports, eliding it if it does not contain an export specifier that
         * resolves to a value.
         *
         * @param node The named exports node.
         */
        function visitNamedExports(node) {
            // Elide the named exports if all of its export specifiers were elided.
            var elements = ts.visitNodes(node.elements, visitExportSpecifier, ts.isExportSpecifier);
            return ts.some(elements) ? ts.updateNamedExports(node, elements) : undefined;
        }
        function visitNamespaceExports(node) {
            return ts.updateNamespaceExport(node, ts.visitNode(node.name, visitor, ts.isIdentifier));
        }
        function visitNamedExportBindings(node) {
            return ts.isNamespaceExport(node) ? visitNamespaceExports(node) : visitNamedExports(node);
        }
        /**
         * Visits an export specifier, eliding it if it does not resolve to a value.
         *
         * @param node The export specifier node.
         */
        function visitExportSpecifier(node) {
            // Elide an export specifier if it does not reference a value.
            return resolver.isValueAliasDeclaration(node) ? node : undefined;
        }
        /**
         * Determines whether to emit an import equals declaration.
         *
         * @param node The import equals declaration node.
         */
        function shouldEmitImportEqualsDeclaration(node) {
            // preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
            // - current file is not external module
            // - import declaration is top level and target is value imported by entity name
            return resolver.isReferencedAliasDeclaration(node)
                || (!ts.isExternalModule(currentSourceFile)
                    && resolver.isTopLevelValueImportEqualsWithEntityName(node));
        }
        /**
         * Visits an import equals declaration.
         *
         * @param node The import equals declaration node.
         */
        function visitImportEqualsDeclaration(node) {
            if (ts.isExternalModuleImportEqualsDeclaration(node)) {
                var isReferenced = resolver.isReferencedAliasDeclaration(node);
                // If the alias is unreferenced but we want to keep the import, replace with 'import "mod"'.
                if (!isReferenced && compilerOptions.importsNotUsedAsValues === 1 /* Preserve */) {
                    return ts.setOriginalNode(ts.setTextRange(ts.createImportDeclaration(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*importClause*/ undefined, node.moduleReference.expression), node), node);
                }
                return isReferenced ? ts.visitEachChild(node, visitor, context) : undefined;
            }
            if (!shouldEmitImportEqualsDeclaration(node)) {
                return undefined;
            }
            var moduleReference = ts.createExpressionFromEntityName(node.moduleReference);
            ts.setEmitFlags(moduleReference, 1536 /* NoComments */ | 2048 /* NoNestedComments */);
            if (isNamedExternalModuleExport(node) || !isExportOfNamespace(node)) {
                //  export var ${name} = ${moduleReference};
                //  var ${name} = ${moduleReference};
                return ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([
                    ts.setOriginalNode(ts.createVariableDeclaration(node.name, 
                    /*type*/ undefined, moduleReference), node)
                ])), node), node);
            }
            else {
                // exports.${name} = ${moduleReference};
                return ts.setOriginalNode(createNamespaceExport(node.name, moduleReference, node), node);
            }
        }
        /**
         * Gets a value indicating whether the node is exported from a namespace.
         *
         * @param node The node to test.
         */
        function isExportOfNamespace(node) {
            return currentNamespace !== undefined && ts.hasModifier(node, 1 /* Export */);
        }
        /**
         * Gets a value indicating whether the node is exported from an external module.
         *
         * @param node The node to test.
         */
        function isExternalModuleExport(node) {
            return currentNamespace === undefined && ts.hasModifier(node, 1 /* Export */);
        }
        /**
         * Gets a value indicating whether the node is a named export from an external module.
         *
         * @param node The node to test.
         */
        function isNamedExternalModuleExport(node) {
            return isExternalModuleExport(node)
                && !ts.hasModifier(node, 512 /* Default */);
        }
        /**
         * Gets a value indicating whether the node is the default export of an external module.
         *
         * @param node The node to test.
         */
        function isDefaultExternalModuleExport(node) {
            return isExternalModuleExport(node)
                && ts.hasModifier(node, 512 /* Default */);
        }
        /**
         * Creates a statement for the provided expression. This is used in calls to `map`.
         */
        function expressionToStatement(expression) {
            return ts.createExpressionStatement(expression);
        }
        function addExportMemberAssignment(statements, node) {
            var expression = ts.createAssignment(ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true), ts.getLocalName(node));
            ts.setSourceMapRange(expression, ts.createRange(node.name ? node.name.pos : node.pos, node.end));
            var statement = ts.createExpressionStatement(expression);
            ts.setSourceMapRange(statement, ts.createRange(-1, node.end));
            statements.push(statement);
        }
        function createNamespaceExport(exportName, exportValue, location) {
            return ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(ts.getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), exportValue)), location);
        }
        function createNamespaceExportExpression(exportName, exportValue, location) {
            return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location);
        }
        function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name) {
            return ts.getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true);
        }
        /**
         * Gets the declaration name used inside of a namespace or enum.
         */
        function getNamespaceParameterName(node) {
            var name = ts.getGeneratedNameForNode(node);
            ts.setSourceMapRange(name, node.name);
            return name;
        }
        /**
         * Gets the expression used to refer to a namespace or enum within the body
         * of its declaration.
         */
        function getNamespaceContainerName(node) {
            return ts.getGeneratedNameForNode(node);
        }
        /**
         * Gets a local alias for a class declaration if it is a decorated class with an internal
         * reference to the static side of the class. This is necessary to avoid issues with
         * double-binding semantics for the class name.
         */
        function getClassAliasIfNeeded(node) {
            if (resolver.getNodeCheckFlags(node) & 16777216 /* ClassWithConstructorReference */) {
                enableSubstitutionForClassAliases();
                var classAlias = ts.createUniqueName(node.name && !ts.isGeneratedIdentifier(node.name) ? ts.idText(node.name) : "default");
                classAliases[ts.getOriginalNodeId(node)] = classAlias;
                hoistVariableDeclaration(classAlias);
                return classAlias;
            }
        }
        function getClassPrototype(node) {
            return ts.createPropertyAccess(ts.getDeclarationName(node), "prototype");
        }
        function getClassMemberPrefix(node, member) {
            return ts.hasModifier(member, 32 /* Static */)
                ? ts.getDeclarationName(node)
                : getClassPrototype(node);
        }
        function enableSubstitutionForNonQualifiedEnumMembers() {
            if ((enabledSubstitutions & 8 /* NonQualifiedEnumMembers */) === 0) {
                enabledSubstitutions |= 8 /* NonQualifiedEnumMembers */;
                context.enableSubstitution(75 /* Identifier */);
            }
        }
        function enableSubstitutionForClassAliases() {
            if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) {
                enabledSubstitutions |= 1 /* ClassAliases */;
                // We need to enable substitutions for identifiers. This allows us to
                // substitute class names inside of a class declaration.
                context.enableSubstitution(75 /* Identifier */);
                // Keep track of class aliases.
                classAliases = [];
            }
        }
        function enableSubstitutionForNamespaceExports() {
            if ((enabledSubstitutions & 2 /* NamespaceExports */) === 0) {
                enabledSubstitutions |= 2 /* NamespaceExports */;
                // We need to enable substitutions for identifiers and shorthand property assignments. This allows us to
                // substitute the names of exported members of a namespace.
                context.enableSubstitution(75 /* Identifier */);
                context.enableSubstitution(282 /* ShorthandPropertyAssignment */);
                // We need to be notified when entering and exiting namespaces.
                context.enableEmitNotification(249 /* ModuleDeclaration */);
            }
        }
        function isTransformedModuleDeclaration(node) {
            return ts.getOriginalNode(node).kind === 249 /* ModuleDeclaration */;
        }
        function isTransformedEnumDeclaration(node) {
            return ts.getOriginalNode(node).kind === 248 /* EnumDeclaration */;
        }
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            var savedApplicableSubstitutions = applicableSubstitutions;
            var savedCurrentSourceFile = currentSourceFile;
            if (ts.isSourceFile(node)) {
                currentSourceFile = node;
            }
            if (enabledSubstitutions & 2 /* NamespaceExports */ && isTransformedModuleDeclaration(node)) {
                applicableSubstitutions |= 2 /* NamespaceExports */;
            }
            if (enabledSubstitutions & 8 /* NonQualifiedEnumMembers */ && isTransformedEnumDeclaration(node)) {
                applicableSubstitutions |= 8 /* NonQualifiedEnumMembers */;
            }
            previousOnEmitNode(hint, node, emitCallback);
            applicableSubstitutions = savedApplicableSubstitutions;
            currentSourceFile = savedCurrentSourceFile;
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        function substituteShorthandPropertyAssignment(node) {
            if (enabledSubstitutions & 2 /* NamespaceExports */) {
                var name = node.name;
                var exportedName = trySubstituteNamespaceExportedName(name);
                if (exportedName) {
                    // A shorthand property with an assignment initializer is probably part of a
                    // destructuring assignment
                    if (node.objectAssignmentInitializer) {
                        var initializer = ts.createAssignment(exportedName, node.objectAssignmentInitializer);
                        return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
                    }
                    return ts.setTextRange(ts.createPropertyAssignment(name, exportedName), node);
                }
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 194 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 195 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            return trySubstituteClassAlias(node)
                || trySubstituteNamespaceExportedName(node)
                || node;
        }
        function trySubstituteClassAlias(node) {
            if (enabledSubstitutions & 1 /* ClassAliases */) {
                if (resolver.getNodeCheckFlags(node) & 33554432 /* ConstructorReferenceInClass */) {
                    // Due to the emit for class decorators, any reference to the class from inside of the class body
                    // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                    // behavior of class names in ES6.
                    // Also, when emitting statics for class expressions, we must substitute a class alias for
                    // constructor references in static property initializers.
                    var declaration = resolver.getReferencedValueDeclaration(node);
                    if (declaration) {
                        var classAlias = classAliases[declaration.id]; // TODO: GH#18217
                        if (classAlias) {
                            var clone_1 = ts.getSynthesizedClone(classAlias);
                            ts.setSourceMapRange(clone_1, node);
                            ts.setCommentRange(clone_1, node);
                            return clone_1;
                        }
                    }
                }
            }
            return undefined;
        }
        function trySubstituteNamespaceExportedName(node) {
            // If this is explicitly a local name, do not substitute.
            if (enabledSubstitutions & applicableSubstitutions && !ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                // If we are nested within a namespace declaration, we may need to qualifiy
                // an identifier that is exported from a merged namespace.
                var container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false);
                if (container && container.kind !== 290 /* SourceFile */) {
                    var substitute = (applicableSubstitutions & 2 /* NamespaceExports */ && container.kind === 249 /* ModuleDeclaration */) ||
                        (applicableSubstitutions & 8 /* NonQualifiedEnumMembers */ && container.kind === 248 /* EnumDeclaration */);
                    if (substitute) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(container), node), 
                        /*location*/ node);
                    }
                }
            }
            return undefined;
        }
        function substitutePropertyAccessExpression(node) {
            return substituteConstantValue(node);
        }
        function substituteElementAccessExpression(node) {
            return substituteConstantValue(node);
        }
        function substituteConstantValue(node) {
            var constantValue = tryGetConstEnumValue(node);
            if (constantValue !== undefined) {
                // track the constant value on the node for the printer in needsDotDotForPropertyAccess
                ts.setConstantValue(node, constantValue);
                var substitute = ts.createLiteral(constantValue);
                if (!compilerOptions.removeComments) {
                    var originalNode = ts.getOriginalNode(node, ts.isAccessExpression);
                    var propertyName = ts.isPropertyAccessExpression(originalNode)
                        ? ts.declarationNameToString(originalNode.name)
                        : ts.getTextOfNode(originalNode.argumentExpression);
                    ts.addSyntheticTrailingComment(substitute, 3 /* MultiLineCommentTrivia */, " " + propertyName + " ");
                }
                return substitute;
            }
            return node;
        }
        function tryGetConstEnumValue(node) {
            if (compilerOptions.isolatedModules) {
                return undefined;
            }
            return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined;
        }
    }
    ts.transformTypeScript = transformTypeScript;
    function createDecorateHelper(context, decoratorExpressions, target, memberName, descriptor, location) {
        var argumentsArray = [];
        argumentsArray.push(ts.createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
        argumentsArray.push(target);
        if (memberName) {
            argumentsArray.push(memberName);
            if (descriptor) {
                argumentsArray.push(descriptor);
            }
        }
        context.requestEmitHelper(ts.decorateHelper);
        return ts.setTextRange(ts.createCall(ts.getUnscopedHelperName("__decorate"), 
        /*typeArguments*/ undefined, argumentsArray), location);
    }
    ts.decorateHelper = {
        name: "typescript:decorate",
        importName: "__decorate",
        scoped: false,
        priority: 2,
        text: "\n            var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n                var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n                if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n                else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n                return c > 3 && r && Object.defineProperty(target, key, r), r;\n            };"
    };
    function createMetadataHelper(context, metadataKey, metadataValue) {
        context.requestEmitHelper(ts.metadataHelper);
        return ts.createCall(ts.getUnscopedHelperName("__metadata"), 
        /*typeArguments*/ undefined, [
            ts.createLiteral(metadataKey),
            metadataValue
        ]);
    }
    ts.metadataHelper = {
        name: "typescript:metadata",
        importName: "__metadata",
        scoped: false,
        priority: 3,
        text: "\n            var __metadata = (this && this.__metadata) || function (k, v) {\n                if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(k, v);\n            };"
    };
    function createParamHelper(context, expression, parameterOffset, location) {
        context.requestEmitHelper(ts.paramHelper);
        return ts.setTextRange(ts.createCall(ts.getUnscopedHelperName("__param"), 
        /*typeArguments*/ undefined, [
            ts.createLiteral(parameterOffset),
            expression
        ]), location);
    }
    ts.paramHelper = {
        name: "typescript:param",
        importName: "__param",
        scoped: false,
        priority: 4,
        text: "\n            var __param = (this && this.__param) || function (paramIndex, decorator) {\n                return function (target, key) { decorator(target, key, paramIndex); }\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ClassPropertySubstitutionFlags;
    (function (ClassPropertySubstitutionFlags) {
        /**
         * Enables substitutions for class expressions with static fields
         * which have initializers that reference the class name.
         */
        ClassPropertySubstitutionFlags[ClassPropertySubstitutionFlags["ClassAliases"] = 1] = "ClassAliases";
    })(ClassPropertySubstitutionFlags || (ClassPropertySubstitutionFlags = {}));
    var PrivateIdentifierPlacement;
    (function (PrivateIdentifierPlacement) {
        PrivateIdentifierPlacement[PrivateIdentifierPlacement["InstanceField"] = 0] = "InstanceField";
    })(PrivateIdentifierPlacement || (PrivateIdentifierPlacement = {}));
    /**
     * Transforms ECMAScript Class Syntax.
     * TypeScript parameter property syntax is transformed in the TypeScript transformer.
     * For now, this transforms public field declarations using TypeScript class semantics,
     * where declarations are elided and initializers are transformed as assignments in the constructor.
     * When --useDefineForClassFields is on, this transforms to ECMAScript semantics, with Object.defineProperty.
     */
    function transformClassFields(context) {
        var hoistVariableDeclaration = context.hoistVariableDeclaration, endLexicalEnvironment = context.endLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var shouldTransformPrivateFields = languageVersion < 99 /* ESNext */;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var enabledSubstitutions;
        var classAliases;
        /**
         * Tracks what computed name expressions originating from elided names must be inlined
         * at the next execution site, in document order
         */
        var pendingExpressions;
        /**
         * Tracks what computed name expression statements and static property initializers must be
         * emitted at the next execution site, in document order (for decorated classes).
         */
        var pendingStatements;
        var privateIdentifierEnvironmentStack = [];
        var currentPrivateIdentifierEnvironment;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            var options = context.getCompilerOptions();
            if (node.isDeclarationFile
                || options.useDefineForClassFields && options.target === 99 /* ESNext */) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            if (!(node.transformFlags & 4194304 /* ContainsClassFields */))
                return node;
            switch (node.kind) {
                case 214 /* ClassExpression */:
                case 245 /* ClassDeclaration */:
                    return visitClassLike(node);
                case 159 /* PropertyDeclaration */:
                    return visitPropertyDeclaration(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 154 /* ComputedPropertyName */:
                    return visitComputedPropertyName(node);
                case 194 /* PropertyAccessExpression */:
                    return visitPropertyAccessExpression(node);
                case 207 /* PrefixUnaryExpression */:
                    return visitPrefixUnaryExpression(node);
                case 208 /* PostfixUnaryExpression */:
                    return visitPostfixUnaryExpression(node, /*valueIsDiscarded*/ false);
                case 196 /* CallExpression */:
                    return visitCallExpression(node);
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                case 76 /* PrivateIdentifier */:
                    return visitPrivateIdentifier(node);
                case 226 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 230 /* ForStatement */:
                    return visitForStatement(node);
                case 198 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitorDestructuringTarget(node) {
            switch (node.kind) {
                case 193 /* ObjectLiteralExpression */:
                case 192 /* ArrayLiteralExpression */:
                    return visitAssignmentPattern(node);
                default:
                    return visitor(node);
            }
        }
        /**
         * If we visit a private name, this means it is an undeclared private name.
         * Replace it with an empty identifier to indicate a problem with the code.
         */
        function visitPrivateIdentifier(node) {
            if (!shouldTransformPrivateFields) {
                return node;
            }
            return ts.setOriginalNode(ts.createIdentifier(""), node);
        }
        /**
         * Visits the members of a class that has fields.
         *
         * @param node The node to visit.
         */
        function classElementVisitor(node) {
            switch (node.kind) {
                case 162 /* Constructor */:
                    // Constructors for classes using class fields are transformed in
                    // `visitClassDeclaration` or `visitClassExpression`.
                    return undefined;
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 161 /* MethodDeclaration */:
                    // Visit the name of the member (if it's a computed property name).
                    return ts.visitEachChild(node, classElementVisitor, context);
                case 159 /* PropertyDeclaration */:
                    return visitPropertyDeclaration(node);
                case 154 /* ComputedPropertyName */:
                    return visitComputedPropertyName(node);
                case 222 /* SemicolonClassElement */:
                    return node;
                default:
                    return visitor(node);
            }
        }
        function visitVariableStatement(node) {
            var savedPendingStatements = pendingStatements;
            pendingStatements = [];
            var visitedNode = ts.visitEachChild(node, visitor, context);
            var statement = ts.some(pendingStatements) ? __spreadArrays([visitedNode], pendingStatements) :
                visitedNode;
            pendingStatements = savedPendingStatements;
            return statement;
        }
        function visitComputedPropertyName(name) {
            var node = ts.visitEachChild(name, visitor, context);
            if (ts.some(pendingExpressions)) {
                var expressions = pendingExpressions;
                expressions.push(name.expression);
                pendingExpressions = [];
                node = ts.updateComputedPropertyName(node, ts.inlineExpressions(expressions));
            }
            return node;
        }
        function visitPropertyDeclaration(node) {
            ts.Debug.assert(!ts.some(node.decorators));
            if (!shouldTransformPrivateFields && ts.isPrivateIdentifier(node.name)) {
                // Initializer is elided as the field is initialized in transformConstructor.
                return ts.updateProperty(node, 
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.name, 
                /*questionOrExclamationToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined);
            }
            // Create a temporary variable to store a computed property name (if necessary).
            // If it's not inlineable, then we emit an expression after the class which assigns
            // the property name to the temporary variable.
            var expr = getPropertyNameExpressionIfNeeded(node.name, !!node.initializer || !!context.getCompilerOptions().useDefineForClassFields);
            if (expr && !ts.isSimpleInlineableExpression(expr)) {
                (pendingExpressions || (pendingExpressions = [])).push(expr);
            }
            return undefined;
        }
        function createPrivateIdentifierAccess(info, receiver) {
            receiver = ts.visitNode(receiver, visitor, ts.isExpression);
            switch (info.placement) {
                case 0 /* InstanceField */:
                    return createClassPrivateFieldGetHelper(context, ts.nodeIsSynthesized(receiver) ? receiver : ts.getSynthesizedClone(receiver), info.weakMapName);
                default: return ts.Debug.fail("Unexpected private identifier placement");
            }
        }
        function visitPropertyAccessExpression(node) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifier(node.name)) {
                var privateIdentifierInfo = accessPrivateIdentifier(node.name);
                if (privateIdentifierInfo) {
                    return ts.setOriginalNode(createPrivateIdentifierAccess(privateIdentifierInfo, node.expression), node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitPrefixUnaryExpression(node) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyAccessExpression(node.operand)) {
                var operator = node.operator === 45 /* PlusPlusToken */ ?
                    39 /* PlusToken */ : node.operator === 46 /* MinusMinusToken */ ?
                    40 /* MinusToken */ : undefined;
                var info = void 0;
                if (operator && (info = accessPrivateIdentifier(node.operand.name))) {
                    var receiver = ts.visitNode(node.operand.expression, visitor, ts.isExpression);
                    var _a = createCopiableReceiverExpr(receiver), readExpression = _a.readExpression, initializeExpression = _a.initializeExpression;
                    var existingValue = ts.createPrefix(39 /* PlusToken */, createPrivateIdentifierAccess(info, readExpression));
                    return ts.setOriginalNode(createPrivateIdentifierAssignment(info, initializeExpression || readExpression, ts.createBinary(existingValue, operator, ts.createLiteral(1)), 62 /* EqualsToken */), node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitPostfixUnaryExpression(node, valueIsDiscarded) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyAccessExpression(node.operand)) {
                var operator = node.operator === 45 /* PlusPlusToken */ ?
                    39 /* PlusToken */ : node.operator === 46 /* MinusMinusToken */ ?
                    40 /* MinusToken */ : undefined;
                var info = void 0;
                if (operator && (info = accessPrivateIdentifier(node.operand.name))) {
                    var receiver = ts.visitNode(node.operand.expression, visitor, ts.isExpression);
                    var _a = createCopiableReceiverExpr(receiver), readExpression = _a.readExpression, initializeExpression = _a.initializeExpression;
                    var existingValue = ts.createPrefix(39 /* PlusToken */, createPrivateIdentifierAccess(info, readExpression));
                    // Create a temporary variable to store the value returned by the expression.
                    var returnValue = valueIsDiscarded ? undefined : ts.createTempVariable(hoistVariableDeclaration);
                    return ts.setOriginalNode(ts.inlineExpressions(ts.compact([
                        createPrivateIdentifierAssignment(info, initializeExpression || readExpression, ts.createBinary(returnValue ? ts.createAssignment(returnValue, existingValue) : existingValue, operator, ts.createLiteral(1)), 62 /* EqualsToken */),
                        returnValue
                    ])), node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForStatement(node) {
            if (node.incrementor && ts.isPostfixUnaryExpression(node.incrementor)) {
                return ts.updateFor(node, ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), visitPostfixUnaryExpression(node.incrementor, /*valueIsDiscarded*/ true), ts.visitNode(node.statement, visitor, ts.isStatement));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitExpressionStatement(node) {
            if (ts.isPostfixUnaryExpression(node.expression)) {
                return ts.updateExpressionStatement(node, visitPostfixUnaryExpression(node.expression, /*valueIsDiscarded*/ true));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function createCopiableReceiverExpr(receiver) {
            var clone = ts.nodeIsSynthesized(receiver) ? receiver : ts.getSynthesizedClone(receiver);
            if (ts.isSimpleInlineableExpression(receiver)) {
                return { readExpression: clone, initializeExpression: undefined };
            }
            var readExpression = ts.createTempVariable(hoistVariableDeclaration);
            var initializeExpression = ts.createAssignment(readExpression, clone);
            return { readExpression: readExpression, initializeExpression: initializeExpression };
        }
        function visitCallExpression(node) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyAccessExpression(node.expression)) {
                // Transform call expressions of private names to properly bind the `this` parameter.
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion), thisArg = _a.thisArg, target = _a.target;
                return ts.updateCall(node, ts.createPropertyAccess(ts.visitNode(target, visitor), "call"), 
                /*typeArguments*/ undefined, __spreadArrays([ts.visitNode(thisArg, visitor, ts.isExpression)], ts.visitNodes(node.arguments, visitor, ts.isExpression)));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitTaggedTemplateExpression(node) {
            if (shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyAccessExpression(node.tag)) {
                // Bind the `this` correctly for tagged template literals when the tag is a private identifier property access.
                var _a = ts.createCallBinding(node.tag, hoistVariableDeclaration, languageVersion), thisArg = _a.thisArg, target = _a.target;
                return ts.updateTaggedTemplate(node, ts.createCall(ts.createPropertyAccess(ts.visitNode(target, visitor), "bind"), 
                /*typeArguments*/ undefined, [ts.visitNode(thisArg, visitor, ts.isExpression)]), ts.visitNode(node.template, visitor, ts.isTemplateLiteral));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitBinaryExpression(node) {
            if (shouldTransformPrivateFields) {
                if (ts.isDestructuringAssignment(node)) {
                    var savedPendingExpressions = pendingExpressions;
                    pendingExpressions = undefined;
                    node = ts.updateBinary(node, ts.visitNode(node.left, visitorDestructuringTarget), ts.visitNode(node.right, visitor), node.operatorToken);
                    var expr = ts.some(pendingExpressions) ?
                        ts.inlineExpressions(ts.compact(__spreadArrays(pendingExpressions, [node]))) :
                        node;
                    pendingExpressions = savedPendingExpressions;
                    return expr;
                }
                if (ts.isAssignmentExpression(node) && ts.isPrivateIdentifierPropertyAccessExpression(node.left)) {
                    var info = accessPrivateIdentifier(node.left.name);
                    if (info) {
                        return ts.setOriginalNode(createPrivateIdentifierAssignment(info, node.left.expression, node.right, node.operatorToken.kind), node);
                    }
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function createPrivateIdentifierAssignment(info, receiver, right, operator) {
            switch (info.placement) {
                case 0 /* InstanceField */: {
                    return createPrivateIdentifierInstanceFieldAssignment(info, receiver, right, operator);
                }
                default: return ts.Debug.fail("Unexpected private identifier placement");
            }
        }
        function createPrivateIdentifierInstanceFieldAssignment(info, receiver, right, operator) {
            receiver = ts.visitNode(receiver, visitor, ts.isExpression);
            right = ts.visitNode(right, visitor, ts.isExpression);
            if (ts.isCompoundAssignment(operator)) {
                var _a = createCopiableReceiverExpr(receiver), readExpression = _a.readExpression, initializeExpression = _a.initializeExpression;
                return createClassPrivateFieldSetHelper(context, initializeExpression || readExpression, info.weakMapName, ts.createBinary(createClassPrivateFieldGetHelper(context, readExpression, info.weakMapName), ts.getNonAssignmentOperatorForCompoundAssignment(operator), right));
            }
            else {
                return createClassPrivateFieldSetHelper(context, receiver, info.weakMapName, right);
            }
        }
        /**
         * Set up the environment for a class.
         */
        function visitClassLike(node) {
            var savedPendingExpressions = pendingExpressions;
            pendingExpressions = undefined;
            if (shouldTransformPrivateFields) {
                startPrivateIdentifierEnvironment();
            }
            var result = ts.isClassDeclaration(node) ?
                visitClassDeclaration(node) :
                visitClassExpression(node);
            if (shouldTransformPrivateFields) {
                endPrivateIdentifierEnvironment();
            }
            pendingExpressions = savedPendingExpressions;
            return result;
        }
        function doesClassElementNeedTransform(node) {
            return ts.isPropertyDeclaration(node) || (shouldTransformPrivateFields && node.name && ts.isPrivateIdentifier(node.name));
        }
        function visitClassDeclaration(node) {
            if (!ts.forEach(node.members, doesClassElementNeedTransform)) {
                return ts.visitEachChild(node, visitor, context);
            }
            var extendsClauseElement = ts.getEffectiveBaseTypeNode(node);
            var isDerivedClass = !!(extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 100 /* NullKeyword */);
            var statements = [
                ts.updateClassDeclaration(node, 
                /*decorators*/ undefined, node.modifiers, node.name, 
                /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node, isDerivedClass))
            ];
            // Write any pending expressions from elided or moved computed property names
            if (ts.some(pendingExpressions)) {
                statements.push(ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions)));
            }
            // Emit static property assignment. Because classDeclaration is lexically evaluated,
            // it is safe to emit static property assignment after classDeclaration
            // From ES6 specification:
            //      HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
            //                                  a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
            var staticProperties = ts.getProperties(node, /*requireInitializer*/ true, /*isStatic*/ true);
            if (ts.some(staticProperties)) {
                addPropertyStatements(statements, staticProperties, ts.getInternalName(node));
            }
            return statements;
        }
        function visitClassExpression(node) {
            if (!ts.forEach(node.members, doesClassElementNeedTransform)) {
                return ts.visitEachChild(node, visitor, context);
            }
            // If this class expression is a transformation of a decorated class declaration,
            // then we want to output the pendingExpressions as statements, not as inlined
            // expressions with the class statement.
            //
            // In this case, we use pendingStatements to produce the same output as the
            // class declaration transformation. The VariableStatement visitor will insert
            // these statements after the class expression variable statement.
            var isDecoratedClassDeclaration = ts.isClassDeclaration(ts.getOriginalNode(node));
            var staticProperties = ts.getProperties(node, /*requireInitializer*/ true, /*isStatic*/ true);
            var extendsClauseElement = ts.getEffectiveBaseTypeNode(node);
            var isDerivedClass = !!(extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 100 /* NullKeyword */);
            var classExpression = ts.updateClassExpression(node, node.modifiers, node.name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node, isDerivedClass));
            if (ts.some(staticProperties) || ts.some(pendingExpressions)) {
                if (isDecoratedClassDeclaration) {
                    ts.Debug.assertIsDefined(pendingStatements, "Decorated classes transformed by TypeScript are expected to be within a variable declaration.");
                    // Write any pending expressions from elided or moved computed property names
                    if (pendingStatements && pendingExpressions && ts.some(pendingExpressions)) {
                        pendingStatements.push(ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions)));
                    }
                    if (pendingStatements && ts.some(staticProperties)) {
                        addPropertyStatements(pendingStatements, staticProperties, ts.getInternalName(node));
                    }
                    return classExpression;
                }
                else {
                    var expressions = [];
                    var isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & 16777216 /* ClassWithConstructorReference */;
                    var temp = ts.createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference);
                    if (isClassWithConstructorReference) {
                        // record an alias as the class name is not in scope for statics.
                        enableSubstitutionForClassAliases();
                        var alias = ts.getSynthesizedClone(temp);
                        alias.autoGenerateFlags &= ~8 /* ReservedInNestedScopes */;
                        classAliases[ts.getOriginalNodeId(node)] = alias;
                    }
                    // To preserve the behavior of the old emitter, we explicitly indent
                    // the body of a class with static initializers.
                    ts.setEmitFlags(classExpression, 65536 /* Indented */ | ts.getEmitFlags(classExpression));
                    expressions.push(ts.startOnNewLine(ts.createAssignment(temp, classExpression)));
                    // Add any pending expressions leftover from elided or relocated computed property names
                    ts.addRange(expressions, ts.map(pendingExpressions, ts.startOnNewLine));
                    ts.addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp));
                    expressions.push(ts.startOnNewLine(temp));
                    return ts.inlineExpressions(expressions);
                }
            }
            return classExpression;
        }
        function transformClassMembers(node, isDerivedClass) {
            if (shouldTransformPrivateFields) {
                // Declare private names.
                for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                    var member = _a[_i];
                    if (ts.isPrivateIdentifierPropertyDeclaration(member)) {
                        addPrivateIdentifierToEnvironment(member.name);
                    }
                }
            }
            var members = [];
            var constructor = transformConstructor(node, isDerivedClass);
            if (constructor) {
                members.push(constructor);
            }
            ts.addRange(members, ts.visitNodes(node.members, classElementVisitor, ts.isClassElement));
            return ts.setTextRange(ts.createNodeArray(members), /*location*/ node.members);
        }
        function isPropertyDeclarationThatRequiresConstructorStatement(member) {
            if (!ts.isPropertyDeclaration(member) || ts.hasStaticModifier(member)) {
                return false;
            }
            if (context.getCompilerOptions().useDefineForClassFields) {
                // If we are using define semantics and targeting ESNext or higher,
                // then we don't need to transform any class properties.
                return languageVersion < 99 /* ESNext */;
            }
            return ts.isInitializedProperty(member) || shouldTransformPrivateFields && ts.isPrivateIdentifierPropertyDeclaration(member);
        }
        function transformConstructor(node, isDerivedClass) {
            var constructor = ts.visitNode(ts.getFirstConstructorWithBody(node), visitor, ts.isConstructorDeclaration);
            var properties = node.members.filter(isPropertyDeclarationThatRequiresConstructorStatement);
            if (!ts.some(properties)) {
                return constructor;
            }
            var parameters = ts.visitParameterList(constructor ? constructor.parameters : undefined, visitor, context);
            var body = transformConstructorBody(node, constructor, isDerivedClass);
            if (!body) {
                return undefined;
            }
            return ts.startOnNewLine(ts.setOriginalNode(ts.setTextRange(ts.createConstructor(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, parameters !== null && parameters !== void 0 ? parameters : [], body), constructor || node), constructor));
        }
        function transformConstructorBody(node, constructor, isDerivedClass) {
            var useDefineForClassFields = context.getCompilerOptions().useDefineForClassFields;
            var properties = ts.getProperties(node, /*requireInitializer*/ false, /*isStatic*/ false);
            if (!useDefineForClassFields) {
                properties = ts.filter(properties, function (property) { return !!property.initializer || ts.isPrivateIdentifier(property.name); });
            }
            // Only generate synthetic constructor when there are property initializers to move.
            if (!constructor && !ts.some(properties)) {
                return ts.visitFunctionBody(/*node*/ undefined, visitor, context);
            }
            resumeLexicalEnvironment();
            var indexOfFirstStatement = 0;
            var statements = [];
            if (!constructor && isDerivedClass) {
                // Add a synthetic `super` call:
                //
                //  super(...arguments);
                //
                statements.push(ts.createExpressionStatement(ts.createCall(ts.createSuper(), 
                /*typeArguments*/ undefined, [ts.createSpread(ts.createIdentifier("arguments"))])));
            }
            if (constructor) {
                indexOfFirstStatement = ts.addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor);
            }
            // Add the property initializers. Transforms this:
            //
            //  public x = 1;
            //
            // Into this:
            //
            //  constructor() {
            //      this.x = 1;
            //  }
            //
            if (constructor === null || constructor === void 0 ? void 0 : constructor.body) {
                var afterParameterProperties = ts.findIndex(constructor.body.statements, function (s) { return !ts.isParameterPropertyDeclaration(ts.getOriginalNode(s), constructor); }, indexOfFirstStatement);
                if (afterParameterProperties === -1) {
                    afterParameterProperties = constructor.body.statements.length;
                }
                if (afterParameterProperties > indexOfFirstStatement) {
                    if (!useDefineForClassFields) {
                        ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatement, afterParameterProperties - indexOfFirstStatement));
                    }
                    indexOfFirstStatement = afterParameterProperties;
                }
            }
            addPropertyStatements(statements, properties, ts.createThis());
            // Add existing statements, skipping the initial super call.
            if (constructor) {
                ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatement));
            }
            statements = ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            return ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), 
            /*location*/ constructor ? constructor.body.statements : node.members), 
            /*multiLine*/ true), 
            /*location*/ constructor ? constructor.body : undefined);
        }
        /**
         * Generates assignment statements for property initializers.
         *
         * @param properties An array of property declarations to transform.
         * @param receiver The receiver on which each property should be assigned.
         */
        function addPropertyStatements(statements, properties, receiver) {
            for (var _i = 0, properties_8 = properties; _i < properties_8.length; _i++) {
                var property = properties_8[_i];
                var expression = transformProperty(property, receiver);
                if (!expression) {
                    continue;
                }
                var statement = ts.createExpressionStatement(expression);
                ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property));
                ts.setCommentRange(statement, property);
                ts.setOriginalNode(statement, property);
                statements.push(statement);
            }
        }
        /**
         * Generates assignment expressions for property initializers.
         *
         * @param properties An array of property declarations to transform.
         * @param receiver The receiver on which each property should be assigned.
         */
        function generateInitializedPropertyExpressions(properties, receiver) {
            var expressions = [];
            for (var _i = 0, properties_9 = properties; _i < properties_9.length; _i++) {
                var property = properties_9[_i];
                var expression = transformProperty(property, receiver);
                if (!expression) {
                    continue;
                }
                ts.startOnNewLine(expression);
                ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property));
                ts.setCommentRange(expression, property);
                ts.setOriginalNode(expression, property);
                expressions.push(expression);
            }
            return expressions;
        }
        /**
         * Transforms a property initializer into an assignment statement.
         *
         * @param property The property declaration.
         * @param receiver The object receiving the property assignment.
         */
        function transformProperty(property, receiver) {
            // We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name)
            var emitAssignment = !context.getCompilerOptions().useDefineForClassFields;
            var propertyName = ts.isComputedPropertyName(property.name) && !ts.isSimpleInlineableExpression(property.name.expression)
                ? ts.updateComputedPropertyName(property.name, ts.getGeneratedNameForNode(property.name))
                : property.name;
            if (shouldTransformPrivateFields && ts.isPrivateIdentifier(propertyName)) {
                var privateIdentifierInfo = accessPrivateIdentifier(propertyName);
                if (privateIdentifierInfo) {
                    switch (privateIdentifierInfo.placement) {
                        case 0 /* InstanceField */: {
                            return createPrivateInstanceFieldInitializer(receiver, ts.visitNode(property.initializer, visitor, ts.isExpression), privateIdentifierInfo.weakMapName);
                        }
                    }
                }
                else {
                    ts.Debug.fail("Undeclared private name for property declaration.");
                }
            }
            if (ts.isPrivateIdentifier(propertyName) && !property.initializer) {
                return undefined;
            }
            if (ts.isPrivateIdentifier(propertyName) && !property.initializer) {
                return undefined;
            }
            var propertyOriginalNode = ts.getOriginalNode(property);
            var initializer = property.initializer || emitAssignment ? ts.visitNode(property.initializer, visitor, ts.isExpression)
                : ts.isParameterPropertyDeclaration(propertyOriginalNode, propertyOriginalNode.parent) && ts.isIdentifier(propertyName) ? propertyName
                    : ts.createVoidZero();
            if (emitAssignment || ts.isPrivateIdentifier(propertyName)) {
                var memberAccess = ts.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName);
                return ts.createAssignment(memberAccess, initializer);
            }
            else {
                var name = ts.isComputedPropertyName(propertyName) ? propertyName.expression
                    : ts.isIdentifier(propertyName) ? ts.createStringLiteral(ts.unescapeLeadingUnderscores(propertyName.escapedText))
                        : propertyName;
                var descriptor = ts.createPropertyDescriptor({ value: initializer, configurable: true, writable: true, enumerable: true });
                return ts.createObjectDefinePropertyCall(receiver, name, descriptor);
            }
        }
        function enableSubstitutionForClassAliases() {
            if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) {
                enabledSubstitutions |= 1 /* ClassAliases */;
                // We need to enable substitutions for identifiers. This allows us to
                // substitute class names inside of a class declaration.
                context.enableSubstitution(75 /* Identifier */);
                // Keep track of class aliases.
                classAliases = [];
            }
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            return trySubstituteClassAlias(node) || node;
        }
        function trySubstituteClassAlias(node) {
            if (enabledSubstitutions & 1 /* ClassAliases */) {
                if (resolver.getNodeCheckFlags(node) & 33554432 /* ConstructorReferenceInClass */) {
                    // Due to the emit for class decorators, any reference to the class from inside of the class body
                    // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
                    // behavior of class names in ES6.
                    // Also, when emitting statics for class expressions, we must substitute a class alias for
                    // constructor references in static property initializers.
                    var declaration = resolver.getReferencedValueDeclaration(node);
                    if (declaration) {
                        var classAlias = classAliases[declaration.id]; // TODO: GH#18217
                        if (classAlias) {
                            var clone_2 = ts.getSynthesizedClone(classAlias);
                            ts.setSourceMapRange(clone_2, node);
                            ts.setCommentRange(clone_2, node);
                            return clone_2;
                        }
                    }
                }
            }
            return undefined;
        }
        /**
         * If the name is a computed property, this function transforms it, then either returns an expression which caches the
         * value of the result or the expression itself if the value is either unused or safe to inline into multiple locations
         * @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator)
         */
        function getPropertyNameExpressionIfNeeded(name, shouldHoist) {
            if (ts.isComputedPropertyName(name)) {
                var expression = ts.visitNode(name.expression, visitor, ts.isExpression);
                var innerExpression = ts.skipPartiallyEmittedExpressions(expression);
                var inlinable = ts.isSimpleInlineableExpression(innerExpression);
                var alreadyTransformed = ts.isAssignmentExpression(innerExpression) && ts.isGeneratedIdentifier(innerExpression.left);
                if (!alreadyTransformed && !inlinable && shouldHoist) {
                    var generatedName = ts.getGeneratedNameForNode(name);
                    hoistVariableDeclaration(generatedName);
                    return ts.createAssignment(generatedName, expression);
                }
                return (inlinable || ts.isIdentifier(innerExpression)) ? undefined : expression;
            }
        }
        function startPrivateIdentifierEnvironment() {
            privateIdentifierEnvironmentStack.push(currentPrivateIdentifierEnvironment);
            currentPrivateIdentifierEnvironment = undefined;
        }
        function endPrivateIdentifierEnvironment() {
            currentPrivateIdentifierEnvironment = privateIdentifierEnvironmentStack.pop();
        }
        function addPrivateIdentifierToEnvironment(name) {
            var text = ts.getTextOfPropertyName(name);
            var weakMapName = ts.createOptimisticUniqueName("_" + text.substring(1));
            weakMapName.autoGenerateFlags |= 8 /* ReservedInNestedScopes */;
            hoistVariableDeclaration(weakMapName);
            (currentPrivateIdentifierEnvironment || (currentPrivateIdentifierEnvironment = ts.createUnderscoreEscapedMap()))
                .set(name.escapedText, { placement: 0 /* InstanceField */, weakMapName: weakMapName });
            (pendingExpressions || (pendingExpressions = [])).push(ts.createAssignment(weakMapName, ts.createNew(ts.createIdentifier("WeakMap"), 
            /*typeArguments*/ undefined, [])));
        }
        function accessPrivateIdentifier(name) {
            if (currentPrivateIdentifierEnvironment) {
                var info = currentPrivateIdentifierEnvironment.get(name.escapedText);
                if (info) {
                    return info;
                }
            }
            for (var i = privateIdentifierEnvironmentStack.length - 1; i >= 0; --i) {
                var env = privateIdentifierEnvironmentStack[i];
                if (!env) {
                    continue;
                }
                var info = env.get(name.escapedText);
                if (info) {
                    return info;
                }
            }
            return undefined;
        }
        function wrapPrivateIdentifierForDestructuringTarget(node) {
            var parameter = ts.getGeneratedNameForNode(node);
            var info = accessPrivateIdentifier(node.name);
            if (!info) {
                return ts.visitEachChild(node, visitor, context);
            }
            var receiver = node.expression;
            // We cannot copy `this` or `super` into the function because they will be bound
            // differently inside the function.
            if (ts.isThisProperty(node) || ts.isSuperProperty(node) || !ts.isSimpleCopiableExpression(node.expression)) {
                receiver = ts.createTempVariable(hoistVariableDeclaration);
                receiver.autoGenerateFlags |= 8 /* ReservedInNestedScopes */;
                (pendingExpressions || (pendingExpressions = [])).push(ts.createBinary(receiver, 62 /* EqualsToken */, node.expression));
            }
            return ts.createPropertyAccess(
            // Explicit parens required because of v8 regression (https://bugs.chromium.org/p/v8/issues/detail?id=9560)
            ts.createParen(ts.createObjectLiteral([
                ts.createSetAccessor(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, "value", [ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, parameter, 
                    /*questionToken*/ undefined, 
                    /*type*/ undefined, 
                    /*initializer*/ undefined)], ts.createBlock([ts.createExpressionStatement(createPrivateIdentifierAssignment(info, receiver, parameter, 62 /* EqualsToken */))]))
            ])), "value");
        }
        function visitArrayAssignmentTarget(node) {
            var target = ts.getTargetOfBindingOrAssignmentElement(node);
            if (target && ts.isPrivateIdentifierPropertyAccessExpression(target)) {
                var wrapped = wrapPrivateIdentifierForDestructuringTarget(target);
                if (ts.isAssignmentExpression(node)) {
                    return ts.updateBinary(node, wrapped, ts.visitNode(node.right, visitor, ts.isExpression), node.operatorToken);
                }
                else if (ts.isSpreadElement(node)) {
                    return ts.updateSpread(node, wrapped);
                }
                else {
                    return wrapped;
                }
            }
            return ts.visitNode(node, visitorDestructuringTarget);
        }
        function visitObjectAssignmentTarget(node) {
            if (ts.isPropertyAssignment(node)) {
                var target = ts.getTargetOfBindingOrAssignmentElement(node);
                if (target && ts.isPrivateIdentifierPropertyAccessExpression(target)) {
                    var initializer = ts.getInitializerOfBindingOrAssignmentElement(node);
                    var wrapped = wrapPrivateIdentifierForDestructuringTarget(target);
                    return ts.updatePropertyAssignment(node, ts.visitNode(node.name, visitor), initializer ? ts.createAssignment(wrapped, ts.visitNode(initializer, visitor)) : wrapped);
                }
                return ts.updatePropertyAssignment(node, ts.visitNode(node.name, visitor), ts.visitNode(node.initializer, visitorDestructuringTarget));
            }
            return ts.visitNode(node, visitor);
        }
        function visitAssignmentPattern(node) {
            if (ts.isArrayLiteralExpression(node)) {
                // Transforms private names in destructuring assignment array bindings.
                //
                // Source:
                // ([ this.#myProp ] = [ "hello" ]);
                //
                // Transformation:
                // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ];
                return ts.updateArrayLiteral(node, ts.visitNodes(node.elements, visitArrayAssignmentTarget, ts.isExpression));
            }
            else {
                // Transforms private names in destructuring assignment object bindings.
                //
                // Source:
                // ({ stringProperty: this.#myProp } = { stringProperty: "hello" });
                //
                // Transformation:
                // ({ stringProperty: { set value(x) { this.#myProp = x; } }.value }) = { stringProperty: "hello" };
                return ts.updateObjectLiteral(node, ts.visitNodes(node.properties, visitObjectAssignmentTarget, ts.isObjectLiteralElementLike));
            }
        }
    }
    ts.transformClassFields = transformClassFields;
    function createPrivateInstanceFieldInitializer(receiver, initializer, weakMapName) {
        return ts.createCall(ts.createPropertyAccess(weakMapName, "set"), 
        /*typeArguments*/ undefined, [receiver, initializer || ts.createVoidZero()]);
    }
    ts.classPrivateFieldGetHelper = {
        name: "typescript:classPrivateFieldGet",
        scoped: false,
        text: "\n            var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {\n                if (!privateMap.has(receiver)) {\n                    throw new TypeError(\"attempted to get private field on non-instance\");\n                }\n                return privateMap.get(receiver);\n            };"
    };
    function createClassPrivateFieldGetHelper(context, receiver, privateField) {
        context.requestEmitHelper(ts.classPrivateFieldGetHelper);
        return ts.createCall(ts.getUnscopedHelperName("__classPrivateFieldGet"), /* typeArguments */ undefined, [receiver, privateField]);
    }
    ts.classPrivateFieldSetHelper = {
        name: "typescript:classPrivateFieldSet",
        scoped: false,
        text: "\n            var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) {\n                if (!privateMap.has(receiver)) {\n                    throw new TypeError(\"attempted to set private field on non-instance\");\n                }\n                privateMap.set(receiver, value);\n                return value;\n            };"
    };
    function createClassPrivateFieldSetHelper(context, receiver, privateField, value) {
        context.requestEmitHelper(ts.classPrivateFieldSetHelper);
        return ts.createCall(ts.getUnscopedHelperName("__classPrivateFieldSet"), /* typeArguments */ undefined, [receiver, privateField, value]);
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ES2017SubstitutionFlags;
    (function (ES2017SubstitutionFlags) {
        /** Enables substitutions for async methods with `super` calls. */
        ES2017SubstitutionFlags[ES2017SubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
    })(ES2017SubstitutionFlags || (ES2017SubstitutionFlags = {}));
    var ContextFlags;
    (function (ContextFlags) {
        ContextFlags[ContextFlags["NonTopLevel"] = 1] = "NonTopLevel";
        ContextFlags[ContextFlags["HasLexicalThis"] = 2] = "HasLexicalThis";
    })(ContextFlags || (ContextFlags = {}));
    function transformES2017(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        /**
         * Keeps track of whether expression substitution has been enabled for specific edge cases.
         * They are persisted between each SourceFile transformation and should not be reset.
         */
        var enabledSubstitutions;
        /**
         * This keeps track of containers where `super` is valid, for use with
         * just-in-time substitution for `super` expressions inside of async methods.
         */
        var enclosingSuperContainerFlags = 0;
        var enclosingFunctionParameterNames;
        /**
         * Keeps track of property names accessed on super (`super.x`) within async functions.
         */
        var capturedSuperProperties;
        /** Whether the async function contains an element access on super (`super[x]`). */
        var hasSuperElementAccess;
        /** A set of node IDs for generated super accessors (variable statements). */
        var substitutedSuperAccessors = [];
        var contextFlags = 0;
        // Save the previous transformation hooks.
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        // Set new transformation hooks.
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            setContextFlag(1 /* NonTopLevel */, false);
            setContextFlag(2 /* HasLexicalThis */, !ts.isEffectiveStrictModeSourceFile(node, compilerOptions));
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function setContextFlag(flag, val) {
            contextFlags = val ? contextFlags | flag : contextFlags & ~flag;
        }
        function inContext(flags) {
            return (contextFlags & flags) !== 0;
        }
        function inTopLevelContext() {
            return !inContext(1 /* NonTopLevel */);
        }
        function inHasLexicalThisContext() {
            return inContext(2 /* HasLexicalThis */);
        }
        function doWithContext(flags, cb, value) {
            var contextFlagsToSet = flags & ~contextFlags;
            if (contextFlagsToSet) {
                setContextFlag(contextFlagsToSet, /*val*/ true);
                var result = cb(value);
                setContextFlag(contextFlagsToSet, /*val*/ false);
                return result;
            }
            return cb(value);
        }
        function visitDefault(node) {
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 64 /* ContainsES2017 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 126 /* AsyncKeyword */:
                    // ES2017 async modifier should be elided for targets < ES2017
                    return undefined;
                case 206 /* AwaitExpression */:
                    return visitAwaitExpression(node);
                case 161 /* MethodDeclaration */:
                    return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitMethodDeclaration, node);
                case 244 /* FunctionDeclaration */:
                    return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitFunctionDeclaration, node);
                case 201 /* FunctionExpression */:
                    return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitFunctionExpression, node);
                case 202 /* ArrowFunction */:
                    return doWithContext(1 /* NonTopLevel */, visitArrowFunction, node);
                case 194 /* PropertyAccessExpression */:
                    if (capturedSuperProperties && ts.isPropertyAccessExpression(node) && node.expression.kind === 102 /* SuperKeyword */) {
                        capturedSuperProperties.set(node.name.escapedText, true);
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 195 /* ElementAccessExpression */:
                    if (capturedSuperProperties && node.expression.kind === 102 /* SuperKeyword */) {
                        hasSuperElementAccess = true;
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                case 162 /* Constructor */:
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return doWithContext(1 /* NonTopLevel */ | 2 /* HasLexicalThis */, visitDefault, node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function asyncBodyVisitor(node) {
            if (ts.isNodeWithPossibleHoistedDeclaration(node)) {
                switch (node.kind) {
                    case 225 /* VariableStatement */:
                        return visitVariableStatementInAsyncBody(node);
                    case 230 /* ForStatement */:
                        return visitForStatementInAsyncBody(node);
                    case 231 /* ForInStatement */:
                        return visitForInStatementInAsyncBody(node);
                    case 232 /* ForOfStatement */:
                        return visitForOfStatementInAsyncBody(node);
                    case 280 /* CatchClause */:
                        return visitCatchClauseInAsyncBody(node);
                    case 223 /* Block */:
                    case 237 /* SwitchStatement */:
                    case 251 /* CaseBlock */:
                    case 277 /* CaseClause */:
                    case 278 /* DefaultClause */:
                    case 240 /* TryStatement */:
                    case 228 /* DoStatement */:
                    case 229 /* WhileStatement */:
                    case 227 /* IfStatement */:
                    case 236 /* WithStatement */:
                    case 238 /* LabeledStatement */:
                        return ts.visitEachChild(node, asyncBodyVisitor, context);
                    default:
                        return ts.Debug.assertNever(node, "Unhandled node.");
                }
            }
            return visitor(node);
        }
        function visitCatchClauseInAsyncBody(node) {
            var catchClauseNames = ts.createUnderscoreEscapedMap();
            recordDeclarationName(node.variableDeclaration, catchClauseNames); // TODO: GH#18217
            // names declared in a catch variable are block scoped
            var catchClauseUnshadowedNames;
            catchClauseNames.forEach(function (_, escapedName) {
                if (enclosingFunctionParameterNames.has(escapedName)) {
                    if (!catchClauseUnshadowedNames) {
                        catchClauseUnshadowedNames = ts.cloneMap(enclosingFunctionParameterNames);
                    }
                    catchClauseUnshadowedNames.delete(escapedName);
                }
            });
            if (catchClauseUnshadowedNames) {
                var savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
                enclosingFunctionParameterNames = catchClauseUnshadowedNames;
                var result = ts.visitEachChild(node, asyncBodyVisitor, context);
                enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
                return result;
            }
            else {
                return ts.visitEachChild(node, asyncBodyVisitor, context);
            }
        }
        function visitVariableStatementInAsyncBody(node) {
            if (isVariableDeclarationListWithCollidingName(node.declarationList)) {
                var expression = visitVariableDeclarationListWithCollidingNames(node.declarationList, /*hasReceiver*/ false);
                return expression ? ts.createExpressionStatement(expression) : undefined;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForInStatementInAsyncBody(node) {
            return ts.updateForIn(node, isVariableDeclarationListWithCollidingName(node.initializer)
                ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        function visitForOfStatementInAsyncBody(node) {
            return ts.updateForOf(node, ts.visitNode(node.awaitModifier, visitor, ts.isToken), isVariableDeclarationListWithCollidingName(node.initializer)
                ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        function visitForStatementInAsyncBody(node) {
            var initializer = node.initializer; // TODO: GH#18217
            return ts.updateFor(node, isVariableDeclarationListWithCollidingName(initializer)
                ? visitVariableDeclarationListWithCollidingNames(initializer, /*hasReceiver*/ false)
                : ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, asyncBodyVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits an AwaitExpression node.
         *
         * This function will be called any time a ES2017 await expression is encountered.
         *
         * @param node The node to visit.
         */
        function visitAwaitExpression(node) {
            // do not downlevel a top-level await as it is module syntax...
            if (inTopLevelContext()) {
                return ts.visitEachChild(node, visitor, context);
            }
            return ts.setOriginalNode(ts.setTextRange(ts.createYield(
            /*asteriskToken*/ undefined, ts.visitNode(node.expression, visitor, ts.isExpression)), node), node);
        }
        /**
         * Visits a MethodDeclaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked as async
         *
         * @param node The node to visit.
         */
        function visitMethodDeclaration(node) {
            return ts.updateMethod(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*questionToken*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            return ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits a FunctionExpression node.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitFunctionExpression(node) {
            return ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        /**
         * Visits an ArrowFunction.
         *
         * This function will be called when one of the following conditions are met:
         * - The node is marked async
         *
         * @param node The node to visit.
         */
        function visitArrowFunction(node) {
            return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 /* Async */
                ? transformAsyncFunctionBody(node)
                : ts.visitFunctionBody(node.body, visitor, context));
        }
        function recordDeclarationName(_a, names) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                names.set(name.escapedText, true);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element)) {
                        recordDeclarationName(element, names);
                    }
                }
            }
        }
        function isVariableDeclarationListWithCollidingName(node) {
            return !!node
                && ts.isVariableDeclarationList(node)
                && !(node.flags & 3 /* BlockScoped */)
                && node.declarations.some(collidesWithParameterName);
        }
        function visitVariableDeclarationListWithCollidingNames(node, hasReceiver) {
            hoistVariableDeclarationList(node);
            var variables = ts.getInitializedVariables(node);
            if (variables.length === 0) {
                if (hasReceiver) {
                    return ts.visitNode(ts.convertToAssignmentElementTarget(node.declarations[0].name), visitor, ts.isExpression);
                }
                return undefined;
            }
            return ts.inlineExpressions(ts.map(variables, transformInitializedVariable));
        }
        function hoistVariableDeclarationList(node) {
            ts.forEach(node.declarations, hoistVariable);
        }
        function hoistVariable(_a) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                hoistVariableDeclaration(name);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element)) {
                        hoistVariable(element);
                    }
                }
            }
        }
        function transformInitializedVariable(node) {
            var converted = ts.setSourceMapRange(ts.createAssignment(ts.convertToAssignmentElementTarget(node.name), node.initializer), node);
            return ts.visitNode(converted, visitor, ts.isExpression);
        }
        function collidesWithParameterName(_a) {
            var name = _a.name;
            if (ts.isIdentifier(name)) {
                return enclosingFunctionParameterNames.has(name.escapedText);
            }
            else {
                for (var _i = 0, _b = name.elements; _i < _b.length; _i++) {
                    var element = _b[_i];
                    if (!ts.isOmittedExpression(element) && collidesWithParameterName(element)) {
                        return true;
                    }
                }
            }
            return false;
        }
        function transformAsyncFunctionBody(node) {
            resumeLexicalEnvironment();
            var original = ts.getOriginalNode(node, ts.isFunctionLike);
            var nodeType = original.type;
            var promiseConstructor = languageVersion < 2 /* ES2015 */ ? getPromiseConstructor(nodeType) : undefined;
            var isArrowFunction = node.kind === 202 /* ArrowFunction */;
            var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 8192 /* CaptureArguments */) !== 0;
            // An async function is emit as an outer function that calls an inner
            // generator function. To preserve lexical bindings, we pass the current
            // `this` and `arguments` objects to `__awaiter`. The generator function
            // passed to `__awaiter` is executed inside of the callback to the
            // promise constructor.
            var savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames;
            enclosingFunctionParameterNames = ts.createUnderscoreEscapedMap();
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                recordDeclarationName(parameter, enclosingFunctionParameterNames);
            }
            var savedCapturedSuperProperties = capturedSuperProperties;
            var savedHasSuperElementAccess = hasSuperElementAccess;
            if (!isArrowFunction) {
                capturedSuperProperties = ts.createUnderscoreEscapedMap();
                hasSuperElementAccess = false;
            }
            var result;
            if (!isArrowFunction) {
                var statements = [];
                var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
                statements.push(ts.createReturn(createAwaiterHelper(context, inHasLexicalThisContext(), hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body, statementOffset))));
                ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
                // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
                // This step isn't needed if we eventually transform this to ES5.
                var emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && resolver.getNodeCheckFlags(node) & (4096 /* AsyncMethodWithSuperBinding */ | 2048 /* AsyncMethodWithSuper */);
                if (emitSuperHelpers) {
                    enableSubstitutionForAsyncMethodsWithSuper();
                    if (ts.hasEntries(capturedSuperProperties)) {
                        var variableStatement = createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
                        substitutedSuperAccessors[ts.getNodeId(variableStatement)] = true;
                        ts.insertStatementsAfterStandardPrologue(statements, [variableStatement]);
                    }
                }
                var block = ts.createBlock(statements, /*multiLine*/ true);
                ts.setTextRange(block, node.body);
                if (emitSuperHelpers && hasSuperElementAccess) {
                    // Emit helpers for super element access expressions (`super[x]`).
                    if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                        ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
                    }
                    else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                        ts.addEmitHelper(block, ts.asyncSuperHelper);
                    }
                }
                result = block;
            }
            else {
                var expression = createAwaiterHelper(context, inHasLexicalThisContext(), hasLexicalArguments, promiseConstructor, transformAsyncFunctionBodyWorker(node.body));
                var declarations = endLexicalEnvironment();
                if (ts.some(declarations)) {
                    var block = ts.convertToFunctionBody(expression);
                    result = ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(ts.concatenate(declarations, block.statements)), block.statements));
                }
                else {
                    result = expression;
                }
            }
            enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames;
            if (!isArrowFunction) {
                capturedSuperProperties = savedCapturedSuperProperties;
                hasSuperElementAccess = savedHasSuperElementAccess;
            }
            return result;
        }
        function transformAsyncFunctionBodyWorker(body, start) {
            if (ts.isBlock(body)) {
                return ts.updateBlock(body, ts.visitNodes(body.statements, asyncBodyVisitor, ts.isStatement, start));
            }
            else {
                return ts.convertToFunctionBody(ts.visitNode(body, asyncBodyVisitor, ts.isConciseBody));
            }
        }
        function getPromiseConstructor(type) {
            var typeName = type && ts.getEntityNameFromTypeNode(type);
            if (typeName && ts.isEntityName(typeName)) {
                var serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
                if (serializationKind === ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
                    || serializationKind === ts.TypeReferenceSerializationKind.Unknown) {
                    return typeName;
                }
            }
            return undefined;
        }
        function enableSubstitutionForAsyncMethodsWithSuper() {
            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
                // We need to enable substitutions for call, property access, and element access
                // if we need to rewrite super calls.
                context.enableSubstitution(196 /* CallExpression */);
                context.enableSubstitution(194 /* PropertyAccessExpression */);
                context.enableSubstitution(195 /* ElementAccessExpression */);
                // We need to be notified when entering and exiting declarations that bind super.
                context.enableEmitNotification(245 /* ClassDeclaration */);
                context.enableEmitNotification(161 /* MethodDeclaration */);
                context.enableEmitNotification(163 /* GetAccessor */);
                context.enableEmitNotification(164 /* SetAccessor */);
                context.enableEmitNotification(162 /* Constructor */);
                // We need to be notified when entering the generated accessor arrow functions.
                context.enableEmitNotification(225 /* VariableStatement */);
            }
        }
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            // If we need to support substitutions for `super` in an async method,
            // we should track it here.
            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
                if (superContainerFlags !== enclosingSuperContainerFlags) {
                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                    enclosingSuperContainerFlags = superContainerFlags;
                    previousOnEmitNode(hint, node, emitCallback);
                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                    return;
                }
            }
            // Disable substitution in the generated super accessor itself.
            else if (enabledSubstitutions && substitutedSuperAccessors[ts.getNodeId(node)]) {
                var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                enclosingSuperContainerFlags = 0;
                previousOnEmitNode(hint, node, emitCallback);
                enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 195 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
                case 196 /* CallExpression */:
                    return substituteCallExpression(node);
            }
            return node;
        }
        function substitutePropertyAccessExpression(node) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), node.name), node);
            }
            return node;
        }
        function substituteElementAccessExpression(node) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return createSuperElementAccessInAsyncMethod(node.argumentExpression, node);
            }
            return node;
        }
        function substituteCallExpression(node) {
            var expression = node.expression;
            if (ts.isSuperProperty(expression)) {
                var argumentExpression = ts.isPropertyAccessExpression(expression)
                    ? substitutePropertyAccessExpression(expression)
                    : substituteElementAccessExpression(expression);
                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
                /*typeArguments*/ undefined, __spreadArrays([
                    ts.createThis()
                ], node.arguments));
            }
            return node;
        }
        function isSuperContainer(node) {
            var kind = node.kind;
            return kind === 245 /* ClassDeclaration */
                || kind === 162 /* Constructor */
                || kind === 161 /* MethodDeclaration */
                || kind === 163 /* GetAccessor */
                || kind === 164 /* SetAccessor */;
        }
        function createSuperElementAccessInAsyncMethod(argumentExpression, location) {
            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createFileLevelUniqueName("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
            }
            else {
                return ts.setTextRange(ts.createCall(ts.createFileLevelUniqueName("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), location);
            }
        }
    }
    ts.transformES2017 = transformES2017;
    /** Creates a variable named `_super` with accessor properties for the given property names. */
    function createSuperAccessVariableStatement(resolver, node, names) {
        // Create a variable declaration with a getter/setter (if binding) definition for each name:
        //   const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... });
        var hasBinding = (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) !== 0;
        var accessors = [];
        names.forEach(function (_, key) {
            var name = ts.unescapeLeadingUnderscores(key);
            var getterAndSetter = [];
            getterAndSetter.push(ts.createPropertyAssignment("get", ts.createArrowFunction(
            /* modifiers */ undefined, 
            /* typeParameters */ undefined, 
            /* parameters */ [], 
            /* type */ undefined, 
            /* equalsGreaterThanToken */ undefined, ts.setEmitFlags(ts.createPropertyAccess(ts.setEmitFlags(ts.createSuper(), 4 /* NoSubstitution */), name), 4 /* NoSubstitution */))));
            if (hasBinding) {
                getterAndSetter.push(ts.createPropertyAssignment("set", ts.createArrowFunction(
                /* modifiers */ undefined, 
                /* typeParameters */ undefined, 
                /* parameters */ [
                    ts.createParameter(
                    /* decorators */ undefined, 
                    /* modifiers */ undefined, 
                    /* dotDotDotToken */ undefined, "v", 
                    /* questionToken */ undefined, 
                    /* type */ undefined, 
                    /* initializer */ undefined)
                ], 
                /* type */ undefined, 
                /* equalsGreaterThanToken */ undefined, ts.createAssignment(ts.setEmitFlags(ts.createPropertyAccess(ts.setEmitFlags(ts.createSuper(), 4 /* NoSubstitution */), name), 4 /* NoSubstitution */), ts.createIdentifier("v")))));
            }
            accessors.push(ts.createPropertyAssignment(name, ts.createObjectLiteral(getterAndSetter)));
        });
        return ts.createVariableStatement(
        /* modifiers */ undefined, ts.createVariableDeclarationList([
            ts.createVariableDeclaration(ts.createFileLevelUniqueName("_super"), 
            /* type */ undefined, ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "create"), 
            /* typeArguments */ undefined, [
                ts.createNull(),
                ts.createObjectLiteral(accessors, /* multiline */ true)
            ]))
        ], 2 /* Const */));
    }
    ts.createSuperAccessVariableStatement = createSuperAccessVariableStatement;
    ts.awaiterHelper = {
        name: "typescript:awaiter",
        importName: "__awaiter",
        scoped: false,
        priority: 5,
        text: "\n            var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n                function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n                return new (P || (P = Promise))(function (resolve, reject) {\n                    function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n                    function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n                    function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n                    step((generator = generator.apply(thisArg, _arguments || [])).next());\n                });\n            };"
    };
    function createAwaiterHelper(context, hasLexicalThis, hasLexicalArguments, promiseConstructor, body) {
        context.requestEmitHelper(ts.awaiterHelper);
        var generatorFunc = ts.createFunctionExpression(
        /*modifiers*/ undefined, ts.createToken(41 /* AsteriskToken */), 
        /*name*/ undefined, 
        /*typeParameters*/ undefined, 
        /*parameters*/ [], 
        /*type*/ undefined, body);
        // Mark this node as originally an async function
        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */ | 524288 /* ReuseTempVariableScope */;
        return ts.createCall(ts.getUnscopedHelperName("__awaiter"), 
        /*typeArguments*/ undefined, [
            hasLexicalThis ? ts.createThis() : ts.createVoidZero(),
            hasLexicalArguments ? ts.createIdentifier("arguments") : ts.createVoidZero(),
            promiseConstructor ? ts.createExpressionFromEntityName(promiseConstructor) : ts.createVoidZero(),
            generatorFunc
        ]);
    }
    ts.asyncSuperHelper = {
        name: "typescript:async-super",
        scoped: true,
        text: ts.helperString(__makeTemplateObject(["\n            const ", " = name => super[name];"], ["\n            const ", " = name => super[name];"]), "_superIndex")
    };
    ts.advancedAsyncSuperHelper = {
        name: "typescript:advanced-async-super",
        scoped: true,
        text: ts.helperString(__makeTemplateObject(["\n            const ", " = (function (geti, seti) {\n                const cache = Object.create(null);\n                return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n            })(name => super[name], (name, value) => super[name] = value);"], ["\n            const ", " = (function (geti, seti) {\n                const cache = Object.create(null);\n                return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n            })(name => super[name], (name, value) => super[name] = value);"]), "_superIndex")
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ESNextSubstitutionFlags;
    (function (ESNextSubstitutionFlags) {
        /** Enables substitutions for async methods with `super` calls. */
        ESNextSubstitutionFlags[ESNextSubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper";
    })(ESNextSubstitutionFlags || (ESNextSubstitutionFlags = {}));
    // Facts we track as we traverse the tree
    var HierarchyFacts;
    (function (HierarchyFacts) {
        HierarchyFacts[HierarchyFacts["None"] = 0] = "None";
        //
        // Ancestor facts
        //
        HierarchyFacts[HierarchyFacts["HasLexicalThis"] = 1] = "HasLexicalThis";
        HierarchyFacts[HierarchyFacts["IterationContainer"] = 2] = "IterationContainer";
        // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below.
        //
        // Ancestor masks
        //
        HierarchyFacts[HierarchyFacts["AncestorFactsMask"] = 3] = "AncestorFactsMask";
        HierarchyFacts[HierarchyFacts["SourceFileIncludes"] = 1] = "SourceFileIncludes";
        HierarchyFacts[HierarchyFacts["SourceFileExcludes"] = 2] = "SourceFileExcludes";
        HierarchyFacts[HierarchyFacts["StrictModeSourceFileIncludes"] = 0] = "StrictModeSourceFileIncludes";
        HierarchyFacts[HierarchyFacts["ClassOrFunctionIncludes"] = 1] = "ClassOrFunctionIncludes";
        HierarchyFacts[HierarchyFacts["ClassOrFunctionExcludes"] = 2] = "ClassOrFunctionExcludes";
        HierarchyFacts[HierarchyFacts["ArrowFunctionIncludes"] = 0] = "ArrowFunctionIncludes";
        HierarchyFacts[HierarchyFacts["ArrowFunctionExcludes"] = 2] = "ArrowFunctionExcludes";
        HierarchyFacts[HierarchyFacts["IterationStatementIncludes"] = 2] = "IterationStatementIncludes";
        HierarchyFacts[HierarchyFacts["IterationStatementExcludes"] = 0] = "IterationStatementExcludes";
    })(HierarchyFacts || (HierarchyFacts = {}));
    function transformES2018(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var resolver = context.getEmitResolver();
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var previousOnEmitNode = context.onEmitNode;
        context.onEmitNode = onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var exportedVariableStatement = false;
        var enabledSubstitutions;
        var enclosingFunctionFlags;
        var enclosingSuperContainerFlags = 0;
        var hierarchyFacts = 0;
        var currentSourceFile;
        var taggedTemplateStringDeclarations;
        /** Keeps track of property names accessed on super (`super.x`) within async functions. */
        var capturedSuperProperties;
        /** Whether the async function contains an element access on super (`super[x]`). */
        var hasSuperElementAccess;
        /** A set of node IDs for generated super accessors. */
        var substitutedSuperAccessors = [];
        return ts.chainBundle(transformSourceFile);
        function affectsSubtree(excludeFacts, includeFacts) {
            return hierarchyFacts !== (hierarchyFacts & ~excludeFacts | includeFacts);
        }
        /**
         * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification.
         * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree.
         * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree.
         */
        function enterSubtree(excludeFacts, includeFacts) {
            var ancestorFacts = hierarchyFacts;
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 3 /* AncestorFactsMask */;
            return ancestorFacts;
        }
        /**
         * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's
         * subtree.
         * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree.
         */
        function exitSubtree(ancestorFacts) {
            hierarchyFacts = ancestorFacts;
        }
        function recordTaggedTemplateString(temp) {
            taggedTemplateStringDeclarations = ts.append(taggedTemplateStringDeclarations, ts.createVariableDeclaration(temp));
        }
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = visitSourceFile(node);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            taggedTemplateStringDeclarations = undefined;
            return visited;
        }
        function visitor(node) {
            return visitorWorker(node, /*noDestructuringValue*/ false);
        }
        function visitorNoDestructuringValue(node) {
            return visitorWorker(node, /*noDestructuringValue*/ true);
        }
        function visitorNoAsyncModifier(node) {
            if (node.kind === 126 /* AsyncKeyword */) {
                return undefined;
            }
            return node;
        }
        function doWithHierarchyFacts(cb, value, excludeFacts, includeFacts) {
            if (affectsSubtree(excludeFacts, includeFacts)) {
                var ancestorFacts = enterSubtree(excludeFacts, includeFacts);
                var result = cb(value);
                exitSubtree(ancestorFacts);
                return result;
            }
            return cb(value);
        }
        function visitDefault(node) {
            return ts.visitEachChild(node, visitor, context);
        }
        function visitorWorker(node, noDestructuringValue) {
            if ((node.transformFlags & 32 /* ContainsES2018 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 206 /* AwaitExpression */:
                    return visitAwaitExpression(node);
                case 212 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 235 /* ReturnStatement */:
                    return visitReturnStatement(node);
                case 238 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 193 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node, noDestructuringValue);
                case 280 /* CatchClause */:
                    return visitCatchClause(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 242 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                case 231 /* ForInStatement */:
                    return doWithHierarchyFacts(visitDefault, node, 0 /* IterationStatementExcludes */, 2 /* IterationStatementIncludes */);
                case 232 /* ForOfStatement */:
                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
                case 230 /* ForStatement */:
                    return doWithHierarchyFacts(visitForStatement, node, 0 /* IterationStatementExcludes */, 2 /* IterationStatementIncludes */);
                case 205 /* VoidExpression */:
                    return visitVoidExpression(node);
                case 162 /* Constructor */:
                    return doWithHierarchyFacts(visitConstructorDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 161 /* MethodDeclaration */:
                    return doWithHierarchyFacts(visitMethodDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 163 /* GetAccessor */:
                    return doWithHierarchyFacts(visitGetAccessorDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 164 /* SetAccessor */:
                    return doWithHierarchyFacts(visitSetAccessorDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 244 /* FunctionDeclaration */:
                    return doWithHierarchyFacts(visitFunctionDeclaration, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 201 /* FunctionExpression */:
                    return doWithHierarchyFacts(visitFunctionExpression, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                case 202 /* ArrowFunction */:
                    return doWithHierarchyFacts(visitArrowFunction, node, 2 /* ArrowFunctionExcludes */, 0 /* ArrowFunctionIncludes */);
                case 156 /* Parameter */:
                    return visitParameter(node);
                case 226 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 200 /* ParenthesizedExpression */:
                    return visitParenthesizedExpression(node, noDestructuringValue);
                case 198 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 194 /* PropertyAccessExpression */:
                    if (capturedSuperProperties && ts.isPropertyAccessExpression(node) && node.expression.kind === 102 /* SuperKeyword */) {
                        capturedSuperProperties.set(node.name.escapedText, true);
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 195 /* ElementAccessExpression */:
                    if (capturedSuperProperties && node.expression.kind === 102 /* SuperKeyword */) {
                        hasSuperElementAccess = true;
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 245 /* ClassDeclaration */:
                case 214 /* ClassExpression */:
                    return doWithHierarchyFacts(visitDefault, node, 2 /* ClassOrFunctionExcludes */, 1 /* ClassOrFunctionIncludes */);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitAwaitExpression(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.visitNode(node.expression, visitor, ts.isExpression))), 
                /*location*/ node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitYieldExpression(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                if (node.asteriskToken) {
                    var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
                    return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.updateYield(node, node.asteriskToken, createAsyncDelegatorHelper(context, createAsyncValuesHelper(context, expression, expression), expression)))), node), node);
                }
                return ts.setOriginalNode(ts.setTextRange(ts.createYield(createDownlevelAwait(node.expression
                    ? ts.visitNode(node.expression, visitor, ts.isExpression)
                    : ts.createVoidZero())), node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitReturnStatement(node) {
            if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) {
                return ts.updateReturn(node, createDownlevelAwait(node.expression ? ts.visitNode(node.expression, visitor, ts.isExpression) : ts.createVoidZero()));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitLabeledStatement(node) {
            if (enclosingFunctionFlags & 2 /* Async */) {
                var statement = ts.unwrapInnermostStatementOfLabel(node);
                if (statement.kind === 232 /* ForOfStatement */ && statement.awaitModifier) {
                    return visitForOfStatement(statement, node);
                }
                return ts.restoreEnclosingLabel(ts.visitNode(statement, visitor, ts.isStatement, ts.liftToBlock), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function chunkObjectLiteralElements(elements) {
            var chunkObject;
            var objects = [];
            for (var _i = 0, elements_4 = elements; _i < elements_4.length; _i++) {
                var e = elements_4[_i];
                if (e.kind === 283 /* SpreadAssignment */) {
                    if (chunkObject) {
                        objects.push(ts.createObjectLiteral(chunkObject));
                        chunkObject = undefined;
                    }
                    var target = e.expression;
                    objects.push(ts.visitNode(target, visitor, ts.isExpression));
                }
                else {
                    chunkObject = ts.append(chunkObject, e.kind === 281 /* PropertyAssignment */
                        ? ts.createPropertyAssignment(e.name, ts.visitNode(e.initializer, visitor, ts.isExpression))
                        : ts.visitNode(e, visitor, ts.isObjectLiteralElementLike));
                }
            }
            if (chunkObject) {
                objects.push(ts.createObjectLiteral(chunkObject));
            }
            return objects;
        }
        function visitObjectLiteralExpression(node) {
            if (node.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                // spread elements emit like so:
                // non-spread elements are chunked together into object literals, and then all are passed to __assign:
                //     { a, ...o, b } => __assign(__assign({a}, o), {b});
                // If the first element is a spread element, then the first argument to __assign is {}:
                //     { ...o, a, b, ...o2 } => __assign(__assign(__assign({}, o), {a, b}), o2)
                //
                // We cannot call __assign with more than two elements, since any element could cause side effects. For
                // example:
                //      var k = { a: 1, b: 2 };
                //      var o = { a: 3, ...k, b: k.a++ };
                //      // expected: { a: 1, b: 1 }
                // If we translate the above to `__assign({ a: 3 }, k, { b: k.a++ })`, the `k.a++` will evaluate before
                // `k` is spread and we end up with `{ a: 2, b: 1 }`.
                //
                // This also occurs for spread elements, not just property assignments:
                //      var k = { a: 1, get b() { l = { z: 9 }; return 2; } };
                //      var l = { c: 3 };
                //      var o = { ...k, ...l };
                //      // expected: { a: 1, b: 2, z: 9 }
                // If we translate the above to `__assign({}, k, l)`, the `l` will evaluate before `k` is spread and we
                // end up with `{ a: 1, b: 2, c: 3 }`
                var objects = chunkObjectLiteralElements(node.properties);
                if (objects.length && objects[0].kind !== 193 /* ObjectLiteralExpression */) {
                    objects.unshift(ts.createObjectLiteral());
                }
                var expression = objects[0];
                if (objects.length > 1) {
                    for (var i = 1; i < objects.length; i++) {
                        expression = createAssignHelper(context, [expression, objects[i]]);
                    }
                    return expression;
                }
                else {
                    return createAssignHelper(context, objects);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitExpressionStatement(node) {
            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
        }
        function visitParenthesizedExpression(node, noDestructuringValue) {
            return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
        }
        function visitSourceFile(node) {
            var ancestorFacts = enterSubtree(2 /* SourceFileExcludes */, ts.isEffectiveStrictModeSourceFile(node, compilerOptions) ?
                0 /* StrictModeSourceFileIncludes */ :
                1 /* SourceFileIncludes */);
            exportedVariableStatement = false;
            var visited = ts.visitEachChild(node, visitor, context);
            var statement = ts.concatenate(visited.statements, taggedTemplateStringDeclarations && [
                ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(taggedTemplateStringDeclarations))
            ]);
            var result = ts.updateSourceFileNode(visited, ts.setTextRange(ts.createNodeArray(statement), node.statements));
            exitSubtree(ancestorFacts);
            return result;
        }
        function visitTaggedTemplateExpression(node) {
            return ts.processTaggedTemplateExpression(context, node, visitor, currentSourceFile, recordTaggedTemplateString, ts.ProcessLevel.LiftRestriction);
        }
        /**
         * Visits a BinaryExpression that contains a destructuring assignment.
         *
         * @param node A BinaryExpression node.
         */
        function visitBinaryExpression(node, noDestructuringValue) {
            if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 1 /* ObjectRest */, !noDestructuringValue);
            }
            else if (node.operatorToken.kind === 27 /* CommaToken */) {
                return ts.updateBinary(node, ts.visitNode(node.left, visitorNoDestructuringValue, ts.isExpression), ts.visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, ts.isExpression));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCatchClause(node) {
            if (node.variableDeclaration &&
                ts.isBindingPattern(node.variableDeclaration.name) &&
                node.variableDeclaration.name.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                var name = ts.getGeneratedNameForNode(node.variableDeclaration.name);
                var updatedDecl = ts.updateVariableDeclaration(node.variableDeclaration, node.variableDeclaration.name, /*type*/ undefined, name);
                var visitedBindings = ts.flattenDestructuringBinding(updatedDecl, visitor, context, 1 /* ObjectRest */);
                var block = ts.visitNode(node.block, visitor, ts.isBlock);
                if (ts.some(visitedBindings)) {
                    block = ts.updateBlock(block, __spreadArrays([
                        ts.createVariableStatement(/*modifiers*/ undefined, visitedBindings)
                    ], block.statements));
                }
                return ts.updateCatchClause(node, ts.updateVariableDeclaration(node.variableDeclaration, name, /*type*/ undefined, /*initializer*/ undefined), block);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitVariableStatement(node) {
            if (ts.hasModifier(node, 1 /* Export */)) {
                var savedExportedVariableStatement = exportedVariableStatement;
                exportedVariableStatement = true;
                var visited = ts.visitEachChild(node, visitor, context);
                exportedVariableStatement = savedExportedVariableStatement;
                return visited;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a VariableDeclaration node with a binding pattern.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclaration(node) {
            if (exportedVariableStatement) {
                var savedExportedVariableStatement = exportedVariableStatement;
                exportedVariableStatement = false;
                var visited = visitVariableDeclarationWorker(node, /*exportedVariableStatement*/ true);
                exportedVariableStatement = savedExportedVariableStatement;
                return visited;
            }
            return visitVariableDeclarationWorker(node, /*exportedVariableStatement*/ false);
        }
        function visitVariableDeclarationWorker(node, exportedVariableStatement) {
            // If we are here it is because the name contains a binding pattern with a rest somewhere in it.
            if (ts.isBindingPattern(node.name) && node.name.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                return ts.flattenDestructuringBinding(node, visitor, context, 1 /* ObjectRest */, 
                /*rval*/ undefined, exportedVariableStatement);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitForStatement(node) {
            return ts.updateFor(node, ts.visitNode(node.initializer, visitorNoDestructuringValue, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement));
        }
        function visitVoidExpression(node) {
            return ts.visitEachChild(node, visitorNoDestructuringValue, context);
        }
        /**
         * Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement.
         *
         * @param node A ForOfStatement.
         */
        function visitForOfStatement(node, outermostLabeledStatement) {
            var ancestorFacts = enterSubtree(0 /* IterationStatementExcludes */, 2 /* IterationStatementIncludes */);
            if (node.initializer.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                node = transformForOfStatementWithObjectRest(node);
            }
            var result = node.awaitModifier ?
                transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) :
                ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement);
            exitSubtree(ancestorFacts);
            return result;
        }
        function transformForOfStatementWithObjectRest(node) {
            var initializerWithoutParens = ts.skipParentheses(node.initializer);
            if (ts.isVariableDeclarationList(initializerWithoutParens) || ts.isAssignmentPattern(initializerWithoutParens)) {
                var bodyLocation = void 0;
                var statementsLocation = void 0;
                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                var statements = [ts.createForOfBindingStatement(initializerWithoutParens, temp)];
                if (ts.isBlock(node.statement)) {
                    ts.addRange(statements, node.statement.statements);
                    bodyLocation = node.statement;
                    statementsLocation = node.statement.statements;
                }
                else if (node.statement) {
                    ts.append(statements, node.statement);
                    bodyLocation = node.statement;
                    statementsLocation = node.statement;
                }
                return ts.updateForOf(node, node.awaitModifier, ts.setTextRange(ts.createVariableDeclarationList([
                    ts.setTextRange(ts.createVariableDeclaration(temp), node.initializer)
                ], 1 /* Let */), node.initializer), node.expression, ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
                /*multiLine*/ true), bodyLocation));
            }
            return node;
        }
        function convertForOfStatementHead(node, boundValue) {
            var binding = ts.createForOfBindingStatement(node.initializer, boundValue);
            var bodyLocation;
            var statementsLocation;
            var statements = [ts.visitNode(binding, visitor, ts.isStatement)];
            var statement = ts.visitNode(node.statement, visitor, ts.isStatement);
            if (ts.isBlock(statement)) {
                ts.addRange(statements, statement.statements);
                bodyLocation = statement;
                statementsLocation = statement.statements;
            }
            else {
                statements.push(statement);
            }
            return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), 
            /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
        }
        function createDownlevelAwait(expression) {
            return enclosingFunctionFlags & 1 /* Generator */
                ? ts.createYield(/*asteriskToken*/ undefined, createAwaitHelper(context, expression))
                : ts.createAwait(expression);
        }
        function transformForAwaitOfStatement(node, outermostLabeledStatement, ancestorFacts) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var errorRecord = ts.createUniqueName("e");
            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
            var callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
            var callNext = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
            var getDone = ts.createPropertyAccess(result, "done");
            var getValue = ts.createPropertyAccess(result, "value");
            var callReturn = ts.createFunctionCall(returnMethod, iterator, []);
            hoistVariableDeclaration(errorRecord);
            hoistVariableDeclaration(returnMethod);
            // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration
            var initializer = ancestorFacts & 2 /* IterationContainer */ ?
                ts.inlineExpressions([ts.createAssignment(errorRecord, ts.createVoidZero()), callValues]) :
                callValues;
            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression),
                ts.createVariableDeclaration(result)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.createComma(ts.createAssignment(result, createDownlevelAwait(callNext)), ts.createLogicalNot(getDone)), 
            /*incrementor*/ undefined, 
            /*statement*/ convertForOfStatementHead(node, getValue)), 
            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
            return ts.createTry(ts.createBlock([
                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement)
            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
                ts.createExpressionStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
                    ts.createPropertyAssignment("error", catchVariable)
                ])))
            ]), 1 /* SingleLine */)), ts.createBlock([
                ts.createTry(
                /*tryBlock*/ ts.createBlock([
                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(getDone)), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createExpressionStatement(createDownlevelAwait(callReturn))), 1 /* SingleLine */)
                ]), 
                /*catchClause*/ undefined, 
                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
                ]), 1 /* SingleLine */))
            ]));
        }
        function visitParameter(node) {
            if (node.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                // Binding patterns are converted into a generated name and are
                // evaluated inside the function body.
                return ts.updateParameter(node, 
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, node.dotDotDotToken, ts.getGeneratedNameForNode(node), 
                /*questionToken*/ undefined, 
                /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitConstructorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateConstructor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitGetAccessorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateGetAccessor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitSetAccessorDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = 0 /* Normal */;
            var updated = ts.updateSetAccessor(node, 
            /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitMethodDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateMethod(node, 
            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitNode(/*questionToken*/ undefined, visitor, ts.isToken), 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitFunctionDeclaration(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitArrowFunction(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateArrowFunction(node, node.modifiers, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, node.equalsGreaterThanToken, transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function visitFunctionExpression(node) {
            var savedEnclosingFunctionFlags = enclosingFunctionFlags;
            enclosingFunctionFlags = ts.getFunctionFlags(node);
            var updated = ts.updateFunctionExpression(node, enclosingFunctionFlags & 1 /* Generator */
                ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier)
                : node.modifiers, enclosingFunctionFlags & 2 /* Async */
                ? undefined
                : node.asteriskToken, node.name, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */
                ? transformAsyncGeneratorFunctionBody(node)
                : transformFunctionBody(node));
            enclosingFunctionFlags = savedEnclosingFunctionFlags;
            return updated;
        }
        function transformAsyncGeneratorFunctionBody(node) {
            resumeLexicalEnvironment();
            var statements = [];
            var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
            appendObjectRestAssignmentsIfNeeded(statements, node);
            var savedCapturedSuperProperties = capturedSuperProperties;
            var savedHasSuperElementAccess = hasSuperElementAccess;
            capturedSuperProperties = ts.createUnderscoreEscapedMap();
            hasSuperElementAccess = false;
            var returnStatement = ts.createReturn(createAsyncGeneratorHelper(context, ts.createFunctionExpression(
            /*modifiers*/ undefined, ts.createToken(41 /* AsteriskToken */), node.name && ts.getGeneratedNameForNode(node.name), 
            /*typeParameters*/ undefined, 
            /*parameters*/ [], 
            /*type*/ undefined, ts.updateBlock(node.body, ts.visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset))), !!(hierarchyFacts & 1 /* HasLexicalThis */)));
            // Minor optimization, emit `_super` helper to capture `super` access in an arrow.
            // This step isn't needed if we eventually transform this to ES5.
            var emitSuperHelpers = languageVersion >= 2 /* ES2015 */ && resolver.getNodeCheckFlags(node) & (4096 /* AsyncMethodWithSuperBinding */ | 2048 /* AsyncMethodWithSuper */);
            if (emitSuperHelpers) {
                enableSubstitutionForAsyncMethodsWithSuper();
                var variableStatement = ts.createSuperAccessVariableStatement(resolver, node, capturedSuperProperties);
                substitutedSuperAccessors[ts.getNodeId(variableStatement)] = true;
                ts.insertStatementsAfterStandardPrologue(statements, [variableStatement]);
            }
            statements.push(returnStatement);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var block = ts.updateBlock(node.body, statements);
            if (emitSuperHelpers && hasSuperElementAccess) {
                if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) {
                    ts.addEmitHelper(block, ts.advancedAsyncSuperHelper);
                }
                else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) {
                    ts.addEmitHelper(block, ts.asyncSuperHelper);
                }
            }
            capturedSuperProperties = savedCapturedSuperProperties;
            hasSuperElementAccess = savedHasSuperElementAccess;
            return block;
        }
        function transformFunctionBody(node) {
            resumeLexicalEnvironment();
            var statementOffset = 0;
            var statements = [];
            var body = ts.visitNode(node.body, visitor, ts.isConciseBody);
            if (ts.isBlock(body)) {
                statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
            }
            ts.addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node));
            var leadingStatements = endLexicalEnvironment();
            if (statementOffset > 0 || ts.some(statements) || ts.some(leadingStatements)) {
                var block = ts.convertToFunctionBody(body, /*multiLine*/ true);
                ts.insertStatementsAfterStandardPrologue(statements, leadingStatements);
                ts.addRange(statements, block.statements.slice(statementOffset));
                return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(statements), block.statements));
            }
            return body;
        }
        function appendObjectRestAssignmentsIfNeeded(statements, node) {
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                if (parameter.transformFlags & 16384 /* ContainsObjectRestOrSpread */) {
                    var temp = ts.getGeneratedNameForNode(parameter);
                    var declarations = ts.flattenDestructuringBinding(parameter, visitor, context, 1 /* ObjectRest */, temp, 
                    /*doNotRecordTempVariablesInLine*/ false, 
                    /*skipInitializer*/ true);
                    if (ts.some(declarations)) {
                        var statement = ts.createVariableStatement(
                        /*modifiers*/ undefined, ts.createVariableDeclarationList(declarations));
                        ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
                        statements = ts.append(statements, statement);
                    }
                }
            }
            return statements;
        }
        function enableSubstitutionForAsyncMethodsWithSuper() {
            if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) {
                enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */;
                // We need to enable substitutions for call, property access, and element access
                // if we need to rewrite super calls.
                context.enableSubstitution(196 /* CallExpression */);
                context.enableSubstitution(194 /* PropertyAccessExpression */);
                context.enableSubstitution(195 /* ElementAccessExpression */);
                // We need to be notified when entering and exiting declarations that bind super.
                context.enableEmitNotification(245 /* ClassDeclaration */);
                context.enableEmitNotification(161 /* MethodDeclaration */);
                context.enableEmitNotification(163 /* GetAccessor */);
                context.enableEmitNotification(164 /* SetAccessor */);
                context.enableEmitNotification(162 /* Constructor */);
                // We need to be notified when entering the generated accessor arrow functions.
                context.enableEmitNotification(225 /* VariableStatement */);
            }
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to be printed.
         * @param emitCallback The callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            // If we need to support substitutions for `super` in an async method,
            // we should track it here.
            if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) {
                var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */);
                if (superContainerFlags !== enclosingSuperContainerFlags) {
                    var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                    enclosingSuperContainerFlags = superContainerFlags;
                    previousOnEmitNode(hint, node, emitCallback);
                    enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                    return;
                }
            }
            // Disable substitution in the generated super accessor itself.
            else if (enabledSubstitutions && substitutedSuperAccessors[ts.getNodeId(node)]) {
                var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
                enclosingSuperContainerFlags = 0;
                previousOnEmitNode(hint, node, emitCallback);
                enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                    return substitutePropertyAccessExpression(node);
                case 195 /* ElementAccessExpression */:
                    return substituteElementAccessExpression(node);
                case 196 /* CallExpression */:
                    return substituteCallExpression(node);
            }
            return node;
        }
        function substitutePropertyAccessExpression(node) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), node.name), node);
            }
            return node;
        }
        function substituteElementAccessExpression(node) {
            if (node.expression.kind === 102 /* SuperKeyword */) {
                return createSuperElementAccessInAsyncMethod(node.argumentExpression, node);
            }
            return node;
        }
        function substituteCallExpression(node) {
            var expression = node.expression;
            if (ts.isSuperProperty(expression)) {
                var argumentExpression = ts.isPropertyAccessExpression(expression)
                    ? substitutePropertyAccessExpression(expression)
                    : substituteElementAccessExpression(expression);
                return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), 
                /*typeArguments*/ undefined, __spreadArrays([
                    ts.createThis()
                ], node.arguments));
            }
            return node;
        }
        function isSuperContainer(node) {
            var kind = node.kind;
            return kind === 245 /* ClassDeclaration */
                || kind === 162 /* Constructor */
                || kind === 161 /* MethodDeclaration */
                || kind === 163 /* GetAccessor */
                || kind === 164 /* SetAccessor */;
        }
        function createSuperElementAccessInAsyncMethod(argumentExpression, location) {
            if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) {
                return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), "value"), location);
            }
            else {
                return ts.setTextRange(ts.createCall(ts.createIdentifier("_superIndex"), 
                /*typeArguments*/ undefined, [argumentExpression]), location);
            }
        }
    }
    ts.transformES2018 = transformES2018;
    ts.assignHelper = {
        name: "typescript:assign",
        importName: "__assign",
        scoped: false,
        priority: 1,
        text: "\n            var __assign = (this && this.__assign) || function () {\n                __assign = Object.assign || function(t) {\n                    for (var s, i = 1, n = arguments.length; i < n; i++) {\n                        s = arguments[i];\n                        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n                            t[p] = s[p];\n                    }\n                    return t;\n                };\n                return __assign.apply(this, arguments);\n            };"
    };
    function createAssignHelper(context, attributesSegments) {
        if (context.getCompilerOptions().target >= 2 /* ES2015 */) {
            return ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "assign"), /*typeArguments*/ undefined, attributesSegments);
        }
        context.requestEmitHelper(ts.assignHelper);
        return ts.createCall(ts.getUnscopedHelperName("__assign"), 
        /*typeArguments*/ undefined, attributesSegments);
    }
    ts.createAssignHelper = createAssignHelper;
    ts.awaitHelper = {
        name: "typescript:await",
        importName: "__await",
        scoped: false,
        text: "\n            var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }"
    };
    function createAwaitHelper(context, expression) {
        context.requestEmitHelper(ts.awaitHelper);
        return ts.createCall(ts.getUnscopedHelperName("__await"), /*typeArguments*/ undefined, [expression]);
    }
    ts.asyncGeneratorHelper = {
        name: "typescript:asyncGenerator",
        importName: "__asyncGenerator",
        scoped: false,
        dependencies: [ts.awaitHelper],
        text: "\n            var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var g = generator.apply(thisArg, _arguments || []), i, q = [];\n                return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n                function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n                function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n                function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n                function fulfill(value) { resume(\"next\", value); }\n                function reject(value) { resume(\"throw\", value); }\n                function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n            };"
    };
    function createAsyncGeneratorHelper(context, generatorFunc, hasLexicalThis) {
        context.requestEmitHelper(ts.asyncGeneratorHelper);
        // Mark this node as originally an async function
        (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */ | 524288 /* ReuseTempVariableScope */;
        return ts.createCall(ts.getUnscopedHelperName("__asyncGenerator"), 
        /*typeArguments*/ undefined, [
            hasLexicalThis ? ts.createThis() : ts.createVoidZero(),
            ts.createIdentifier("arguments"),
            generatorFunc
        ]);
    }
    ts.asyncDelegator = {
        name: "typescript:asyncDelegator",
        importName: "__asyncDelegator",
        scoped: false,
        dependencies: [ts.awaitHelper],
        text: "\n            var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {\n                var i, p;\n                return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n                function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\n            };"
    };
    function createAsyncDelegatorHelper(context, expression, location) {
        context.requestEmitHelper(ts.asyncDelegator);
        return ts.setTextRange(ts.createCall(ts.getUnscopedHelperName("__asyncDelegator"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
    ts.asyncValues = {
        name: "typescript:asyncValues",
        importName: "__asyncValues",
        scoped: false,
        text: "\n            var __asyncValues = (this && this.__asyncValues) || function (o) {\n                if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n                var m = o[Symbol.asyncIterator], i;\n                return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n                function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n                function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n            };"
    };
    function createAsyncValuesHelper(context, expression, location) {
        context.requestEmitHelper(ts.asyncValues);
        return ts.setTextRange(ts.createCall(ts.getUnscopedHelperName("__asyncValues"), 
        /*typeArguments*/ undefined, [expression]), location);
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2019(context) {
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 16 /* ContainsES2019 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 280 /* CatchClause */:
                    return visitCatchClause(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitCatchClause(node) {
            if (!node.variableDeclaration) {
                return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(/*recordTempVariable*/ undefined)), ts.visitNode(node.block, visitor, ts.isBlock));
            }
            return ts.visitEachChild(node, visitor, context);
        }
    }
    ts.transformES2019 = transformES2019;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2020(context) {
        var hoistVariableDeclaration = context.hoistVariableDeclaration;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 8 /* ContainsES2020 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */:
                case 196 /* CallExpression */:
                    if (node.flags & 32 /* OptionalChain */) {
                        var updated = visitOptionalExpression(node, /*captureThisArg*/ false, /*isDelete*/ false);
                        ts.Debug.assertNotNode(updated, ts.isSyntheticReference);
                        return updated;
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 209 /* BinaryExpression */:
                    if (node.operatorToken.kind === 60 /* QuestionQuestionToken */) {
                        return transformNullishCoalescingExpression(node);
                    }
                    return ts.visitEachChild(node, visitor, context);
                case 203 /* DeleteExpression */:
                    return visitDeleteExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function flattenChain(chain) {
            ts.Debug.assertNotNode(chain, ts.isNonNullChain);
            var links = [chain];
            while (!chain.questionDotToken && !ts.isTaggedTemplateExpression(chain)) {
                chain = ts.cast(ts.skipPartiallyEmittedExpressions(chain.expression), ts.isOptionalChain);
                ts.Debug.assertNotNode(chain, ts.isNonNullChain);
                links.unshift(chain);
            }
            return { expression: chain.expression, chain: links };
        }
        function visitNonOptionalParenthesizedExpression(node, captureThisArg, isDelete) {
            var expression = visitNonOptionalExpression(node.expression, captureThisArg, isDelete);
            if (ts.isSyntheticReference(expression)) {
                // `(a.b)` -> { expression `((_a = a).b)`, thisArg: `_a` }
                // `(a[b])` -> { expression `((_a = a)[b])`, thisArg: `_a` }
                return ts.createSyntheticReferenceExpression(ts.updateParen(node, expression.expression), expression.thisArg);
            }
            return ts.updateParen(node, expression);
        }
        function visitNonOptionalPropertyOrElementAccessExpression(node, captureThisArg, isDelete) {
            if (ts.isOptionalChain(node)) {
                // If `node` is an optional chain, then it is the outermost chain of an optional expression.
                return visitOptionalExpression(node, captureThisArg, isDelete);
            }
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            ts.Debug.assertNotNode(expression, ts.isSyntheticReference);
            var thisArg;
            if (captureThisArg) {
                if (shouldCaptureInTempVariable(expression)) {
                    thisArg = ts.createTempVariable(hoistVariableDeclaration);
                    expression = ts.createAssignment(thisArg, expression);
                    // if (inParameterInitializer) tempVariableInParameter = true;
                }
                else {
                    thisArg = expression;
                }
            }
            expression = node.kind === 194 /* PropertyAccessExpression */
                ? ts.updatePropertyAccess(node, expression, ts.visitNode(node.name, visitor, ts.isIdentifier))
                : ts.updateElementAccess(node, expression, ts.visitNode(node.argumentExpression, visitor, ts.isExpression));
            return thisArg ? ts.createSyntheticReferenceExpression(expression, thisArg) : expression;
        }
        function visitNonOptionalCallExpression(node, captureThisArg) {
            if (ts.isOptionalChain(node)) {
                // If `node` is an optional chain, then it is the outermost chain of an optional expression.
                return visitOptionalExpression(node, captureThisArg, /*isDelete*/ false);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitNonOptionalExpression(node, captureThisArg, isDelete) {
            switch (node.kind) {
                case 200 /* ParenthesizedExpression */: return visitNonOptionalParenthesizedExpression(node, captureThisArg, isDelete);
                case 194 /* PropertyAccessExpression */:
                case 195 /* ElementAccessExpression */: return visitNonOptionalPropertyOrElementAccessExpression(node, captureThisArg, isDelete);
                case 196 /* CallExpression */: return visitNonOptionalCallExpression(node, captureThisArg);
                default: return ts.visitNode(node, visitor, ts.isExpression);
            }
        }
        function visitOptionalExpression(node, captureThisArg, isDelete) {
            var _a = flattenChain(node), expression = _a.expression, chain = _a.chain;
            var left = visitNonOptionalExpression(expression, ts.isCallChain(chain[0]), /*isDelete*/ false);
            var leftThisArg = ts.isSyntheticReference(left) ? left.thisArg : undefined;
            var leftExpression = ts.isSyntheticReference(left) ? left.expression : left;
            var capturedLeft = leftExpression;
            if (shouldCaptureInTempVariable(leftExpression)) {
                capturedLeft = ts.createTempVariable(hoistVariableDeclaration);
                leftExpression = ts.createAssignment(capturedLeft, leftExpression);
                // if (inParameterInitializer) tempVariableInParameter = true;
            }
            var rightExpression = capturedLeft;
            var thisArg;
            for (var i = 0; i < chain.length; i++) {
                var segment = chain[i];
                switch (segment.kind) {
                    case 194 /* PropertyAccessExpression */:
                    case 195 /* ElementAccessExpression */:
                        if (i === chain.length - 1 && captureThisArg) {
                            if (shouldCaptureInTempVariable(rightExpression)) {
                                thisArg = ts.createTempVariable(hoistVariableDeclaration);
                                rightExpression = ts.createAssignment(thisArg, rightExpression);
                                // if (inParameterInitializer) tempVariableInParameter = true;
                            }
                            else {
                                thisArg = rightExpression;
                            }
                        }
                        rightExpression = segment.kind === 194 /* PropertyAccessExpression */
                            ? ts.createPropertyAccess(rightExpression, ts.visitNode(segment.name, visitor, ts.isIdentifier))
                            : ts.createElementAccess(rightExpression, ts.visitNode(segment.argumentExpression, visitor, ts.isExpression));
                        break;
                    case 196 /* CallExpression */:
                        if (i === 0 && leftThisArg) {
                            rightExpression = ts.createFunctionCall(rightExpression, leftThisArg.kind === 102 /* SuperKeyword */ ? ts.createThis() : leftThisArg, ts.visitNodes(segment.arguments, visitor, ts.isExpression));
                        }
                        else {
                            rightExpression = ts.createCall(rightExpression, 
                            /*typeArguments*/ undefined, ts.visitNodes(segment.arguments, visitor, ts.isExpression));
                        }
                        break;
                }
                ts.setOriginalNode(rightExpression, segment);
            }
            var target = isDelete
                ? ts.createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), ts.createTrue(), ts.createDelete(rightExpression))
                : ts.createConditional(createNotNullCondition(leftExpression, capturedLeft, /*invert*/ true), ts.createVoidZero(), rightExpression);
            return thisArg ? ts.createSyntheticReferenceExpression(target, thisArg) : target;
        }
        function createNotNullCondition(left, right, invert) {
            return ts.createBinary(ts.createBinary(left, ts.createToken(invert ? 36 /* EqualsEqualsEqualsToken */ : 37 /* ExclamationEqualsEqualsToken */), ts.createNull()), ts.createToken(invert ? 56 /* BarBarToken */ : 55 /* AmpersandAmpersandToken */), ts.createBinary(right, ts.createToken(invert ? 36 /* EqualsEqualsEqualsToken */ : 37 /* ExclamationEqualsEqualsToken */), ts.createVoidZero()));
        }
        function transformNullishCoalescingExpression(node) {
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = left;
            if (shouldCaptureInTempVariable(left)) {
                right = ts.createTempVariable(hoistVariableDeclaration);
                left = ts.createAssignment(right, left);
                // if (inParameterInitializer) tempVariableInParameter = true;
            }
            return ts.createConditional(createNotNullCondition(left, right), right, ts.visitNode(node.right, visitor, ts.isExpression));
        }
        function shouldCaptureInTempVariable(expression) {
            // don't capture identifiers and `this` in a temporary variable
            // `super` cannot be captured as it's no real variable
            return !ts.isIdentifier(expression) &&
                expression.kind !== 104 /* ThisKeyword */ &&
                expression.kind !== 102 /* SuperKeyword */;
        }
        function visitDeleteExpression(node) {
            return ts.isOptionalChain(ts.skipParentheses(node.expression))
                ? ts.setOriginalNode(visitNonOptionalExpression(node.expression, /*captureThisArg*/ false, /*isDelete*/ true), node)
                : ts.updateDelete(node, ts.visitNode(node.expression, visitor, ts.isExpression));
        }
    }
    ts.transformES2020 = transformES2020;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformESNext(context) {
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 4 /* ContainsESNext */) === 0) {
                return node;
            }
            switch (node.kind) {
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
    }
    ts.transformESNext = transformESNext;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformJsx(context) {
        var compilerOptions = context.getCompilerOptions();
        var currentSourceFile;
        return ts.chainBundle(transformSourceFile);
        /**
         * Transform JSX-specific syntax in a SourceFile.
         *
         * @param node A SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        function visitor(node) {
            if (node.transformFlags & 2 /* ContainsJsx */) {
                return visitorWorker(node);
            }
            else {
                return node;
            }
        }
        function visitorWorker(node) {
            switch (node.kind) {
                case 266 /* JsxElement */:
                    return visitJsxElement(node, /*isChild*/ false);
                case 267 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node, /*isChild*/ false);
                case 270 /* JsxFragment */:
                    return visitJsxFragment(node, /*isChild*/ false);
                case 276 /* JsxExpression */:
                    return visitJsxExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformJsxChildToExpression(node) {
            switch (node.kind) {
                case 11 /* JsxText */:
                    return visitJsxText(node);
                case 276 /* JsxExpression */:
                    return visitJsxExpression(node);
                case 266 /* JsxElement */:
                    return visitJsxElement(node, /*isChild*/ true);
                case 267 /* JsxSelfClosingElement */:
                    return visitJsxSelfClosingElement(node, /*isChild*/ true);
                case 270 /* JsxFragment */:
                    return visitJsxFragment(node, /*isChild*/ true);
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function visitJsxElement(node, isChild) {
            return visitJsxOpeningLikeElement(node.openingElement, node.children, isChild, /*location*/ node);
        }
        function visitJsxSelfClosingElement(node, isChild) {
            return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
        }
        function visitJsxFragment(node, isChild) {
            return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node);
        }
        function visitJsxOpeningLikeElement(node, children, isChild, location) {
            var tagName = getTagName(node);
            var objectProperties;
            var attrs = node.attributes.properties;
            if (attrs.length === 0) {
                // When there are no attributes, React wants "null"
                objectProperties = ts.createNull();
            }
            else {
                // Map spans of JsxAttribute nodes into object literals and spans
                // of JsxSpreadAttribute nodes into expressions.
                var segments = ts.flatten(ts.spanMap(attrs, ts.isJsxSpreadAttribute, function (attrs, isSpread) { return isSpread
                    ? ts.map(attrs, transformJsxSpreadAttributeToExpression)
                    : ts.createObjectLiteral(ts.map(attrs, transformJsxAttributeToObjectLiteralElement)); }));
                if (ts.isJsxSpreadAttribute(attrs[0])) {
                    // We must always emit at least one object literal before a spread
                    // argument.
                    segments.unshift(ts.createObjectLiteral());
                }
                // Either emit one big object literal (no spread attribs), or
                // a call to the __assign helper.
                objectProperties = ts.singleOrUndefined(segments);
                if (!objectProperties) {
                    objectProperties = ts.createAssignHelper(context, segments);
                }
            }
            var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(currentSourceFile), compilerOptions.reactNamespace, // TODO: GH#18217
            tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location);
            if (isChild) {
                ts.startOnNewLine(element);
            }
            return element;
        }
        function visitJsxOpeningFragment(node, children, isChild, location) {
            var element = ts.createExpressionForJsxFragment(context.getEmitResolver().getJsxFactoryEntity(currentSourceFile), compilerOptions.reactNamespace, // TODO: GH#18217
            ts.mapDefined(children, transformJsxChildToExpression), node, location);
            if (isChild) {
                ts.startOnNewLine(element);
            }
            return element;
        }
        function transformJsxSpreadAttributeToExpression(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        function transformJsxAttributeToObjectLiteralElement(node) {
            var name = getAttributeName(node);
            var expression = transformJsxAttributeInitializer(node.initializer);
            return ts.createPropertyAssignment(name, expression);
        }
        function transformJsxAttributeInitializer(node) {
            if (node === undefined) {
                return ts.createTrue();
            }
            else if (node.kind === 10 /* StringLiteral */) {
                // Always recreate the literal to escape any escape sequences or newlines which may be in the original jsx string and which
                // Need to be escaped to be handled correctly in a normal string
                var literal = ts.createLiteral(tryDecodeEntities(node.text) || node.text);
                literal.singleQuote = node.singleQuote !== undefined ? node.singleQuote : !ts.isStringDoubleQuoted(node, currentSourceFile);
                return ts.setTextRange(literal, node);
            }
            else if (node.kind === 276 /* JsxExpression */) {
                if (node.expression === undefined) {
                    return ts.createTrue();
                }
                return visitJsxExpression(node);
            }
            else {
                return ts.Debug.failBadSyntaxKind(node);
            }
        }
        function visitJsxText(node) {
            var fixed = fixupWhitespaceAndDecodeEntities(node.text);
            return fixed === undefined ? undefined : ts.createLiteral(fixed);
        }
        /**
         * JSX trims whitespace at the end and beginning of lines, except that the
         * start/end of a tag is considered a start/end of a line only if that line is
         * on the same line as the closing tag. See examples in
         * tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
         * See also https://www.w3.org/TR/html4/struct/text.html#h-9.1 and https://www.w3.org/TR/CSS2/text.html#white-space-model
         *
         * An equivalent algorithm would be:
         * - If there is only one line, return it.
         * - If there is only whitespace (but multiple lines), return `undefined`.
         * - Split the text into lines.
         * - 'trimRight' the first line, 'trimLeft' the last line, 'trim' middle lines.
         * - Decode entities on each line (individually).
         * - Remove empty lines and join the rest with " ".
         */
        function fixupWhitespaceAndDecodeEntities(text) {
            var acc;
            // First non-whitespace character on this line.
            var firstNonWhitespace = 0;
            // Last non-whitespace character on this line.
            var lastNonWhitespace = -1;
            // These initial values are special because the first line is:
            // firstNonWhitespace = 0 to indicate that we want leading whitsepace,
            // but lastNonWhitespace = -1 as a special flag to indicate that we *don't* include the line if it's all whitespace.
            for (var i = 0; i < text.length; i++) {
                var c = text.charCodeAt(i);
                if (ts.isLineBreak(c)) {
                    // If we've seen any non-whitespace characters on this line, add the 'trim' of the line.
                    // (lastNonWhitespace === -1 is a special flag to detect whether the first line is all whitespace.)
                    if (firstNonWhitespace !== -1 && lastNonWhitespace !== -1) {
                        acc = addLineOfJsxText(acc, text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1));
                    }
                    // Reset firstNonWhitespace for the next line.
                    // Don't bother to reset lastNonWhitespace because we ignore it if firstNonWhitespace = -1.
                    firstNonWhitespace = -1;
                }
                else if (!ts.isWhiteSpaceSingleLine(c)) {
                    lastNonWhitespace = i;
                    if (firstNonWhitespace === -1) {
                        firstNonWhitespace = i;
                    }
                }
            }
            return firstNonWhitespace !== -1
                // Last line had a non-whitespace character. Emit the 'trimLeft', meaning keep trailing whitespace.
                ? addLineOfJsxText(acc, text.substr(firstNonWhitespace))
                // Last line was all whitespace, so ignore it
                : acc;
        }
        function addLineOfJsxText(acc, trimmedLine) {
            // We do not escape the string here as that is handled by the printer
            // when it emits the literal. We do, however, need to decode JSX entities.
            var decoded = decodeEntities(trimmedLine);
            return acc === undefined ? decoded : acc + " " + decoded;
        }
        /**
         * Replace entities like "&nbsp;", "&#123;", and "&#xDEADBEEF;" with the characters they encode.
         * See https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
         */
        function decodeEntities(text) {
            return text.replace(/&((#((\d+)|x([\da-fA-F]+)))|(\w+));/g, function (match, _all, _number, _digits, decimal, hex, word) {
                if (decimal) {
                    return ts.utf16EncodeAsString(parseInt(decimal, 10));
                }
                else if (hex) {
                    return ts.utf16EncodeAsString(parseInt(hex, 16));
                }
                else {
                    var ch = entities.get(word);
                    // If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace)
                    return ch ? ts.utf16EncodeAsString(ch) : match;
                }
            });
        }
        /** Like `decodeEntities` but returns `undefined` if there were no entities to decode. */
        function tryDecodeEntities(text) {
            var decoded = decodeEntities(text);
            return decoded === text ? undefined : decoded;
        }
        function getTagName(node) {
            if (node.kind === 266 /* JsxElement */) {
                return getTagName(node.openingElement);
            }
            else {
                var name = node.tagName;
                if (ts.isIdentifier(name) && ts.isIntrinsicJsxName(name.escapedText)) {
                    return ts.createLiteral(ts.idText(name));
                }
                else {
                    return ts.createExpressionFromEntityName(name);
                }
            }
        }
        /**
         * Emit an attribute name, which is quoted if it needs to be quoted. Because
         * these emit into an object literal property name, we don't need to be worried
         * about keywords, just non-identifier characters
         */
        function getAttributeName(node) {
            var name = node.name;
            var text = ts.idText(name);
            if (/^[A-Za-z_]\w*$/.test(text)) {
                return name;
            }
            else {
                return ts.createLiteral(text);
            }
        }
        function visitJsxExpression(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
    }
    ts.transformJsx = transformJsx;
    var entities = ts.createMapFromTemplate({
        quot: 0x0022,
        amp: 0x0026,
        apos: 0x0027,
        lt: 0x003C,
        gt: 0x003E,
        nbsp: 0x00A0,
        iexcl: 0x00A1,
        cent: 0x00A2,
        pound: 0x00A3,
        curren: 0x00A4,
        yen: 0x00A5,
        brvbar: 0x00A6,
        sect: 0x00A7,
        uml: 0x00A8,
        copy: 0x00A9,
        ordf: 0x00AA,
        laquo: 0x00AB,
        not: 0x00AC,
        shy: 0x00AD,
        reg: 0x00AE,
        macr: 0x00AF,
        deg: 0x00B0,
        plusmn: 0x00B1,
        sup2: 0x00B2,
        sup3: 0x00B3,
        acute: 0x00B4,
        micro: 0x00B5,
        para: 0x00B6,
        middot: 0x00B7,
        cedil: 0x00B8,
        sup1: 0x00B9,
        ordm: 0x00BA,
        raquo: 0x00BB,
        frac14: 0x00BC,
        frac12: 0x00BD,
        frac34: 0x00BE,
        iquest: 0x00BF,
        Agrave: 0x00C0,
        Aacute: 0x00C1,
        Acirc: 0x00C2,
        Atilde: 0x00C3,
        Auml: 0x00C4,
        Aring: 0x00C5,
        AElig: 0x00C6,
        Ccedil: 0x00C7,
        Egrave: 0x00C8,
        Eacute: 0x00C9,
        Ecirc: 0x00CA,
        Euml: 0x00CB,
        Igrave: 0x00CC,
        Iacute: 0x00CD,
        Icirc: 0x00CE,
        Iuml: 0x00CF,
        ETH: 0x00D0,
        Ntilde: 0x00D1,
        Ograve: 0x00D2,
        Oacute: 0x00D3,
        Ocirc: 0x00D4,
        Otilde: 0x00D5,
        Ouml: 0x00D6,
        times: 0x00D7,
        Oslash: 0x00D8,
        Ugrave: 0x00D9,
        Uacute: 0x00DA,
        Ucirc: 0x00DB,
        Uuml: 0x00DC,
        Yacute: 0x00DD,
        THORN: 0x00DE,
        szlig: 0x00DF,
        agrave: 0x00E0,
        aacute: 0x00E1,
        acirc: 0x00E2,
        atilde: 0x00E3,
        auml: 0x00E4,
        aring: 0x00E5,
        aelig: 0x00E6,
        ccedil: 0x00E7,
        egrave: 0x00E8,
        eacute: 0x00E9,
        ecirc: 0x00EA,
        euml: 0x00EB,
        igrave: 0x00EC,
        iacute: 0x00ED,
        icirc: 0x00EE,
        iuml: 0x00EF,
        eth: 0x00F0,
        ntilde: 0x00F1,
        ograve: 0x00F2,
        oacute: 0x00F3,
        ocirc: 0x00F4,
        otilde: 0x00F5,
        ouml: 0x00F6,
        divide: 0x00F7,
        oslash: 0x00F8,
        ugrave: 0x00F9,
        uacute: 0x00FA,
        ucirc: 0x00FB,
        uuml: 0x00FC,
        yacute: 0x00FD,
        thorn: 0x00FE,
        yuml: 0x00FF,
        OElig: 0x0152,
        oelig: 0x0153,
        Scaron: 0x0160,
        scaron: 0x0161,
        Yuml: 0x0178,
        fnof: 0x0192,
        circ: 0x02C6,
        tilde: 0x02DC,
        Alpha: 0x0391,
        Beta: 0x0392,
        Gamma: 0x0393,
        Delta: 0x0394,
        Epsilon: 0x0395,
        Zeta: 0x0396,
        Eta: 0x0397,
        Theta: 0x0398,
        Iota: 0x0399,
        Kappa: 0x039A,
        Lambda: 0x039B,
        Mu: 0x039C,
        Nu: 0x039D,
        Xi: 0x039E,
        Omicron: 0x039F,
        Pi: 0x03A0,
        Rho: 0x03A1,
        Sigma: 0x03A3,
        Tau: 0x03A4,
        Upsilon: 0x03A5,
        Phi: 0x03A6,
        Chi: 0x03A7,
        Psi: 0x03A8,
        Omega: 0x03A9,
        alpha: 0x03B1,
        beta: 0x03B2,
        gamma: 0x03B3,
        delta: 0x03B4,
        epsilon: 0x03B5,
        zeta: 0x03B6,
        eta: 0x03B7,
        theta: 0x03B8,
        iota: 0x03B9,
        kappa: 0x03BA,
        lambda: 0x03BB,
        mu: 0x03BC,
        nu: 0x03BD,
        xi: 0x03BE,
        omicron: 0x03BF,
        pi: 0x03C0,
        rho: 0x03C1,
        sigmaf: 0x03C2,
        sigma: 0x03C3,
        tau: 0x03C4,
        upsilon: 0x03C5,
        phi: 0x03C6,
        chi: 0x03C7,
        psi: 0x03C8,
        omega: 0x03C9,
        thetasym: 0x03D1,
        upsih: 0x03D2,
        piv: 0x03D6,
        ensp: 0x2002,
        emsp: 0x2003,
        thinsp: 0x2009,
        zwnj: 0x200C,
        zwj: 0x200D,
        lrm: 0x200E,
        rlm: 0x200F,
        ndash: 0x2013,
        mdash: 0x2014,
        lsquo: 0x2018,
        rsquo: 0x2019,
        sbquo: 0x201A,
        ldquo: 0x201C,
        rdquo: 0x201D,
        bdquo: 0x201E,
        dagger: 0x2020,
        Dagger: 0x2021,
        bull: 0x2022,
        hellip: 0x2026,
        permil: 0x2030,
        prime: 0x2032,
        Prime: 0x2033,
        lsaquo: 0x2039,
        rsaquo: 0x203A,
        oline: 0x203E,
        frasl: 0x2044,
        euro: 0x20AC,
        image: 0x2111,
        weierp: 0x2118,
        real: 0x211C,
        trade: 0x2122,
        alefsym: 0x2135,
        larr: 0x2190,
        uarr: 0x2191,
        rarr: 0x2192,
        darr: 0x2193,
        harr: 0x2194,
        crarr: 0x21B5,
        lArr: 0x21D0,
        uArr: 0x21D1,
        rArr: 0x21D2,
        dArr: 0x21D3,
        hArr: 0x21D4,
        forall: 0x2200,
        part: 0x2202,
        exist: 0x2203,
        empty: 0x2205,
        nabla: 0x2207,
        isin: 0x2208,
        notin: 0x2209,
        ni: 0x220B,
        prod: 0x220F,
        sum: 0x2211,
        minus: 0x2212,
        lowast: 0x2217,
        radic: 0x221A,
        prop: 0x221D,
        infin: 0x221E,
        ang: 0x2220,
        and: 0x2227,
        or: 0x2228,
        cap: 0x2229,
        cup: 0x222A,
        int: 0x222B,
        there4: 0x2234,
        sim: 0x223C,
        cong: 0x2245,
        asymp: 0x2248,
        ne: 0x2260,
        equiv: 0x2261,
        le: 0x2264,
        ge: 0x2265,
        sub: 0x2282,
        sup: 0x2283,
        nsub: 0x2284,
        sube: 0x2286,
        supe: 0x2287,
        oplus: 0x2295,
        otimes: 0x2297,
        perp: 0x22A5,
        sdot: 0x22C5,
        lceil: 0x2308,
        rceil: 0x2309,
        lfloor: 0x230A,
        rfloor: 0x230B,
        lang: 0x2329,
        rang: 0x232A,
        loz: 0x25CA,
        spades: 0x2660,
        clubs: 0x2663,
        hearts: 0x2665,
        diams: 0x2666
    });
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformES2016(context) {
        var hoistVariableDeclaration = context.hoistVariableDeclaration;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitor(node) {
            if ((node.transformFlags & 128 /* ContainsES2016 */) === 0) {
                return node;
            }
            switch (node.kind) {
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitBinaryExpression(node) {
            switch (node.operatorToken.kind) {
                case 66 /* AsteriskAsteriskEqualsToken */:
                    return visitExponentiationAssignmentExpression(node);
                case 42 /* AsteriskAsteriskToken */:
                    return visitExponentiationExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitExponentiationAssignmentExpression(node) {
            var target;
            var value;
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = ts.visitNode(node.right, visitor, ts.isExpression);
            if (ts.isElementAccessExpression(left)) {
                // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)`
                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                var argumentExpressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                target = ts.setTextRange(ts.createElementAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), ts.setTextRange(ts.createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)), left);
                value = ts.setTextRange(ts.createElementAccess(expressionTemp, argumentExpressionTemp), left);
            }
            else if (ts.isPropertyAccessExpression(left)) {
                // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)`
                var expressionTemp = ts.createTempVariable(hoistVariableDeclaration);
                target = ts.setTextRange(ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), left.name), left);
                value = ts.setTextRange(ts.createPropertyAccess(expressionTemp, left.name), left);
            }
            else {
                // Transforms `a **= b` into `a = Math.pow(a, b)`
                target = left;
                value = left;
            }
            return ts.setTextRange(ts.createAssignment(target, ts.createMathPow(value, right, /*location*/ node)), node);
        }
        function visitExponentiationExpression(node) {
            // Transforms `a ** b` into `Math.pow(a, b)`
            var left = ts.visitNode(node.left, visitor, ts.isExpression);
            var right = ts.visitNode(node.right, visitor, ts.isExpression);
            return ts.createMathPow(left, right, /*location*/ node);
        }
    }
    ts.transformES2016 = transformES2016;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var ES2015SubstitutionFlags;
    (function (ES2015SubstitutionFlags) {
        /** Enables substitutions for captured `this` */
        ES2015SubstitutionFlags[ES2015SubstitutionFlags["CapturedThis"] = 1] = "CapturedThis";
        /** Enables substitutions for block-scoped bindings. */
        ES2015SubstitutionFlags[ES2015SubstitutionFlags["BlockScopedBindings"] = 2] = "BlockScopedBindings";
    })(ES2015SubstitutionFlags || (ES2015SubstitutionFlags = {}));
    var LoopOutParameterFlags;
    (function (LoopOutParameterFlags) {
        LoopOutParameterFlags[LoopOutParameterFlags["Body"] = 1] = "Body";
        LoopOutParameterFlags[LoopOutParameterFlags["Initializer"] = 2] = "Initializer";
    })(LoopOutParameterFlags || (LoopOutParameterFlags = {}));
    var CopyDirection;
    (function (CopyDirection) {
        CopyDirection[CopyDirection["ToOriginal"] = 0] = "ToOriginal";
        CopyDirection[CopyDirection["ToOutParameter"] = 1] = "ToOutParameter";
    })(CopyDirection || (CopyDirection = {}));
    var Jump;
    (function (Jump) {
        Jump[Jump["Break"] = 2] = "Break";
        Jump[Jump["Continue"] = 4] = "Continue";
        Jump[Jump["Return"] = 8] = "Return";
    })(Jump || (Jump = {}));
    // Facts we track as we traverse the tree
    var HierarchyFacts;
    (function (HierarchyFacts) {
        HierarchyFacts[HierarchyFacts["None"] = 0] = "None";
        //
        // Ancestor facts
        //
        HierarchyFacts[HierarchyFacts["Function"] = 1] = "Function";
        HierarchyFacts[HierarchyFacts["ArrowFunction"] = 2] = "ArrowFunction";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBody"] = 4] = "AsyncFunctionBody";
        HierarchyFacts[HierarchyFacts["NonStaticClassElement"] = 8] = "NonStaticClassElement";
        HierarchyFacts[HierarchyFacts["CapturesThis"] = 16] = "CapturesThis";
        HierarchyFacts[HierarchyFacts["ExportedVariableStatement"] = 32] = "ExportedVariableStatement";
        HierarchyFacts[HierarchyFacts["TopLevel"] = 64] = "TopLevel";
        HierarchyFacts[HierarchyFacts["Block"] = 128] = "Block";
        HierarchyFacts[HierarchyFacts["IterationStatement"] = 256] = "IterationStatement";
        HierarchyFacts[HierarchyFacts["IterationStatementBlock"] = 512] = "IterationStatementBlock";
        HierarchyFacts[HierarchyFacts["IterationContainer"] = 1024] = "IterationContainer";
        HierarchyFacts[HierarchyFacts["ForStatement"] = 2048] = "ForStatement";
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatement"] = 4096] = "ForInOrForOfStatement";
        HierarchyFacts[HierarchyFacts["ConstructorWithCapturedSuper"] = 8192] = "ConstructorWithCapturedSuper";
        // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below.
        // NOTE: when adding a new ancestor flag, be sure to update the subtree flags below.
        //
        // Ancestor masks
        //
        HierarchyFacts[HierarchyFacts["AncestorFactsMask"] = 16383] = "AncestorFactsMask";
        // We are always in *some* kind of block scope, but only specific block-scope containers are
        // top-level or Blocks.
        HierarchyFacts[HierarchyFacts["BlockScopeIncludes"] = 0] = "BlockScopeIncludes";
        HierarchyFacts[HierarchyFacts["BlockScopeExcludes"] = 7104] = "BlockScopeExcludes";
        // A source file is a top-level block scope.
        HierarchyFacts[HierarchyFacts["SourceFileIncludes"] = 64] = "SourceFileIncludes";
        HierarchyFacts[HierarchyFacts["SourceFileExcludes"] = 8064] = "SourceFileExcludes";
        // Functions, methods, and accessors are both new lexical scopes and new block scopes.
        HierarchyFacts[HierarchyFacts["FunctionIncludes"] = 65] = "FunctionIncludes";
        HierarchyFacts[HierarchyFacts["FunctionExcludes"] = 16286] = "FunctionExcludes";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyIncludes"] = 69] = "AsyncFunctionBodyIncludes";
        HierarchyFacts[HierarchyFacts["AsyncFunctionBodyExcludes"] = 16278] = "AsyncFunctionBodyExcludes";
        // Arrow functions are lexically scoped to their container, but are new block scopes.
        HierarchyFacts[HierarchyFacts["ArrowFunctionIncludes"] = 66] = "ArrowFunctionIncludes";
        HierarchyFacts[HierarchyFacts["ArrowFunctionExcludes"] = 15232] = "ArrowFunctionExcludes";
        // Constructors are both new lexical scopes and new block scopes. Constructors are also
        // always considered non-static members of a class.
        HierarchyFacts[HierarchyFacts["ConstructorIncludes"] = 73] = "ConstructorIncludes";
        HierarchyFacts[HierarchyFacts["ConstructorExcludes"] = 16278] = "ConstructorExcludes";
        // 'do' and 'while' statements are not block scopes. We track that the subtree is contained
        // within an IterationStatement to indicate whether the embedded statement is an
        // IterationStatementBlock.
        HierarchyFacts[HierarchyFacts["DoOrWhileStatementIncludes"] = 1280] = "DoOrWhileStatementIncludes";
        HierarchyFacts[HierarchyFacts["DoOrWhileStatementExcludes"] = 0] = "DoOrWhileStatementExcludes";
        // 'for' statements are new block scopes and have special handling for 'let' declarations.
        HierarchyFacts[HierarchyFacts["ForStatementIncludes"] = 3328] = "ForStatementIncludes";
        HierarchyFacts[HierarchyFacts["ForStatementExcludes"] = 5056] = "ForStatementExcludes";
        // 'for-in' and 'for-of' statements are new block scopes and have special handling for
        // 'let' declarations.
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementIncludes"] = 5376] = "ForInOrForOfStatementIncludes";
        HierarchyFacts[HierarchyFacts["ForInOrForOfStatementExcludes"] = 3008] = "ForInOrForOfStatementExcludes";
        // Blocks (other than function bodies) are new block scopes.
        HierarchyFacts[HierarchyFacts["BlockIncludes"] = 128] = "BlockIncludes";
        HierarchyFacts[HierarchyFacts["BlockExcludes"] = 6976] = "BlockExcludes";
        HierarchyFacts[HierarchyFacts["IterationStatementBlockIncludes"] = 512] = "IterationStatementBlockIncludes";
        HierarchyFacts[HierarchyFacts["IterationStatementBlockExcludes"] = 7104] = "IterationStatementBlockExcludes";
        //
        // Subtree facts
        //
        HierarchyFacts[HierarchyFacts["NewTarget"] = 16384] = "NewTarget";
        HierarchyFacts[HierarchyFacts["CapturedLexicalThis"] = 32768] = "CapturedLexicalThis";
        //
        // Subtree masks
        //
        HierarchyFacts[HierarchyFacts["SubtreeFactsMask"] = -16384] = "SubtreeFactsMask";
        HierarchyFacts[HierarchyFacts["ArrowFunctionSubtreeExcludes"] = 0] = "ArrowFunctionSubtreeExcludes";
        HierarchyFacts[HierarchyFacts["FunctionSubtreeExcludes"] = 49152] = "FunctionSubtreeExcludes";
    })(HierarchyFacts || (HierarchyFacts = {}));
    function transformES2015(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        var currentSourceFile;
        var currentText;
        var hierarchyFacts;
        var taggedTemplateStringDeclarations;
        function recordTaggedTemplateString(temp) {
            taggedTemplateStringDeclarations = ts.append(taggedTemplateStringDeclarations, ts.createVariableDeclaration(temp));
        }
        /**
         * Used to track if we are emitting body of the converted loop
         */
        var convertedLoopState;
        /**
         * Keeps track of whether substitutions have been enabled for specific cases.
         * They are persisted between each SourceFile transformation and should not
         * be reset.
         */
        var enabledSubstitutions;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            currentSourceFile = node;
            currentText = node.text;
            var visited = visitSourceFile(node);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            currentSourceFile = undefined;
            currentText = undefined;
            taggedTemplateStringDeclarations = undefined;
            hierarchyFacts = 0 /* None */;
            return visited;
        }
        /**
         * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification.
         * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree.
         * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree.
         */
        function enterSubtree(excludeFacts, includeFacts) {
            var ancestorFacts = hierarchyFacts;
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 16383 /* AncestorFactsMask */;
            return ancestorFacts;
        }
        /**
         * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's
         * subtree, propagating specific facts from the subtree.
         * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree.
         * @param excludeFacts The existing `HierarchyFacts` of the subtree that should not be propagated.
         * @param includeFacts The new `HierarchyFacts` of the subtree that should be propagated.
         */
        function exitSubtree(ancestorFacts, excludeFacts, includeFacts) {
            hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & -16384 /* SubtreeFactsMask */ | ancestorFacts;
        }
        function isReturnVoidStatementInConstructorWithCapturedSuper(node) {
            return (hierarchyFacts & 8192 /* ConstructorWithCapturedSuper */) !== 0
                && node.kind === 235 /* ReturnStatement */
                && !node.expression;
        }
        function shouldVisitNode(node) {
            return (node.transformFlags & 256 /* ContainsES2015 */) !== 0
                || convertedLoopState !== undefined
                || (hierarchyFacts & 8192 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 223 /* Block */)))
                || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatement(node))
                || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0;
        }
        function visitor(node) {
            if (shouldVisitNode(node)) {
                return visitJavaScript(node);
            }
            else {
                return node;
            }
        }
        function callExpressionVisitor(node) {
            if (node.kind === 102 /* SuperKeyword */) {
                return visitSuperKeyword(/*isExpressionOfCall*/ true);
            }
            return visitor(node);
        }
        function visitJavaScript(node) {
            switch (node.kind) {
                case 120 /* StaticKeyword */:
                    return undefined; // elide static keyword
                case 245 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 214 /* ClassExpression */:
                    return visitClassExpression(node);
                case 156 /* Parameter */:
                    return visitParameter(node);
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 202 /* ArrowFunction */:
                    return visitArrowFunction(node);
                case 201 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 242 /* VariableDeclaration */:
                    return visitVariableDeclaration(node);
                case 75 /* Identifier */:
                    return visitIdentifier(node);
                case 243 /* VariableDeclarationList */:
                    return visitVariableDeclarationList(node);
                case 237 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 251 /* CaseBlock */:
                    return visitCaseBlock(node);
                case 223 /* Block */:
                    return visitBlock(node, /*isFunctionBody*/ false);
                case 234 /* BreakStatement */:
                case 233 /* ContinueStatement */:
                    return visitBreakOrContinueStatement(node);
                case 238 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                    return visitDoOrWhileStatement(node, /*outermostLabeledStatement*/ undefined);
                case 230 /* ForStatement */:
                    return visitForStatement(node, /*outermostLabeledStatement*/ undefined);
                case 231 /* ForInStatement */:
                    return visitForInStatement(node, /*outermostLabeledStatement*/ undefined);
                case 232 /* ForOfStatement */:
                    return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined);
                case 226 /* ExpressionStatement */:
                    return visitExpressionStatement(node);
                case 193 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 280 /* CatchClause */:
                    return visitCatchClause(node);
                case 282 /* ShorthandPropertyAssignment */:
                    return visitShorthandPropertyAssignment(node);
                case 154 /* ComputedPropertyName */:
                    return visitComputedPropertyName(node);
                case 192 /* ArrayLiteralExpression */:
                    return visitArrayLiteralExpression(node);
                case 196 /* CallExpression */:
                    return visitCallExpression(node);
                case 197 /* NewExpression */:
                    return visitNewExpression(node);
                case 200 /* ParenthesizedExpression */:
                    return visitParenthesizedExpression(node, /*needsDestructuringValue*/ true);
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node, /*needsDestructuringValue*/ true);
                case 14 /* NoSubstitutionTemplateLiteral */:
                case 15 /* TemplateHead */:
                case 16 /* TemplateMiddle */:
                case 17 /* TemplateTail */:
                    return visitTemplateLiteral(node);
                case 10 /* StringLiteral */:
                    return visitStringLiteral(node);
                case 8 /* NumericLiteral */:
                    return visitNumericLiteral(node);
                case 198 /* TaggedTemplateExpression */:
                    return visitTaggedTemplateExpression(node);
                case 211 /* TemplateExpression */:
                    return visitTemplateExpression(node);
                case 212 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 213 /* SpreadElement */:
                    return visitSpreadElement(node);
                case 102 /* SuperKeyword */:
                    return visitSuperKeyword(/*isExpressionOfCall*/ false);
                case 104 /* ThisKeyword */:
                    return visitThisKeyword(node);
                case 219 /* MetaProperty */:
                    return visitMetaProperty(node);
                case 161 /* MethodDeclaration */:
                    return visitMethodDeclaration(node);
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return visitAccessorDeclaration(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 235 /* ReturnStatement */:
                    return visitReturnStatement(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        function visitSourceFile(node) {
            var ancestorFacts = enterSubtree(8064 /* SourceFileExcludes */, 64 /* SourceFileIncludes */);
            var prologue = [];
            var statements = [];
            startLexicalEnvironment();
            var statementOffset = ts.addStandardPrologue(prologue, node.statements, /*ensureUseStrict*/ false);
            statementOffset = ts.addCustomPrologue(prologue, node.statements, statementOffset, visitor);
            ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
            if (taggedTemplateStringDeclarations) {
                statements.push(ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(taggedTemplateStringDeclarations)));
            }
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureThisForNodeIfNeeded(prologue, node);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(ts.concatenate(prologue, statements)), node.statements));
        }
        function visitSwitchStatement(node) {
            if (convertedLoopState !== undefined) {
                var savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                // for switch statement allow only non-labeled break
                convertedLoopState.allowedNonLabeledJumps |= 2 /* Break */;
                var result = ts.visitEachChild(node, visitor, context);
                convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps;
                return result;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCaseBlock(node) {
            var ancestorFacts = enterSubtree(7104 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function returnCapturedThis(node) {
            return ts.setOriginalNode(ts.createReturn(ts.createFileLevelUniqueName("_this")), node);
        }
        function visitReturnStatement(node) {
            if (convertedLoopState) {
                convertedLoopState.nonLocalJumps |= 8 /* Return */;
                if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
                    node = returnCapturedThis(node);
                }
                return ts.createReturn(ts.createObjectLiteral([
                    ts.createPropertyAssignment(ts.createIdentifier("value"), node.expression
                        ? ts.visitNode(node.expression, visitor, ts.isExpression)
                        : ts.createVoidZero())
                ]));
            }
            else if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
                return returnCapturedThis(node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitThisKeyword(node) {
            if (hierarchyFacts & 2 /* ArrowFunction */) {
                hierarchyFacts |= 32768 /* CapturedLexicalThis */;
            }
            if (convertedLoopState) {
                if (hierarchyFacts & 2 /* ArrowFunction */) {
                    // if the enclosing function is an ArrowFunction then we use the captured 'this' keyword.
                    convertedLoopState.containsLexicalThis = true;
                    return node;
                }
                return convertedLoopState.thisName || (convertedLoopState.thisName = ts.createUniqueName("this"));
            }
            return node;
        }
        function visitIdentifier(node) {
            if (!convertedLoopState) {
                return node;
            }
            if (ts.isGeneratedIdentifier(node)) {
                return node;
            }
            if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
                return node;
            }
            return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = ts.createUniqueName("arguments"));
        }
        function visitBreakOrContinueStatement(node) {
            if (convertedLoopState) {
                // check if we can emit break/continue as is
                // it is possible if either
                //   - break/continue is labeled and label is located inside the converted loop
                //   - break/continue is non-labeled and located in non-converted loop/switch statement
                var jump = node.kind === 234 /* BreakStatement */ ? 2 /* Break */ : 4 /* Continue */;
                var canUseBreakOrContinue = (node.label && convertedLoopState.labels && convertedLoopState.labels.get(ts.idText(node.label))) ||
                    (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
                if (!canUseBreakOrContinue) {
                    var labelMarker = void 0;
                    var label = node.label;
                    if (!label) {
                        if (node.kind === 234 /* BreakStatement */) {
                            convertedLoopState.nonLocalJumps |= 2 /* Break */;
                            labelMarker = "break";
                        }
                        else {
                            convertedLoopState.nonLocalJumps |= 4 /* Continue */;
                            // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it.
                            labelMarker = "continue";
                        }
                    }
                    else {
                        if (node.kind === 234 /* BreakStatement */) {
                            labelMarker = "break-" + label.escapedText;
                            setLabeledJump(convertedLoopState, /*isBreak*/ true, ts.idText(label), labelMarker);
                        }
                        else {
                            labelMarker = "continue-" + label.escapedText;
                            setLabeledJump(convertedLoopState, /*isBreak*/ false, ts.idText(label), labelMarker);
                        }
                    }
                    var returnExpression = ts.createLiteral(labelMarker);
                    if (convertedLoopState.loopOutParameters.length) {
                        var outParams = convertedLoopState.loopOutParameters;
                        var expr = void 0;
                        for (var i = 0; i < outParams.length; i++) {
                            var copyExpr = copyOutParameter(outParams[i], 1 /* ToOutParameter */);
                            if (i === 0) {
                                expr = copyExpr;
                            }
                            else {
                                expr = ts.createBinary(expr, 27 /* CommaToken */, copyExpr);
                            }
                        }
                        returnExpression = ts.createBinary(expr, 27 /* CommaToken */, returnExpression);
                    }
                    return ts.createReturn(returnExpression);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a ClassDeclaration and transforms it into a variable statement.
         *
         * @param node A ClassDeclaration node.
         */
        function visitClassDeclaration(node) {
            // [source]
            //      class C { }
            //
            // [output]
            //      var C = (function () {
            //          function C() {
            //          }
            //          return C;
            //      }());
            var variable = ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ true), 
            /*type*/ undefined, transformClassLikeDeclarationToExpression(node));
            ts.setOriginalNode(variable, node);
            var statements = [];
            var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([variable]));
            ts.setOriginalNode(statement, node);
            ts.setTextRange(statement, node);
            ts.startOnNewLine(statement);
            statements.push(statement);
            // Add an `export default` statement for default exports (for `--target es5 --module es6`)
            if (ts.hasModifier(node, 1 /* Export */)) {
                var exportStatement = ts.hasModifier(node, 512 /* Default */)
                    ? ts.createExportDefault(ts.getLocalName(node))
                    : ts.createExternalModuleExport(ts.getLocalName(node));
                ts.setOriginalNode(exportStatement, statement);
                statements.push(exportStatement);
            }
            var emitFlags = ts.getEmitFlags(node);
            if ((emitFlags & 4194304 /* HasEndOfDeclarationMarker */) === 0) {
                // Add a DeclarationMarker as a marker for the end of the declaration
                statements.push(ts.createEndOfDeclarationMarker(node));
                ts.setEmitFlags(statement, emitFlags | 4194304 /* HasEndOfDeclarationMarker */);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a ClassExpression and transforms it into an expression.
         *
         * @param node A ClassExpression node.
         */
        function visitClassExpression(node) {
            // [source]
            //      C = class { }
            //
            // [output]
            //      C = (function () {
            //          function class_1() {
            //          }
            //          return class_1;
            //      }())
            return transformClassLikeDeclarationToExpression(node);
        }
        /**
         * Transforms a ClassExpression or ClassDeclaration into an expression.
         *
         * @param node A ClassExpression or ClassDeclaration node.
         */
        function transformClassLikeDeclarationToExpression(node) {
            // [source]
            //      class C extends D {
            //          constructor() {}
            //          method() {}
            //          get prop() {}
            //          set prop(v) {}
            //      }
            //
            // [output]
            //      (function (_super) {
            //          __extends(C, _super);
            //          function C() {
            //          }
            //          C.prototype.method = function () {}
            //          Object.defineProperty(C.prototype, "prop", {
            //              get: function() {},
            //              set: function() {},
            //              enumerable: true,
            //              configurable: true
            //          });
            //          return C;
            //      }(D))
            if (node.name) {
                enableSubstitutionsForBlockScopedBindings();
            }
            var extendsClauseElement = ts.getClassExtendsHeritageElement(node);
            var classFunction = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, extendsClauseElement ? [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, ts.createFileLevelUniqueName("_super"))] : [], 
            /*type*/ undefined, transformClassBody(node, extendsClauseElement));
            // To preserve the behavior of the old emitter, we explicitly indent
            // the body of the function here if it was requested in an earlier
            // transformation.
            ts.setEmitFlags(classFunction, (ts.getEmitFlags(node) & 65536 /* Indented */) | 524288 /* ReuseTempVariableScope */);
            // "inner" and "outer" below are added purely to preserve source map locations from
            // the old emitter
            var inner = ts.createPartiallyEmittedExpression(classFunction);
            inner.end = node.end;
            ts.setEmitFlags(inner, 1536 /* NoComments */);
            var outer = ts.createPartiallyEmittedExpression(inner);
            outer.end = ts.skipTrivia(currentText, node.pos);
            ts.setEmitFlags(outer, 1536 /* NoComments */);
            var result = ts.createParen(ts.createCall(outer, 
            /*typeArguments*/ undefined, extendsClauseElement
                ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)]
                : []));
            ts.addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class ");
            return result;
        }
        /**
         * Transforms a ClassExpression or ClassDeclaration into a function body.
         *
         * @param node A ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function transformClassBody(node, extendsClauseElement) {
            var statements = [];
            startLexicalEnvironment();
            addExtendsHelperIfNeeded(statements, node, extendsClauseElement);
            addConstructor(statements, node, extendsClauseElement);
            addClassMembers(statements, node);
            // Create a synthetic text range for the return statement.
            var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentText, node.members.end), 19 /* CloseBraceToken */);
            var localName = ts.getInternalName(node);
            // The following partially-emitted expression exists purely to align our sourcemap
            // emit with the original emitter.
            var outer = ts.createPartiallyEmittedExpression(localName);
            outer.end = closingBraceLocation.end;
            ts.setEmitFlags(outer, 1536 /* NoComments */);
            var statement = ts.createReturn(outer);
            statement.pos = closingBraceLocation.pos;
            ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */);
            statements.push(statement);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true);
            ts.setEmitFlags(block, 1536 /* NoComments */);
            return block;
        }
        /**
         * Adds a call to the `__extends` helper if needed for a class.
         *
         * @param statements The statements of the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function addExtendsHelperIfNeeded(statements, node, extendsClauseElement) {
            if (extendsClauseElement) {
                statements.push(ts.setTextRange(ts.createExpressionStatement(createExtendsHelper(context, ts.getInternalName(node))), 
                /*location*/ extendsClauseElement));
            }
        }
        /**
         * Adds the constructor of the class to a class body function.
         *
         * @param statements The statements of the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         * @param extendsClauseElement The expression for the class `extends` clause.
         */
        function addConstructor(statements, node, extendsClauseElement) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16278 /* ConstructorExcludes */, 73 /* ConstructorIncludes */);
            var constructor = ts.getFirstConstructorWithBody(node);
            var hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined);
            var constructorFunction = ts.createFunctionDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, ts.getInternalName(node), 
            /*typeParameters*/ undefined, transformConstructorParameters(constructor, hasSynthesizedSuper), 
            /*type*/ undefined, transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper));
            ts.setTextRange(constructorFunction, constructor || node);
            if (extendsClauseElement) {
                ts.setEmitFlags(constructorFunction, 8 /* CapturesThis */);
            }
            statements.push(constructorFunction);
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
        }
        /**
         * Transforms the parameters of the constructor declaration of a class.
         *
         * @param constructor The constructor for the class.
         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
         *                            synthesized `super` call.
         */
        function transformConstructorParameters(constructor, hasSynthesizedSuper) {
            // If the TypeScript transformer needed to synthesize a constructor for property
            // initializers, it would have also added a synthetic `...args` parameter and
            // `super` call.
            // If this is the case, we do not include the synthetic `...args` parameter and
            // will instead use the `arguments` object in ES5/3.
            return ts.visitParameterList(constructor && !hasSynthesizedSuper ? constructor.parameters : undefined, visitor, context)
                || [];
        }
        function createDefaultConstructorBody(node, isDerivedClass) {
            // We must be here because the user didn't write a constructor
            // but we needed to call 'super(...args)' anyway as per 14.5.14 of the ES2016 spec.
            // If that's the case we can just immediately return the result of a 'super()' call.
            var statements = [];
            resumeLexicalEnvironment();
            ts.mergeLexicalEnvironment(statements, endLexicalEnvironment());
            if (isDerivedClass) {
                // return _super !== null && _super.apply(this, arguments) || this;
                statements.push(ts.createReturn(createDefaultSuperCallOrThis()));
            }
            var statementsArray = ts.createNodeArray(statements);
            ts.setTextRange(statementsArray, node.members);
            var block = ts.createBlock(statementsArray, /*multiLine*/ true);
            ts.setTextRange(block, node);
            ts.setEmitFlags(block, 1536 /* NoComments */);
            return block;
        }
        /**
         * Transforms the body of a constructor declaration of a class.
         *
         * @param constructor The constructor for the class.
         * @param node The node which contains the constructor.
         * @param extendsClauseElement The expression for the class `extends` clause.
         * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
         *                            synthesized `super` call.
         */
        function transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper) {
            // determine whether the class is known syntactically to be a derived class (e.g. a
            // class that extends a value that is not syntactically known to be `null`).
            var isDerivedClass = !!extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 100 /* NullKeyword */;
            // When the subclass does not have a constructor, we synthesize a *default* constructor using the following
            // representation:
            //
            // ```
            // // es2015 (source)
            // class C extends Base { }
            //
            // // es5 (transformed)
            // var C = (function (_super) {
            //     function C() {
            //         return _super.apply(this, arguments) || this;
            //     }
            //     return C;
            // })(Base);
            // ```
            if (!constructor)
                return createDefaultConstructorBody(node, isDerivedClass);
            // The prologue will contain all leading standard and custom prologue statements added by this transform
            var prologue = [];
            var statements = [];
            resumeLexicalEnvironment();
            // If a super call has already been synthesized,
            // we're going to assume that we should just transform everything after that.
            // The assumption is that no prior step in the pipeline has added any prologue directives.
            var statementOffset = 0;
            if (!hasSynthesizedSuper)
                statementOffset = ts.addStandardPrologue(prologue, constructor.body.statements, /*ensureUseStrict*/ false);
            addDefaultValueAssignmentsIfNeeded(statements, constructor);
            addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper);
            if (!hasSynthesizedSuper)
                statementOffset = ts.addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor);
            // If the first statement is a call to `super()`, visit the statement directly
            var superCallExpression;
            if (hasSynthesizedSuper) {
                superCallExpression = createDefaultSuperCallOrThis();
            }
            else if (isDerivedClass && statementOffset < constructor.body.statements.length) {
                var firstStatement = constructor.body.statements[statementOffset];
                if (ts.isExpressionStatement(firstStatement) && ts.isSuperCall(firstStatement.expression)) {
                    superCallExpression = visitImmediateSuperCallInBody(firstStatement.expression);
                }
            }
            if (superCallExpression) {
                hierarchyFacts |= 8192 /* ConstructorWithCapturedSuper */;
                statementOffset++; // skip this statement, we will add it after visiting the rest of the body.
            }
            // visit the remaining statements
            ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, /*start*/ statementOffset));
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureNewTargetIfNeeded(prologue, constructor, /*copyOnWrite*/ false);
            if (isDerivedClass) {
                if (superCallExpression && statementOffset === constructor.body.statements.length && !(constructor.body.transformFlags & 4096 /* ContainsLexicalThis */)) {
                    // If the subclass constructor does *not* contain `this` and *ends* with a `super()` call, we will use the
                    // following representation:
                    //
                    // ```
                    // // es2015 (source)
                    // class C extends Base {
                    //     constructor() {
                    //         super("foo");
                    //     }
                    // }
                    //
                    // // es5 (transformed)
                    // var C = (function (_super) {
                    //     function C() {
                    //         return _super.call(this, "foo") || this;
                    //     }
                    //     return C;
                    // })(Base);
                    // ```
                    var superCall = ts.cast(ts.cast(superCallExpression, ts.isBinaryExpression).left, ts.isCallExpression);
                    var returnStatement = ts.createReturn(superCallExpression);
                    ts.setCommentRange(returnStatement, ts.getCommentRange(superCall));
                    ts.setEmitFlags(superCall, 1536 /* NoComments */);
                    statements.push(returnStatement);
                }
                else {
                    // Otherwise, we will use the following transformed representation for calls to `super()` in a constructor:
                    //
                    // ```
                    // // es2015 (source)
                    // class C extends Base {
                    //     constructor() {
                    //         super("foo");
                    //         this.x = 1;
                    //     }
                    // }
                    //
                    // // es5 (transformed)
                    // var C = (function (_super) {
                    //     function C() {
                    //         var _this = _super.call(this, "foo") || this;
                    //         _this.x = 1;
                    //         return _this;
                    //     }
                    //     return C;
                    // })(Base);
                    // ```
                    // Since the `super()` call was the first statement, we insert the `this` capturing call to
                    // `super()` at the top of the list of `statements` (after any pre-existing custom prologues).
                    insertCaptureThisForNode(statements, constructor, superCallExpression || createActualThis());
                    if (!isSufficientlyCoveredByReturnStatements(constructor.body)) {
                        statements.push(ts.createReturn(ts.createFileLevelUniqueName("_this")));
                    }
                }
            }
            else {
                // If a class is not derived from a base class or does not have a call to `super()`, `this` is only
                // captured when necessitated by an arrow function capturing the lexical `this`:
                //
                // ```
                // // es2015
                // class C {}
                //
                // // es5
                // var C = (function () {
                //     function C() {
                //     }
                //     return C;
                // })();
                // ```
                insertCaptureThisForNodeIfNeeded(prologue, constructor);
            }
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(ts.concatenate(prologue, statements)), 
            /*location*/ constructor.body.statements), 
            /*multiLine*/ true);
            ts.setTextRange(block, constructor.body);
            return block;
        }
        /**
         * We want to try to avoid emitting a return statement in certain cases if a user already returned something.
         * It would generate obviously dead code, so we'll try to make things a little bit prettier
         * by doing a minimal check on whether some common patterns always explicitly return.
         */
        function isSufficientlyCoveredByReturnStatements(statement) {
            // A return statement is considered covered.
            if (statement.kind === 235 /* ReturnStatement */) {
                return true;
            }
            // An if-statement with two covered branches is covered.
            else if (statement.kind === 227 /* IfStatement */) {
                var ifStatement = statement;
                if (ifStatement.elseStatement) {
                    return isSufficientlyCoveredByReturnStatements(ifStatement.thenStatement) &&
                        isSufficientlyCoveredByReturnStatements(ifStatement.elseStatement);
                }
            }
            // A block is covered if it has a last statement which is covered.
            else if (statement.kind === 223 /* Block */) {
                var lastStatement = ts.lastOrUndefined(statement.statements);
                if (lastStatement && isSufficientlyCoveredByReturnStatements(lastStatement)) {
                    return true;
                }
            }
            return false;
        }
        function createActualThis() {
            return ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */);
        }
        function createDefaultSuperCallOrThis() {
            return ts.createLogicalOr(ts.createLogicalAnd(ts.createStrictInequality(ts.createFileLevelUniqueName("_super"), ts.createNull()), ts.createFunctionApply(ts.createFileLevelUniqueName("_super"), createActualThis(), ts.createIdentifier("arguments"))), createActualThis());
        }
        /**
         * Visits a parameter declaration.
         *
         * @param node A ParameterDeclaration node.
         */
        function visitParameter(node) {
            if (node.dotDotDotToken) {
                // rest parameters are elided
                return undefined;
            }
            else if (ts.isBindingPattern(node.name)) {
                // Binding patterns are converted into a generated name and are
                // evaluated inside the function body.
                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, ts.getGeneratedNameForNode(node), 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined), 
                /*location*/ node), 
                /*original*/ node);
            }
            else if (node.initializer) {
                // Initializers are elided
                return ts.setOriginalNode(ts.setTextRange(ts.createParameter(
                /*decorators*/ undefined, 
                /*modifiers*/ undefined, 
                /*dotDotDotToken*/ undefined, node.name, 
                /*questionToken*/ undefined, 
                /*type*/ undefined, 
                /*initializer*/ undefined), 
                /*location*/ node), 
                /*original*/ node);
            }
            else {
                return node;
            }
        }
        function hasDefaultValueOrBindingPattern(node) {
            return node.initializer !== undefined
                || ts.isBindingPattern(node.name);
        }
        /**
         * Adds statements to the body of a function-like node if it contains parameters with
         * binding patterns or initializers.
         *
         * @param statements The statements for the new function body.
         * @param node A function-like node.
         */
        function addDefaultValueAssignmentsIfNeeded(statements, node) {
            if (!ts.some(node.parameters, hasDefaultValueOrBindingPattern)) {
                return false;
            }
            var added = false;
            for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
                var parameter = _a[_i];
                var name = parameter.name, initializer = parameter.initializer, dotDotDotToken = parameter.dotDotDotToken;
                // A rest parameter cannot have a binding pattern or an initializer,
                // so let's just ignore it.
                if (dotDotDotToken) {
                    continue;
                }
                if (ts.isBindingPattern(name)) {
                    added = insertDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) || added;
                }
                else if (initializer) {
                    insertDefaultValueAssignmentForInitializer(statements, parameter, name, initializer);
                    added = true;
                }
            }
            return added;
        }
        /**
         * Adds statements to the body of a function-like node for parameters with binding patterns
         *
         * @param statements The statements for the new function body.
         * @param parameter The parameter for the function.
         * @param name The name of the parameter.
         * @param initializer The initializer for the parameter.
         */
        function insertDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) {
            // In cases where a binding pattern is simply '[]' or '{}',
            // we usually don't want to emit a var declaration; however, in the presence
            // of an initializer, we must emit that expression to preserve side effects.
            if (name.elements.length > 0) {
                ts.insertStatementAfterCustomPrologue(statements, ts.setEmitFlags(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, ts.getGeneratedNameForNode(parameter)))), 1048576 /* CustomPrologue */));
                return true;
            }
            else if (initializer) {
                ts.insertStatementAfterCustomPrologue(statements, ts.setEmitFlags(ts.createExpressionStatement(ts.createAssignment(ts.getGeneratedNameForNode(parameter), ts.visitNode(initializer, visitor, ts.isExpression))), 1048576 /* CustomPrologue */));
                return true;
            }
            return false;
        }
        /**
         * Adds statements to the body of a function-like node for parameters with initializers.
         *
         * @param statements The statements for the new function body.
         * @param parameter The parameter for the function.
         * @param name The name of the parameter.
         * @param initializer The initializer for the parameter.
         */
        function insertDefaultValueAssignmentForInitializer(statements, parameter, name, initializer) {
            initializer = ts.visitNode(initializer, visitor, ts.isExpression);
            var statement = ts.createIf(ts.createTypeCheck(ts.getSynthesizedClone(name), "undefined"), ts.setEmitFlags(ts.setTextRange(ts.createBlock([
                ts.createExpressionStatement(ts.setEmitFlags(ts.setTextRange(ts.createAssignment(ts.setEmitFlags(ts.getMutableClone(name), 48 /* NoSourceMap */), ts.setEmitFlags(initializer, 48 /* NoSourceMap */ | ts.getEmitFlags(initializer) | 1536 /* NoComments */)), parameter), 1536 /* NoComments */))
            ]), parameter), 1 /* SingleLine */ | 32 /* NoTrailingSourceMap */ | 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */));
            ts.startOnNewLine(statement);
            ts.setTextRange(statement, parameter);
            ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1048576 /* CustomPrologue */ | 1536 /* NoComments */);
            ts.insertStatementAfterCustomPrologue(statements, statement);
        }
        /**
         * Gets a value indicating whether we need to add statements to handle a rest parameter.
         *
         * @param node A ParameterDeclaration node.
         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
         *                                          part of a constructor declaration with a
         *                                          synthesized call to `super`
         */
        function shouldAddRestParameter(node, inConstructorWithSynthesizedSuper) {
            return !!(node && node.dotDotDotToken && !inConstructorWithSynthesizedSuper);
        }
        /**
         * Adds statements to the body of a function-like node if it contains a rest parameter.
         *
         * @param statements The statements for the new function body.
         * @param node A function-like node.
         * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is
         *                                          part of a constructor declaration with a
         *                                          synthesized call to `super`
         */
        function addRestParameterIfNeeded(statements, node, inConstructorWithSynthesizedSuper) {
            var prologueStatements = [];
            var parameter = ts.lastOrUndefined(node.parameters);
            if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) {
                return false;
            }
            // `declarationName` is the name of the local declaration for the parameter.
            var declarationName = parameter.name.kind === 75 /* Identifier */ ? ts.getMutableClone(parameter.name) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            ts.setEmitFlags(declarationName, 48 /* NoSourceMap */);
            // `expressionName` is the name of the parameter used in expressions.
            var expressionName = parameter.name.kind === 75 /* Identifier */ ? ts.getSynthesizedClone(parameter.name) : declarationName;
            var restIndex = node.parameters.length - 1;
            var temp = ts.createLoopVariable();
            // var param = [];
            prologueStatements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(declarationName, 
                /*type*/ undefined, ts.createArrayLiteral([]))
            ])), 
            /*location*/ parameter), 1048576 /* CustomPrologue */));
            // for (var _i = restIndex; _i < arguments.length; _i++) {
            //   param[_i - restIndex] = arguments[_i];
            // }
            var forStatement = ts.createFor(ts.setTextRange(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(temp, /*type*/ undefined, ts.createLiteral(restIndex))
            ]), parameter), ts.setTextRange(ts.createLessThan(temp, ts.createPropertyAccess(ts.createIdentifier("arguments"), "length")), parameter), ts.setTextRange(ts.createPostfixIncrement(temp), parameter), ts.createBlock([
                ts.startOnNewLine(ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(ts.createElementAccess(expressionName, restIndex === 0
                    ? temp
                    : ts.createSubtract(temp, ts.createLiteral(restIndex))), ts.createElementAccess(ts.createIdentifier("arguments"), temp))), 
                /*location*/ parameter))
            ]));
            ts.setEmitFlags(forStatement, 1048576 /* CustomPrologue */);
            ts.startOnNewLine(forStatement);
            prologueStatements.push(forStatement);
            if (parameter.name.kind !== 75 /* Identifier */) {
                // do the actual destructuring of the rest parameter if necessary
                prologueStatements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, expressionName))), parameter), 1048576 /* CustomPrologue */));
            }
            ts.insertStatementsAfterCustomPrologue(statements, prologueStatements);
            return true;
        }
        /**
         * Adds a statement to capture the `this` of a function declaration if it is needed.
         * NOTE: This must be executed *after* the subtree has been visited.
         *
         * @param statements The statements for the new function body.
         * @param node A node.
         */
        function insertCaptureThisForNodeIfNeeded(statements, node) {
            if (hierarchyFacts & 32768 /* CapturedLexicalThis */ && node.kind !== 202 /* ArrowFunction */) {
                insertCaptureThisForNode(statements, node, ts.createThis());
                return true;
            }
            return false;
        }
        function insertCaptureThisForNode(statements, node, initializer) {
            enableSubstitutionsForCapturedThis();
            var captureThisStatement = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(ts.createFileLevelUniqueName("_this"), 
                /*type*/ undefined, initializer)
            ]));
            ts.setEmitFlags(captureThisStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */);
            ts.setSourceMapRange(captureThisStatement, node);
            ts.insertStatementAfterCustomPrologue(statements, captureThisStatement);
        }
        function insertCaptureNewTargetIfNeeded(statements, node, copyOnWrite) {
            if (hierarchyFacts & 16384 /* NewTarget */) {
                var newTarget = void 0;
                switch (node.kind) {
                    case 202 /* ArrowFunction */:
                        return statements;
                    case 161 /* MethodDeclaration */:
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        // Methods and accessors cannot be constructors, so 'new.target' will
                        // always return 'undefined'.
                        newTarget = ts.createVoidZero();
                        break;
                    case 162 /* Constructor */:
                        // Class constructors can only be called with `new`, so `this.constructor`
                        // should be relatively safe to use.
                        newTarget = ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor");
                        break;
                    case 244 /* FunctionDeclaration */:
                    case 201 /* FunctionExpression */:
                        // Functions can be called or constructed, and may have a `this` due to
                        // being a member or when calling an imported function via `other_1.f()`.
                        newTarget = ts.createConditional(ts.createLogicalAnd(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), ts.createBinary(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), 98 /* InstanceOfKeyword */, ts.getLocalName(node))), ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor"), ts.createVoidZero());
                        break;
                    default:
                        return ts.Debug.failBadSyntaxKind(node);
                }
                var captureNewTargetStatement = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(ts.createFileLevelUniqueName("_newTarget"), 
                    /*type*/ undefined, newTarget)
                ]));
                ts.setEmitFlags(captureNewTargetStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */);
                if (copyOnWrite) {
                    statements = statements.slice();
                }
                ts.insertStatementAfterCustomPrologue(statements, captureNewTargetStatement);
            }
            return statements;
        }
        /**
         * Adds statements to the class body function for a class to define the members of the
         * class.
         *
         * @param statements The statements for the class body function.
         * @param node The ClassExpression or ClassDeclaration node.
         */
        function addClassMembers(statements, node) {
            for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
                var member = _a[_i];
                switch (member.kind) {
                    case 222 /* SemicolonClassElement */:
                        statements.push(transformSemicolonClassElementToStatement(member));
                        break;
                    case 161 /* MethodDeclaration */:
                        statements.push(transformClassMethodDeclarationToStatement(getClassMemberPrefix(node, member), member, node));
                        break;
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        var accessors = ts.getAllAccessorDeclarations(node.members, member);
                        if (member === accessors.firstAccessor) {
                            statements.push(transformAccessorsToStatement(getClassMemberPrefix(node, member), accessors, node));
                        }
                        break;
                    case 162 /* Constructor */:
                        // Constructors are handled in visitClassExpression/visitClassDeclaration
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(member, currentSourceFile && currentSourceFile.fileName);
                        break;
                }
            }
        }
        /**
         * Transforms a SemicolonClassElement into a statement for a class body function.
         *
         * @param member The SemicolonClassElement node.
         */
        function transformSemicolonClassElementToStatement(member) {
            return ts.setTextRange(ts.createEmptyStatement(), member);
        }
        /**
         * Transforms a MethodDeclaration into a statement for a class body function.
         *
         * @param receiver The receiver for the member.
         * @param member The MethodDeclaration node.
         */
        function transformClassMethodDeclarationToStatement(receiver, member, container) {
            var commentRange = ts.getCommentRange(member);
            var sourceMapRange = ts.getSourceMapRange(member);
            var memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container);
            var propertyName = ts.visitNode(member.name, visitor, ts.isPropertyName);
            var e;
            if (!ts.isPrivateIdentifier(propertyName) && context.getCompilerOptions().useDefineForClassFields) {
                var name = ts.isComputedPropertyName(propertyName) ? propertyName.expression
                    : ts.isIdentifier(propertyName) ? ts.createStringLiteral(ts.unescapeLeadingUnderscores(propertyName.escapedText))
                        : propertyName;
                e = ts.createObjectDefinePropertyCall(receiver, name, ts.createPropertyDescriptor({ value: memberFunction, enumerable: false, writable: true, configurable: true }));
            }
            else {
                var memberName = ts.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ member.name);
                e = ts.createAssignment(memberName, memberFunction);
            }
            ts.setEmitFlags(memberFunction, 1536 /* NoComments */);
            ts.setSourceMapRange(memberFunction, sourceMapRange);
            var statement = ts.setTextRange(ts.createExpressionStatement(e), /*location*/ member);
            ts.setOriginalNode(statement, member);
            ts.setCommentRange(statement, commentRange);
            // The location for the statement is used to emit comments only.
            // No source map should be emitted for this statement to align with the
            // old emitter.
            ts.setEmitFlags(statement, 48 /* NoSourceMap */);
            return statement;
        }
        /**
         * Transforms a set of related of get/set accessors into a statement for a class body function.
         *
         * @param receiver The receiver for the member.
         * @param accessors The set of related get/set accessors.
         */
        function transformAccessorsToStatement(receiver, accessors, container) {
            var statement = ts.createExpressionStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false));
            // The location for the statement is used to emit source maps only.
            // No comments should be emitted for this statement to align with the
            // old emitter.
            ts.setEmitFlags(statement, 1536 /* NoComments */);
            ts.setSourceMapRange(statement, ts.getSourceMapRange(accessors.firstAccessor));
            return statement;
        }
        /**
         * Transforms a set of related get/set accessors into an expression for either a class
         * body function or an ObjectLiteralExpression with computed properties.
         *
         * @param receiver The receiver for the member.
         */
        function transformAccessorsToExpression(receiver, _a, container, startsOnNewLine) {
            var firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor;
            // To align with source maps in the old emitter, the receiver and property name
            // arguments are both mapped contiguously to the accessor name.
            var target = ts.getMutableClone(receiver);
            ts.setEmitFlags(target, 1536 /* NoComments */ | 32 /* NoTrailingSourceMap */);
            ts.setSourceMapRange(target, firstAccessor.name);
            var visitedAccessorName = ts.visitNode(firstAccessor.name, visitor, ts.isPropertyName);
            if (ts.isPrivateIdentifier(visitedAccessorName)) {
                return ts.Debug.failBadSyntaxKind(visitedAccessorName, "Encountered unhandled private identifier while transforming ES2015.");
            }
            var propertyName = ts.createExpressionForPropertyName(visitedAccessorName);
            ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 16 /* NoLeadingSourceMap */);
            ts.setSourceMapRange(propertyName, firstAccessor.name);
            var properties = [];
            if (getAccessor) {
                var getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined, container);
                ts.setSourceMapRange(getterFunction, ts.getSourceMapRange(getAccessor));
                ts.setEmitFlags(getterFunction, 512 /* NoLeadingComments */);
                var getter = ts.createPropertyAssignment("get", getterFunction);
                ts.setCommentRange(getter, ts.getCommentRange(getAccessor));
                properties.push(getter);
            }
            if (setAccessor) {
                var setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined, container);
                ts.setSourceMapRange(setterFunction, ts.getSourceMapRange(setAccessor));
                ts.setEmitFlags(setterFunction, 512 /* NoLeadingComments */);
                var setter = ts.createPropertyAssignment("set", setterFunction);
                ts.setCommentRange(setter, ts.getCommentRange(setAccessor));
                properties.push(setter);
            }
            properties.push(ts.createPropertyAssignment("enumerable", getAccessor || setAccessor ? ts.createFalse() : ts.createTrue()), ts.createPropertyAssignment("configurable", ts.createTrue()));
            var call = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                target,
                propertyName,
                ts.createObjectLiteral(properties, /*multiLine*/ true)
            ]);
            if (startsOnNewLine) {
                ts.startOnNewLine(call);
            }
            return call;
        }
        /**
         * Visits an ArrowFunction and transforms it into a FunctionExpression.
         *
         * @param node An ArrowFunction node.
         */
        function visitArrowFunction(node) {
            if (node.transformFlags & 4096 /* ContainsLexicalThis */) {
                hierarchyFacts |= 32768 /* CapturedLexicalThis */;
            }
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(15232 /* ArrowFunctionExcludes */, 66 /* ArrowFunctionIncludes */);
            var func = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
            /*type*/ undefined, transformFunctionBody(node));
            ts.setTextRange(func, node);
            ts.setOriginalNode(func, node);
            ts.setEmitFlags(func, 8 /* CapturesThis */);
            if (hierarchyFacts & 32768 /* CapturedLexicalThis */) {
                enableSubstitutionsForCapturedThis();
            }
            // If an arrow function contains
            exitSubtree(ancestorFacts, 0 /* ArrowFunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return func;
        }
        /**
         * Visits a FunctionExpression node.
         *
         * @param node a FunctionExpression node.
         */
        function visitFunctionExpression(node) {
            var ancestorFacts = ts.getEmitFlags(node) & 262144 /* AsyncFunctionBody */
                ? enterSubtree(16278 /* AsyncFunctionBodyExcludes */, 69 /* AsyncFunctionBodyIncludes */)
                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            var name = hierarchyFacts & 16384 /* NewTarget */
                ? ts.getLocalName(node)
                : node.name;
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.updateFunctionExpression(node, 
            /*modifiers*/ undefined, node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body);
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * @param node a FunctionDeclaration node.
         */
        function visitFunctionDeclaration(node) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            var name = hierarchyFacts & 16384 /* NewTarget */
                ? ts.getLocalName(node)
                : node.name;
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.updateFunctionDeclaration(node, 
            /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body);
        }
        /**
         * Transforms a function-like node into a FunctionExpression.
         *
         * @param node The function-like node to transform.
         * @param location The source-map location for the new FunctionExpression.
         * @param name The name of the new FunctionExpression.
         */
        function transformFunctionLikeToExpression(node, location, name, container) {
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = container && ts.isClassLike(container) && !ts.hasModifier(node, 32 /* Static */)
                ? enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */ | 8 /* NonStaticClassElement */)
                : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            if (hierarchyFacts & 16384 /* NewTarget */ && !name && (node.kind === 244 /* FunctionDeclaration */ || node.kind === 201 /* FunctionExpression */)) {
                name = ts.getGeneratedNameForNode(node);
            }
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
            /*modifiers*/ undefined, node.asteriskToken, name, 
            /*typeParameters*/ undefined, parameters, 
            /*type*/ undefined, body), location), 
            /*original*/ node);
        }
        /**
         * Transforms the body of a function-like node.
         *
         * @param node A function-like node.
         */
        function transformFunctionBody(node) {
            var multiLine = false; // indicates whether the block *must* be emitted as multiple lines
            var singleLine = false; // indicates whether the block *may* be emitted as a single line
            var statementsLocation;
            var closeBraceLocation;
            var prologue = [];
            var statements = [];
            var body = node.body;
            var statementOffset;
            resumeLexicalEnvironment();
            if (ts.isBlock(body)) {
                // ensureUseStrict is false because no new prologue-directive should be added.
                // addStandardPrologue will put already-existing directives at the beginning of the target statement-array
                statementOffset = ts.addStandardPrologue(prologue, body.statements, /*ensureUseStrict*/ false);
                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor, ts.isHoistedFunction);
                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor, ts.isHoistedVariableStatement);
            }
            multiLine = addDefaultValueAssignmentsIfNeeded(statements, node) || multiLine;
            multiLine = addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false) || multiLine;
            if (ts.isBlock(body)) {
                // addCustomPrologue puts already-existing directives at the beginning of the target statement-array
                statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor);
                statementsLocation = body.statements;
                ts.addRange(statements, ts.visitNodes(body.statements, visitor, ts.isStatement, statementOffset));
                // If the original body was a multi-line block, this must be a multi-line block.
                if (!multiLine && body.multiLine) {
                    multiLine = true;
                }
            }
            else {
                ts.Debug.assert(node.kind === 202 /* ArrowFunction */);
                // To align with the old emitter, we use a synthetic end position on the location
                // for the statement list we synthesize when we down-level an arrow function with
                // an expression function body. This prevents both comments and source maps from
                // being emitted for the end position only.
                statementsLocation = ts.moveRangeEnd(body, -1);
                var equalsGreaterThanToken = node.equalsGreaterThanToken;
                if (!ts.nodeIsSynthesized(equalsGreaterThanToken) && !ts.nodeIsSynthesized(body)) {
                    if (ts.rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) {
                        singleLine = true;
                    }
                    else {
                        multiLine = true;
                    }
                }
                var expression = ts.visitNode(body, visitor, ts.isExpression);
                var returnStatement = ts.createReturn(expression);
                ts.setTextRange(returnStatement, body);
                ts.moveSyntheticComments(returnStatement, body);
                ts.setEmitFlags(returnStatement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1024 /* NoTrailingComments */);
                statements.push(returnStatement);
                // To align with the source map emit for the old emitter, we set a custom
                // source map location for the close brace.
                closeBraceLocation = body;
            }
            ts.mergeLexicalEnvironment(prologue, endLexicalEnvironment());
            insertCaptureNewTargetIfNeeded(prologue, node, /*copyOnWrite*/ false);
            insertCaptureThisForNodeIfNeeded(prologue, node);
            // If we added any final generated statements, this must be a multi-line block
            if (ts.some(prologue)) {
                multiLine = true;
            }
            statements.unshift.apply(statements, prologue);
            if (ts.isBlock(body) && ts.arrayIsEqualTo(statements, body.statements)) {
                // no changes were made, preserve the tree
                return body;
            }
            var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), multiLine);
            ts.setTextRange(block, node.body);
            if (!multiLine && singleLine) {
                ts.setEmitFlags(block, 1 /* SingleLine */);
            }
            if (closeBraceLocation) {
                ts.setTokenSourceMapRange(block, 19 /* CloseBraceToken */, closeBraceLocation);
            }
            ts.setOriginalNode(block, node.body);
            return block;
        }
        function visitBlock(node, isFunctionBody) {
            if (isFunctionBody) {
                // A function body is not a block scope.
                return ts.visitEachChild(node, visitor, context);
            }
            var ancestorFacts = hierarchyFacts & 256 /* IterationStatement */
                ? enterSubtree(7104 /* IterationStatementBlockExcludes */, 512 /* IterationStatementBlockIncludes */)
                : enterSubtree(6976 /* BlockExcludes */, 128 /* BlockIncludes */);
            var updated = ts.visitEachChild(node, visitor, context);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        /**
         * Visits an ExpressionStatement that contains a destructuring assignment.
         *
         * @param node An ExpressionStatement node.
         */
        function visitExpressionStatement(node) {
            // If we are here it is most likely because our expression is a destructuring assignment.
            switch (node.expression.kind) {
                case 200 /* ParenthesizedExpression */:
                    return ts.updateExpressionStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
                case 209 /* BinaryExpression */:
                    return ts.updateExpressionStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a ParenthesizedExpression that may contain a destructuring assignment.
         *
         * @param node A ParenthesizedExpression node.
         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
         *                                of a destructuring assignment.
         */
        function visitParenthesizedExpression(node, needsDestructuringValue) {
            // If we are here it is most likely because our expression is a destructuring assignment.
            if (!needsDestructuringValue) {
                // By default we always emit the RHS at the end of a flattened destructuring
                // expression. If we are in a state where we do not need the destructuring value,
                // we pass that information along to the children that care about it.
                switch (node.expression.kind) {
                    case 200 /* ParenthesizedExpression */:
                        return ts.updateParen(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false));
                    case 209 /* BinaryExpression */:
                        return ts.updateParen(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false));
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a BinaryExpression that contains a destructuring assignment.
         *
         * @param node A BinaryExpression node.
         * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs
         *                                of a destructuring assignment.
         */
        function visitBinaryExpression(node, needsDestructuringValue) {
            // If we are here it is because this is a destructuring assignment.
            if (ts.isDestructuringAssignment(node)) {
                return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, needsDestructuringValue);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function isVariableStatementOfTypeScriptClassWrapper(node) {
            return node.declarationList.declarations.length === 1
                && !!node.declarationList.declarations[0].initializer
                && !!(ts.getEmitFlags(node.declarationList.declarations[0].initializer) & 33554432 /* TypeScriptClassWrapper */);
        }
        function visitVariableStatement(node) {
            var ancestorFacts = enterSubtree(0 /* None */, ts.hasModifier(node, 1 /* Export */) ? 32 /* ExportedVariableStatement */ : 0 /* None */);
            var updated;
            if (convertedLoopState && (node.declarationList.flags & 3 /* BlockScoped */) === 0 && !isVariableStatementOfTypeScriptClassWrapper(node)) {
                // we are inside a converted loop - hoist variable declarations
                var assignments = void 0;
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl);
                    if (decl.initializer) {
                        var assignment = void 0;
                        if (ts.isBindingPattern(decl.name)) {
                            assignment = ts.flattenDestructuringAssignment(decl, visitor, context, 0 /* All */);
                        }
                        else {
                            assignment = ts.createBinary(decl.name, 62 /* EqualsToken */, ts.visitNode(decl.initializer, visitor, ts.isExpression));
                            ts.setTextRange(assignment, decl);
                        }
                        assignments = ts.append(assignments, assignment);
                    }
                }
                if (assignments) {
                    updated = ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(assignments)), node);
                }
                else {
                    // none of declarations has initializer - the entire variable statement can be deleted
                    updated = undefined;
                }
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        /**
         * Visits a VariableDeclarationList that is block scoped (e.g. `let` or `const`).
         *
         * @param node A VariableDeclarationList node.
         */
        function visitVariableDeclarationList(node) {
            if (node.flags & 3 /* BlockScoped */ || node.transformFlags & 131072 /* ContainsBindingPattern */) {
                if (node.flags & 3 /* BlockScoped */) {
                    enableSubstitutionsForBlockScopedBindings();
                }
                var declarations = ts.flatMap(node.declarations, node.flags & 1 /* Let */
                    ? visitVariableDeclarationInLetDeclarationList
                    : visitVariableDeclaration);
                var declarationList = ts.createVariableDeclarationList(declarations);
                ts.setOriginalNode(declarationList, node);
                ts.setTextRange(declarationList, node);
                ts.setCommentRange(declarationList, node);
                // If the first or last declaration is a binding pattern, we need to modify
                // the source map range for the declaration list.
                if (node.transformFlags & 131072 /* ContainsBindingPattern */
                    && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.last(node.declarations).name))) {
                    ts.setSourceMapRange(declarationList, getRangeUnion(declarations));
                }
                return declarationList;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function getRangeUnion(declarations) {
            // declarations may not be sorted by position.
            // pos should be the minimum* position over all nodes (that's not -1), end should be the maximum end over all nodes.
            var pos = -1, end = -1;
            for (var _i = 0, declarations_10 = declarations; _i < declarations_10.length; _i++) {
                var node = declarations_10[_i];
                pos = pos === -1 ? node.pos : node.pos === -1 ? pos : Math.min(pos, node.pos);
                end = Math.max(end, node.end);
            }
            return ts.createRange(pos, end);
        }
        /**
         * Gets a value indicating whether we should emit an explicit initializer for a variable
         * declaration in a `let` declaration list.
         *
         * @param node A VariableDeclaration node.
         */
        function shouldEmitExplicitInitializerForLetDeclaration(node) {
            // Nested let bindings might need to be initialized explicitly to preserve
            // ES6 semantic:
            //
            //  { let x = 1; }
            //  { let x; } // x here should be undefined. not 1
            //
            // Top level bindings never collide with anything and thus don't require
            // explicit initialization. As for nested let bindings there are two cases:
            //
            // - Nested let bindings that were not renamed definitely should be
            //   initialized explicitly:
            //
            //    { let x = 1; }
            //    { let x; if (some-condition) { x = 1}; if (x) { /*1*/ } }
            //
            //   Without explicit initialization code in /*1*/ can be executed even if
            //   some-condition is evaluated to false.
            //
            // - Renaming introduces fresh name that should not collide with any
            //   existing names, however renamed bindings sometimes also should be
            //   explicitly initialized. One particular case: non-captured binding
            //   declared inside loop body (but not in loop initializer):
            //
            //    let x;
            //    for (;;) {
            //        let x;
            //    }
            //
            //   In downlevel codegen inner 'x' will be renamed so it won't collide
            //   with outer 'x' however it will should be reset on every iteration as
            //   if it was declared anew.
            //
            //   * Why non-captured binding?
            //     - Because if loop contains block scoped binding captured in some
            //       function then loop body will be rewritten to have a fresh scope
            //       on every iteration so everything will just work.
            //
            //   * Why loop initializer is excluded?
            //     - Since we've introduced a fresh name it already will be undefined.
            var flags = resolver.getNodeCheckFlags(node);
            var isCapturedInFunction = flags & 262144 /* CapturedBlockScopedBinding */;
            var isDeclaredInLoop = flags & 524288 /* BlockScopedBindingInLoop */;
            var emittedAsTopLevel = (hierarchyFacts & 64 /* TopLevel */) !== 0
                || (isCapturedInFunction
                    && isDeclaredInLoop
                    && (hierarchyFacts & 512 /* IterationStatementBlock */) !== 0);
            var emitExplicitInitializer = !emittedAsTopLevel
                && (hierarchyFacts & 4096 /* ForInOrForOfStatement */) === 0
                && (!resolver.isDeclarationWithCollidingName(node)
                    || (isDeclaredInLoop
                        && !isCapturedInFunction
                        && (hierarchyFacts & (2048 /* ForStatement */ | 4096 /* ForInOrForOfStatement */)) === 0));
            return emitExplicitInitializer;
        }
        /**
         * Visits a VariableDeclaration in a `let` declaration list.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclarationInLetDeclarationList(node) {
            // For binding pattern names that lack initializers there is no point to emit
            // explicit initializer since downlevel codegen for destructuring will fail
            // in the absence of initializer so all binding elements will say uninitialized
            var name = node.name;
            if (ts.isBindingPattern(name)) {
                return visitVariableDeclaration(node);
            }
            if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) {
                var clone_3 = ts.getMutableClone(node);
                clone_3.initializer = ts.createVoidZero();
                return clone_3;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a VariableDeclaration node with a binding pattern.
         *
         * @param node A VariableDeclaration node.
         */
        function visitVariableDeclaration(node) {
            var ancestorFacts = enterSubtree(32 /* ExportedVariableStatement */, 0 /* None */);
            var updated;
            if (ts.isBindingPattern(node.name)) {
                updated = ts.flattenDestructuringBinding(node, visitor, context, 0 /* All */, 
                /*value*/ undefined, (ancestorFacts & 32 /* ExportedVariableStatement */) !== 0);
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function recordLabel(node) {
            convertedLoopState.labels.set(ts.idText(node.label), true);
        }
        function resetLabel(node) {
            convertedLoopState.labels.set(ts.idText(node.label), false);
        }
        function visitLabeledStatement(node) {
            if (convertedLoopState && !convertedLoopState.labels) {
                convertedLoopState.labels = ts.createMap();
            }
            var statement = ts.unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
            return ts.isIterationStatement(statement, /*lookInLabeledStatements*/ false)
                ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node)
                : ts.restoreEnclosingLabel(ts.visitNode(statement, visitor, ts.isStatement, ts.liftToBlock), node, convertedLoopState && resetLabel);
        }
        function visitIterationStatement(node, outermostLabeledStatement) {
            switch (node.kind) {
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                    return visitDoOrWhileStatement(node, outermostLabeledStatement);
                case 230 /* ForStatement */:
                    return visitForStatement(node, outermostLabeledStatement);
                case 231 /* ForInStatement */:
                    return visitForInStatement(node, outermostLabeledStatement);
                case 232 /* ForOfStatement */:
                    return visitForOfStatement(node, outermostLabeledStatement);
            }
        }
        function visitIterationStatementWithFacts(excludeFacts, includeFacts, node, outermostLabeledStatement, convert) {
            var ancestorFacts = enterSubtree(excludeFacts, includeFacts);
            var updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert);
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function visitDoOrWhileStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(0 /* DoOrWhileStatementExcludes */, 1280 /* DoOrWhileStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(5056 /* ForStatementExcludes */, 3328 /* ForStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForInStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(3008 /* ForInOrForOfStatementExcludes */, 5376 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement);
        }
        function visitForOfStatement(node, outermostLabeledStatement) {
            return visitIterationStatementWithFacts(3008 /* ForInOrForOfStatementExcludes */, 5376 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement, compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray);
        }
        function convertForOfStatementHead(node, boundValue, convertedLoopBodyStatements) {
            var statements = [];
            var initializer = node.initializer;
            if (ts.isVariableDeclarationList(initializer)) {
                if (node.initializer.flags & 3 /* BlockScoped */) {
                    enableSubstitutionsForBlockScopedBindings();
                }
                var firstOriginalDeclaration = ts.firstOrUndefined(initializer.declarations);
                if (firstOriginalDeclaration && ts.isBindingPattern(firstOriginalDeclaration.name)) {
                    // This works whether the declaration is a var, let, or const.
                    // It will use rhsIterationValue _a[_i] as the initializer.
                    var declarations = ts.flattenDestructuringBinding(firstOriginalDeclaration, visitor, context, 0 /* All */, boundValue);
                    var declarationList = ts.setTextRange(ts.createVariableDeclarationList(declarations), node.initializer);
                    ts.setOriginalNode(declarationList, node.initializer);
                    // Adjust the source map range for the first declaration to align with the old
                    // emitter.
                    ts.setSourceMapRange(declarationList, ts.createRange(declarations[0].pos, ts.last(declarations).end));
                    statements.push(ts.createVariableStatement(
                    /*modifiers*/ undefined, declarationList));
                }
                else {
                    // The following call does not include the initializer, so we have
                    // to emit it separately.
                    statements.push(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(firstOriginalDeclaration ? firstOriginalDeclaration.name : ts.createTempVariable(/*recordTempVariable*/ undefined), 
                        /*type*/ undefined, boundValue)
                    ]), ts.moveRangePos(initializer, -1)), initializer)), ts.moveRangeEnd(initializer, -1)));
                }
            }
            else {
                // Initializer is an expression. Emit the expression in the body, so that it's
                // evaluated on every iteration.
                var assignment = ts.createAssignment(initializer, boundValue);
                if (ts.isDestructuringAssignment(assignment)) {
                    ts.aggregateTransformFlags(assignment);
                    statements.push(ts.createExpressionStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
                }
                else {
                    assignment.end = initializer.end;
                    statements.push(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(assignment, visitor, ts.isExpression)), ts.moveRangeEnd(initializer, -1)));
                }
            }
            if (convertedLoopBodyStatements) {
                return createSyntheticBlockForConvertedStatements(ts.addRange(statements, convertedLoopBodyStatements));
            }
            else {
                var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
                if (ts.isBlock(statement)) {
                    return ts.updateBlock(statement, ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, statement.statements)), statement.statements));
                }
                else {
                    statements.push(statement);
                    return createSyntheticBlockForConvertedStatements(statements);
                }
            }
        }
        function createSyntheticBlockForConvertedStatements(statements) {
            return ts.setEmitFlags(ts.createBlock(ts.createNodeArray(statements), 
            /*multiLine*/ true), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */);
        }
        function convertForOfStatementForArray(node, outermostLabeledStatement, convertedLoopBodyStatements) {
            // The following ES6 code:
            //
            //    for (let v of expr) { }
            //
            // should be emitted as
            //
            //    for (var _i = 0, _a = expr; _i < _a.length; _i++) {
            //        var v = _a[_i];
            //    }
            //
            // where _a and _i are temps emitted to capture the RHS and the counter,
            // respectively.
            // When the left hand side is an expression instead of a let declaration,
            // the "let v" is not emitted.
            // When the left hand side is a let/const, the v is renamed if there is
            // another v in scope.
            // Note that all assignments to the LHS are emitted in the body, including
            // all destructuring.
            // Note also that because an extra statement is needed to assign to the LHS,
            // for-of bodies are always emitted as blocks.
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            // In the case where the user wrote an identifier as the RHS, like this:
            //
            //     for (let v of arr) { }
            //
            // we don't want to emit a temporary variable for the RHS, just use it directly.
            var counter = ts.createLoopVariable();
            var rhsReference = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            // The old emitter does not emit source maps for the expression
            ts.setEmitFlags(expression, 48 /* NoSourceMap */ | ts.getEmitFlags(expression));
            var forStatement = ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(counter, /*type*/ undefined, ts.createLiteral(0)), ts.moveRangePos(node.expression, -1)),
                ts.setTextRange(ts.createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.setTextRange(ts.createLessThan(counter, ts.createPropertyAccess(rhsReference, "length")), node.expression), 
            /*incrementor*/ ts.setTextRange(ts.createPostfixIncrement(counter), node.expression), 
            /*statement*/ convertForOfStatementHead(node, ts.createElementAccess(rhsReference, counter), convertedLoopBodyStatements)), 
            /*location*/ node);
            // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
            ts.setEmitFlags(forStatement, 256 /* NoTokenTrailingSourceMaps */);
            ts.setTextRange(forStatement, node);
            return ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
        }
        function convertForOfStatementForIterable(node, outermostLabeledStatement, convertedLoopBodyStatements, ancestorFacts) {
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined);
            var errorRecord = ts.createUniqueName("e");
            var catchVariable = ts.getGeneratedNameForNode(errorRecord);
            var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined);
            var values = ts.createValuesHelper(context, expression, node.expression);
            var next = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []);
            hoistVariableDeclaration(errorRecord);
            hoistVariableDeclaration(returnMethod);
            // if we are enclosed in an outer loop ensure we reset 'errorRecord' per each iteration
            var initializer = ancestorFacts & 1024 /* IterationContainer */
                ? ts.inlineExpressions([ts.createAssignment(errorRecord, ts.createVoidZero()), values])
                : values;
            var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor(
            /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([
                ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, initializer), node.expression),
                ts.createVariableDeclaration(result, /*type*/ undefined, next)
            ]), node.expression), 2097152 /* NoHoisting */), 
            /*condition*/ ts.createLogicalNot(ts.createPropertyAccess(result, "done")), 
            /*incrementor*/ ts.createAssignment(result, next), 
            /*statement*/ convertForOfStatementHead(node, ts.createPropertyAccess(result, "value"), convertedLoopBodyStatements)), 
            /*location*/ node), 256 /* NoTokenTrailingSourceMaps */);
            return ts.createTry(ts.createBlock([
                ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel)
            ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([
                ts.createExpressionStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([
                    ts.createPropertyAssignment("error", catchVariable)
                ])))
            ]), 1 /* SingleLine */)), ts.createBlock([
                ts.createTry(
                /*tryBlock*/ ts.createBlock([
                    ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(ts.createPropertyAccess(result, "done"))), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createExpressionStatement(ts.createFunctionCall(returnMethod, iterator, []))), 1 /* SingleLine */),
                ]), 
                /*catchClause*/ undefined, 
                /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([
                    ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */)
                ]), 1 /* SingleLine */))
            ]));
        }
        /**
         * Visits an ObjectLiteralExpression with computed property names.
         *
         * @param node An ObjectLiteralExpression node.
         */
        function visitObjectLiteralExpression(node) {
            // We are here because a ComputedPropertyName was used somewhere in the expression.
            var properties = node.properties;
            var numProperties = properties.length;
            // Find the first computed property.
            // Everything until that point can be emitted as part of the initial object literal.
            var numInitialProperties = numProperties;
            var numInitialPropertiesWithoutYield = numProperties;
            for (var i = 0; i < numProperties; i++) {
                var property = properties[i];
                if ((property.transformFlags & 262144 /* ContainsYield */ && hierarchyFacts & 4 /* AsyncFunctionBody */)
                    && i < numInitialPropertiesWithoutYield) {
                    numInitialPropertiesWithoutYield = i;
                }
                if (property.name.kind === 154 /* ComputedPropertyName */) {
                    numInitialProperties = i;
                    break;
                }
            }
            if (numInitialProperties !== numProperties) {
                if (numInitialPropertiesWithoutYield < numInitialProperties) {
                    numInitialProperties = numInitialPropertiesWithoutYield;
                }
                // For computed properties, we need to create a unique handle to the object
                // literal so we can modify it without risking internal assignments tainting the object.
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                // Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
                var expressions = [];
                var assignment = ts.createAssignment(temp, ts.setEmitFlags(ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), node.multiLine), 65536 /* Indented */));
                if (node.multiLine) {
                    ts.startOnNewLine(assignment);
                }
                expressions.push(assignment);
                addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
                // We need to clone the temporary identifier so that we can write it on a
                // new line
                expressions.push(node.multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
                return ts.inlineExpressions(expressions);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function shouldConvertPartOfIterationStatement(node) {
            return (resolver.getNodeCheckFlags(node) & 131072 /* ContainsCapturedBlockScopeBinding */) !== 0;
        }
        function shouldConvertInitializerOfForStatement(node) {
            return ts.isForStatement(node) && !!node.initializer && shouldConvertPartOfIterationStatement(node.initializer);
        }
        function shouldConvertConditionOfForStatement(node) {
            return ts.isForStatement(node) && !!node.condition && shouldConvertPartOfIterationStatement(node.condition);
        }
        function shouldConvertIncrementorOfForStatement(node) {
            return ts.isForStatement(node) && !!node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
        }
        function shouldConvertIterationStatement(node) {
            return shouldConvertBodyOfIterationStatement(node)
                || shouldConvertInitializerOfForStatement(node);
        }
        function shouldConvertBodyOfIterationStatement(node) {
            return (resolver.getNodeCheckFlags(node) & 65536 /* LoopWithCapturedBlockScopedBinding */) !== 0;
        }
        /**
         * Records constituents of name for the given variable to be hoisted in the outer scope.
         */
        function hoistVariableDeclarationDeclaredInConvertedLoop(state, node) {
            if (!state.hoistedLocalVariables) {
                state.hoistedLocalVariables = [];
            }
            visit(node.name);
            function visit(node) {
                if (node.kind === 75 /* Identifier */) {
                    state.hoistedLocalVariables.push(node);
                }
                else {
                    for (var _i = 0, _a = node.elements; _i < _a.length; _i++) {
                        var element = _a[_i];
                        if (!ts.isOmittedExpression(element)) {
                            visit(element.name);
                        }
                    }
                }
            }
        }
        function convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert) {
            if (!shouldConvertIterationStatement(node)) {
                var saveAllowedNonLabeledJumps = void 0;
                if (convertedLoopState) {
                    // we get here if we are trying to emit normal loop loop inside converted loop
                    // set allowedNonLabeledJumps to Break | Continue to mark that break\continue inside the loop should be emitted as is
                    saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps;
                    convertedLoopState.allowedNonLabeledJumps = 2 /* Break */ | 4 /* Continue */;
                }
                var result = convert
                    ? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined, ancestorFacts)
                    : ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel);
                if (convertedLoopState) {
                    convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps;
                }
                return result;
            }
            var currentState = createConvertedLoopState(node);
            var statements = [];
            var outerConvertedLoopState = convertedLoopState;
            convertedLoopState = currentState;
            var initializerFunction = shouldConvertInitializerOfForStatement(node) ? createFunctionForInitializerOfForStatement(node, currentState) : undefined;
            var bodyFunction = shouldConvertBodyOfIterationStatement(node) ? createFunctionForBodyOfIterationStatement(node, currentState, outerConvertedLoopState) : undefined;
            convertedLoopState = outerConvertedLoopState;
            if (initializerFunction)
                statements.push(initializerFunction.functionDeclaration);
            if (bodyFunction)
                statements.push(bodyFunction.functionDeclaration);
            addExtraDeclarationsForConvertedLoop(statements, currentState, outerConvertedLoopState);
            if (initializerFunction) {
                statements.push(generateCallToConvertedLoopInitializer(initializerFunction.functionName, initializerFunction.containsYield));
            }
            var loop;
            if (bodyFunction) {
                if (convert) {
                    loop = convert(node, outermostLabeledStatement, bodyFunction.part, ancestorFacts);
                }
                else {
                    var clone_4 = convertIterationStatementCore(node, initializerFunction, ts.createBlock(bodyFunction.part, /*multiLine*/ true));
                    ts.aggregateTransformFlags(clone_4);
                    loop = ts.restoreEnclosingLabel(clone_4, outermostLabeledStatement, convertedLoopState && resetLabel);
                }
            }
            else {
                var clone_5 = convertIterationStatementCore(node, initializerFunction, ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
                ts.aggregateTransformFlags(clone_5);
                loop = ts.restoreEnclosingLabel(clone_5, outermostLabeledStatement, convertedLoopState && resetLabel);
            }
            statements.push(loop);
            return statements;
        }
        function convertIterationStatementCore(node, initializerFunction, convertedLoopBody) {
            switch (node.kind) {
                case 230 /* ForStatement */: return convertForStatement(node, initializerFunction, convertedLoopBody);
                case 231 /* ForInStatement */: return convertForInStatement(node, convertedLoopBody);
                case 232 /* ForOfStatement */: return convertForOfStatement(node, convertedLoopBody);
                case 228 /* DoStatement */: return convertDoStatement(node, convertedLoopBody);
                case 229 /* WhileStatement */: return convertWhileStatement(node, convertedLoopBody);
                default: return ts.Debug.failBadSyntaxKind(node, "IterationStatement expected");
            }
        }
        function convertForStatement(node, initializerFunction, convertedLoopBody) {
            var shouldConvertCondition = node.condition && shouldConvertPartOfIterationStatement(node.condition);
            var shouldConvertIncrementor = shouldConvertCondition || node.incrementor && shouldConvertPartOfIterationStatement(node.incrementor);
            return ts.updateFor(node, ts.visitNode(initializerFunction ? initializerFunction.part : node.initializer, visitor, ts.isForInitializer), ts.visitNode(shouldConvertCondition ? undefined : node.condition, visitor, ts.isExpression), ts.visitNode(shouldConvertIncrementor ? undefined : node.incrementor, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertForOfStatement(node, convertedLoopBody) {
            return ts.updateForOf(node, 
            /*awaitModifier*/ undefined, ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertForInStatement(node, convertedLoopBody) {
            return ts.updateForIn(node, ts.visitNode(node.initializer, visitor, ts.isForInitializer), ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function convertDoStatement(node, convertedLoopBody) {
            return ts.updateDo(node, convertedLoopBody, ts.visitNode(node.expression, visitor, ts.isExpression));
        }
        function convertWhileStatement(node, convertedLoopBody) {
            return ts.updateWhile(node, ts.visitNode(node.expression, visitor, ts.isExpression), convertedLoopBody);
        }
        function createConvertedLoopState(node) {
            var loopInitializer;
            switch (node.kind) {
                case 230 /* ForStatement */:
                case 231 /* ForInStatement */:
                case 232 /* ForOfStatement */:
                    var initializer = node.initializer;
                    if (initializer && initializer.kind === 243 /* VariableDeclarationList */) {
                        loopInitializer = initializer;
                    }
                    break;
            }
            // variables that will be passed to the loop as parameters
            var loopParameters = [];
            // variables declared in the loop initializer that will be changed inside the loop
            var loopOutParameters = [];
            if (loopInitializer && (ts.getCombinedNodeFlags(loopInitializer) & 3 /* BlockScoped */)) {
                var hasCapturedBindingsInForInitializer = shouldConvertInitializerOfForStatement(node);
                for (var _i = 0, _a = loopInitializer.declarations; _i < _a.length; _i++) {
                    var decl = _a[_i];
                    processLoopVariableDeclaration(node, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
                }
            }
            var currentState = { loopParameters: loopParameters, loopOutParameters: loopOutParameters };
            if (convertedLoopState) {
                // convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop.
                // if outer converted loop has already accumulated some state - pass it through
                if (convertedLoopState.argumentsName) {
                    // outer loop has already used 'arguments' so we've already have some name to alias it
                    // use the same name in all nested loops
                    currentState.argumentsName = convertedLoopState.argumentsName;
                }
                if (convertedLoopState.thisName) {
                    // outer loop has already used 'this' so we've already have some name to alias it
                    // use the same name in all nested loops
                    currentState.thisName = convertedLoopState.thisName;
                }
                if (convertedLoopState.hoistedLocalVariables) {
                    // we've already collected some non-block scoped variable declarations in enclosing loop
                    // use the same storage in nested loop
                    currentState.hoistedLocalVariables = convertedLoopState.hoistedLocalVariables;
                }
            }
            return currentState;
        }
        function addExtraDeclarationsForConvertedLoop(statements, state, outerState) {
            var extraVariableDeclarations;
            // propagate state from the inner loop to the outer loop if necessary
            if (state.argumentsName) {
                // if alias for arguments is set
                if (outerState) {
                    // pass it to outer converted loop
                    outerState.argumentsName = state.argumentsName;
                }
                else {
                    // this is top level converted loop and we need to create an alias for 'arguments' object
                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(state.argumentsName, 
                    /*type*/ undefined, ts.createIdentifier("arguments")));
                }
            }
            if (state.thisName) {
                // if alias for this is set
                if (outerState) {
                    // pass it to outer converted loop
                    outerState.thisName = state.thisName;
                }
                else {
                    // this is top level converted loop so we need to create an alias for 'this' here
                    // NOTE:
                    // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set.
                    // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'.
                    (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(state.thisName, 
                    /*type*/ undefined, ts.createIdentifier("this")));
                }
            }
            if (state.hoistedLocalVariables) {
                // if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later
                if (outerState) {
                    // pass them to outer converted loop
                    outerState.hoistedLocalVariables = state.hoistedLocalVariables;
                }
                else {
                    if (!extraVariableDeclarations) {
                        extraVariableDeclarations = [];
                    }
                    // hoist collected variable declarations
                    for (var _i = 0, _a = state.hoistedLocalVariables; _i < _a.length; _i++) {
                        var identifier = _a[_i];
                        extraVariableDeclarations.push(ts.createVariableDeclaration(identifier));
                    }
                }
            }
            // add extra variables to hold out parameters if necessary
            if (state.loopOutParameters.length) {
                if (!extraVariableDeclarations) {
                    extraVariableDeclarations = [];
                }
                for (var _b = 0, _c = state.loopOutParameters; _b < _c.length; _b++) {
                    var outParam = _c[_b];
                    extraVariableDeclarations.push(ts.createVariableDeclaration(outParam.outParamName));
                }
            }
            if (state.conditionVariable) {
                if (!extraVariableDeclarations) {
                    extraVariableDeclarations = [];
                }
                extraVariableDeclarations.push(ts.createVariableDeclaration(state.conditionVariable, /*type*/ undefined, ts.createFalse()));
            }
            // create variable statement to hold all introduced variable declarations
            if (extraVariableDeclarations) {
                statements.push(ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList(extraVariableDeclarations)));
            }
        }
        function createOutVariable(p) {
            return ts.createVariableDeclaration(p.originalName, /*type*/ undefined, p.outParamName);
        }
        /**
         * Creates a `_loop_init` function for a `ForStatement` with a block-scoped initializer
         * that is captured in a closure inside of the initializer. The `_loop_init` function is
         * used to preserve the per-iteration environment semantics of
         * [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
         */
        function createFunctionForInitializerOfForStatement(node, currentState) {
            var functionName = ts.createUniqueName("_loop_init");
            var containsYield = (node.initializer.transformFlags & 262144 /* ContainsYield */) !== 0;
            var emitFlags = 0 /* None */;
            if (currentState.containsLexicalThis)
                emitFlags |= 8 /* CapturesThis */;
            if (containsYield && hierarchyFacts & 4 /* AsyncFunctionBody */)
                emitFlags |= 262144 /* AsyncFunctionBody */;
            var statements = [];
            statements.push(ts.createVariableStatement(/*modifiers*/ undefined, node.initializer));
            copyOutParameters(currentState.loopOutParameters, 2 /* Initializer */, 1 /* ToOutParameter */, statements);
            // This transforms the following ES2015 syntax:
            //
            //  for (let i = (setImmediate(() => console.log(i)), 0); i < 2; i++) {
            //      // loop body
            //  }
            //
            // Into the following ES5 syntax:
            //
            //  var _loop_init_1 = function () {
            //      var i = (setImmediate(() => console.log(i)), 0);
            //      out_i_1 = i;
            //  };
            //  var out_i_1;
            //  _loop_init_1();
            //  for (var i = out_i_1; i < 2; i++) {
            //      // loop body
            //  }
            //
            // Which prevents mutations to `i` in the per-iteration environment of the body
            // from affecting the initial value for `i` outside of the per-iteration environment.
            var functionDeclaration = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(functionName, 
                /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression(
                /*modifiers*/ undefined, containsYield ? ts.createToken(41 /* AsteriskToken */) : undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ undefined, 
                /*type*/ undefined, ts.visitNode(ts.createBlock(statements, /*multiLine*/ true), visitor, ts.isBlock)), emitFlags))
            ]), 2097152 /* NoHoisting */));
            var part = ts.createVariableDeclarationList(ts.map(currentState.loopOutParameters, createOutVariable));
            return { functionName: functionName, containsYield: containsYield, functionDeclaration: functionDeclaration, part: part };
        }
        /**
         * Creates a `_loop` function for an `IterationStatement` with a block-scoped initializer
         * that is captured in a closure inside of the loop body. The `_loop` function is used to
         * preserve the per-iteration environment semantics of
         * [13.7.4.8 RS: ForBodyEvaluation](https://tc39.github.io/ecma262/#sec-forbodyevaluation).
         */
        function createFunctionForBodyOfIterationStatement(node, currentState, outerState) {
            var functionName = ts.createUniqueName("_loop");
            startLexicalEnvironment();
            var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock);
            var lexicalEnvironment = endLexicalEnvironment();
            var statements = [];
            if (shouldConvertConditionOfForStatement(node) || shouldConvertIncrementorOfForStatement(node)) {
                // If a block-scoped variable declared in the initializer of `node` is captured in
                // the condition or incrementor, we must move the condition and incrementor into
                // the body of the for loop.
                //
                // This transforms the following ES2015 syntax:
                //
                //  for (let i = 0; setImmediate(() => console.log(i)), i < 2; setImmediate(() => console.log(i)), i++) {
                //      // loop body
                //  }
                //
                // Into the following ES5 syntax:
                //
                //  var _loop_1 = function (i) {
                //      if (inc_1)
                //          setImmediate(() => console.log(i)), i++;
                //      else
                //          inc_1 = true;
                //      if (!(setImmediate(() => console.log(i)), i < 2))
                //          return out_i_1 = i, "break";
                //      // loop body
                //      out_i_1 = i;
                //  }
                //  var out_i_1, inc_1 = false;
                //  for (var i = 0;;) {
                //      var state_1 = _loop_1(i);
                //      i = out_i_1;
                //      if (state_1 === "break")
                //          break;
                //  }
                //
                // Which prevents mutations to `i` in the per-iteration environment of the body
                // from affecting the value of `i` in the previous per-iteration environment.
                //
                // Note that the incrementor of a `for` loop is evaluated in a *new* per-iteration
                // environment that is carried over to the next iteration of the loop. As a result,
                // we must indicate whether this is the first evaluation of the loop body so that
                // we only evaluate the incrementor on subsequent evaluations.
                currentState.conditionVariable = ts.createUniqueName("inc");
                statements.push(ts.createIf(currentState.conditionVariable, ts.createStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), ts.createStatement(ts.createAssignment(currentState.conditionVariable, ts.createTrue()))));
                if (shouldConvertConditionOfForStatement(node)) {
                    statements.push(ts.createIf(ts.createPrefix(53 /* ExclamationToken */, ts.visitNode(node.condition, visitor, ts.isExpression)), ts.visitNode(ts.createBreak(), visitor, ts.isStatement)));
                }
            }
            if (ts.isBlock(statement)) {
                ts.addRange(statements, statement.statements);
            }
            else {
                statements.push(statement);
            }
            copyOutParameters(currentState.loopOutParameters, 1 /* Body */, 1 /* ToOutParameter */, statements);
            ts.insertStatementsAfterStandardPrologue(statements, lexicalEnvironment);
            var loopBody = ts.createBlock(statements, /*multiLine*/ true);
            if (ts.isBlock(statement))
                ts.setOriginalNode(loopBody, statement);
            var containsYield = (node.statement.transformFlags & 262144 /* ContainsYield */) !== 0;
            var emitFlags = 0;
            if (currentState.containsLexicalThis)
                emitFlags |= 8 /* CapturesThis */;
            if (containsYield && (hierarchyFacts & 4 /* AsyncFunctionBody */) !== 0)
                emitFlags |= 262144 /* AsyncFunctionBody */;
            // This transforms the following ES2015 syntax (in addition to other variations):
            //
            //  for (let i = 0; i < 2; i++) {
            //      setImmediate(() => console.log(i));
            //  }
            //
            // Into the following ES5 syntax:
            //
            //  var _loop_1 = function (i) {
            //      setImmediate(() => console.log(i));
            //  };
            //  for (var i = 0; i < 2; i++) {
            //      _loop_1(i);
            //  }
            var functionDeclaration = ts.createVariableStatement(
            /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([
                ts.createVariableDeclaration(functionName, 
                /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression(
                /*modifiers*/ undefined, containsYield ? ts.createToken(41 /* AsteriskToken */) : undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, currentState.loopParameters, 
                /*type*/ undefined, loopBody), emitFlags))
            ]), 2097152 /* NoHoisting */));
            var part = generateCallToConvertedLoop(functionName, currentState, outerState, containsYield);
            return { functionName: functionName, containsYield: containsYield, functionDeclaration: functionDeclaration, part: part };
        }
        function copyOutParameter(outParam, copyDirection) {
            var source = copyDirection === 0 /* ToOriginal */ ? outParam.outParamName : outParam.originalName;
            var target = copyDirection === 0 /* ToOriginal */ ? outParam.originalName : outParam.outParamName;
            return ts.createBinary(target, 62 /* EqualsToken */, source);
        }
        function copyOutParameters(outParams, partFlags, copyDirection, statements) {
            for (var _i = 0, outParams_1 = outParams; _i < outParams_1.length; _i++) {
                var outParam = outParams_1[_i];
                if (outParam.flags & partFlags) {
                    statements.push(ts.createExpressionStatement(copyOutParameter(outParam, copyDirection)));
                }
            }
        }
        function generateCallToConvertedLoopInitializer(initFunctionExpressionName, containsYield) {
            var call = ts.createCall(initFunctionExpressionName, /*typeArguments*/ undefined, []);
            var callResult = containsYield
                ? ts.createYield(ts.createToken(41 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */))
                : call;
            return ts.createStatement(callResult);
        }
        function generateCallToConvertedLoop(loopFunctionExpressionName, state, outerState, containsYield) {
            var statements = [];
            // loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop
            // simple loops are emitted as just 'loop()';
            // NOTE: if loop uses only 'continue' it still will be emitted as simple loop
            var isSimpleLoop = !(state.nonLocalJumps & ~4 /* Continue */) &&
                !state.labeledNonLocalBreaks &&
                !state.labeledNonLocalContinues;
            var call = ts.createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, ts.map(state.loopParameters, function (p) { return p.name; }));
            var callResult = containsYield
                ? ts.createYield(ts.createToken(41 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */))
                : call;
            if (isSimpleLoop) {
                statements.push(ts.createExpressionStatement(callResult));
                copyOutParameters(state.loopOutParameters, 1 /* Body */, 0 /* ToOriginal */, statements);
            }
            else {
                var loopResultName = ts.createUniqueName("state");
                var stateVariable = ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)]));
                statements.push(stateVariable);
                copyOutParameters(state.loopOutParameters, 1 /* Body */, 0 /* ToOriginal */, statements);
                if (state.nonLocalJumps & 8 /* Return */) {
                    var returnStatement = void 0;
                    if (outerState) {
                        outerState.nonLocalJumps |= 8 /* Return */;
                        returnStatement = ts.createReturn(loopResultName);
                    }
                    else {
                        returnStatement = ts.createReturn(ts.createPropertyAccess(loopResultName, "value"));
                    }
                    statements.push(ts.createIf(ts.createBinary(ts.createTypeOf(loopResultName), 36 /* EqualsEqualsEqualsToken */, ts.createLiteral("object")), returnStatement));
                }
                if (state.nonLocalJumps & 2 /* Break */) {
                    statements.push(ts.createIf(ts.createBinary(loopResultName, 36 /* EqualsEqualsEqualsToken */, ts.createLiteral("break")), ts.createBreak()));
                }
                if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) {
                    var caseClauses = [];
                    processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerState, caseClauses);
                    processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerState, caseClauses);
                    statements.push(ts.createSwitch(loopResultName, ts.createCaseBlock(caseClauses)));
                }
            }
            return statements;
        }
        function setLabeledJump(state, isBreak, labelText, labelMarker) {
            if (isBreak) {
                if (!state.labeledNonLocalBreaks) {
                    state.labeledNonLocalBreaks = ts.createMap();
                }
                state.labeledNonLocalBreaks.set(labelText, labelMarker);
            }
            else {
                if (!state.labeledNonLocalContinues) {
                    state.labeledNonLocalContinues = ts.createMap();
                }
                state.labeledNonLocalContinues.set(labelText, labelMarker);
            }
        }
        function processLabeledJumps(table, isBreak, loopResultName, outerLoop, caseClauses) {
            if (!table) {
                return;
            }
            table.forEach(function (labelMarker, labelText) {
                var statements = [];
                // if there are no outer converted loop or outer label in question is located inside outer converted loop
                // then emit labeled break\continue
                // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do
                if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) {
                    var label = ts.createIdentifier(labelText);
                    statements.push(isBreak ? ts.createBreak(label) : ts.createContinue(label));
                }
                else {
                    setLabeledJump(outerLoop, isBreak, labelText, labelMarker);
                    statements.push(ts.createReturn(loopResultName));
                }
                caseClauses.push(ts.createCaseClause(ts.createLiteral(labelMarker), statements));
            });
        }
        function processLoopVariableDeclaration(container, decl, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer) {
            var name = decl.name;
            if (ts.isBindingPattern(name)) {
                for (var _i = 0, _a = name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        processLoopVariableDeclaration(container, element, loopParameters, loopOutParameters, hasCapturedBindingsInForInitializer);
                    }
                }
            }
            else {
                loopParameters.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
                var checkFlags = resolver.getNodeCheckFlags(decl);
                if (checkFlags & 4194304 /* NeedsLoopOutParameter */ || hasCapturedBindingsInForInitializer) {
                    var outParamName = ts.createUniqueName("out_" + ts.idText(name));
                    var flags = 0;
                    if (checkFlags & 4194304 /* NeedsLoopOutParameter */) {
                        flags |= 1 /* Body */;
                    }
                    if (ts.isForStatement(container) && container.initializer && resolver.isBindingCapturedByNode(container.initializer, decl)) {
                        flags |= 2 /* Initializer */;
                    }
                    loopOutParameters.push({ flags: flags, originalName: name, outParamName: outParamName });
                }
            }
        }
        /**
         * Adds the members of an object literal to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node An ObjectLiteralExpression node.
         * @param receiver The receiver for members of the ObjectLiteralExpression.
         * @param numInitialNonComputedProperties The number of initial properties without
         *                                        computed property names.
         */
        function addObjectLiteralMembers(expressions, node, receiver, start) {
            var properties = node.properties;
            var numProperties = properties.length;
            for (var i = start; i < numProperties; i++) {
                var property = properties[i];
                switch (property.kind) {
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        var accessors = ts.getAllAccessorDeclarations(node.properties, property);
                        if (property === accessors.firstAccessor) {
                            expressions.push(transformAccessorsToExpression(receiver, accessors, node, !!node.multiLine));
                        }
                        break;
                    case 161 /* MethodDeclaration */:
                        expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine));
                        break;
                    case 281 /* PropertyAssignment */:
                        expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine));
                        break;
                    case 282 /* ShorthandPropertyAssignment */:
                        expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine));
                        break;
                    default:
                        ts.Debug.failBadSyntaxKind(node);
                        break;
                }
            }
        }
        /**
         * Transforms a PropertyAssignment node into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the PropertyAssignment.
         * @param property The PropertyAssignment node.
         * @param receiver The receiver for the assignment.
         */
        function transformPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.visitNode(property.initializer, visitor, ts.isExpression));
            ts.setTextRange(expression, property);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        /**
         * Transforms a ShorthandPropertyAssignment node into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the ShorthandPropertyAssignment.
         * @param property The ShorthandPropertyAssignment node.
         * @param receiver The receiver for the assignment.
         */
        function transformShorthandPropertyAssignmentToExpression(property, receiver, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.getSynthesizedClone(property.name));
            ts.setTextRange(expression, property);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        /**
         * Transforms a MethodDeclaration of an ObjectLiteralExpression into an expression.
         *
         * @param node The ObjectLiteralExpression that contains the MethodDeclaration.
         * @param method The MethodDeclaration node.
         * @param receiver The receiver for the assignment.
         */
        function transformObjectLiteralMethodDeclarationToExpression(method, receiver, container, startsOnNewLine) {
            var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(method.name, visitor, ts.isPropertyName)), transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container));
            ts.setTextRange(expression, method);
            if (startsOnNewLine) {
                ts.startOnNewLine(expression);
            }
            return expression;
        }
        function visitCatchClause(node) {
            var ancestorFacts = enterSubtree(7104 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */);
            var updated;
            ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015.");
            if (ts.isBindingPattern(node.variableDeclaration.name)) {
                var temp = ts.createTempVariable(/*recordTempVariable*/ undefined);
                var newVariableDeclaration = ts.createVariableDeclaration(temp);
                ts.setTextRange(newVariableDeclaration, node.variableDeclaration);
                var vars = ts.flattenDestructuringBinding(node.variableDeclaration, visitor, context, 0 /* All */, temp);
                var list = ts.createVariableDeclarationList(vars);
                ts.setTextRange(list, node.variableDeclaration);
                var destructure = ts.createVariableStatement(/*modifiers*/ undefined, list);
                updated = ts.updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
            }
            else {
                updated = ts.visitEachChild(node, visitor, context);
            }
            exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
            return updated;
        }
        function addStatementToStartOfBlock(block, statement) {
            var transformedStatements = ts.visitNodes(block.statements, visitor, ts.isStatement);
            return ts.updateBlock(block, __spreadArrays([statement], transformedStatements));
        }
        /**
         * Visits a MethodDeclaration of an ObjectLiteralExpression and transforms it into a
         * PropertyAssignment.
         *
         * @param node A MethodDeclaration node.
         */
        function visitMethodDeclaration(node) {
            // We should only get here for methods on an object literal with regular identifier names.
            // Methods on classes are handled in visitClassDeclaration/visitClassExpression.
            // Methods with computed property names are handled in visitObjectLiteralExpression.
            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
            var functionExpression = transformFunctionLikeToExpression(node, /*location*/ ts.moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined);
            ts.setEmitFlags(functionExpression, 512 /* NoLeadingComments */ | ts.getEmitFlags(functionExpression));
            return ts.setTextRange(ts.createPropertyAssignment(node.name, functionExpression), 
            /*location*/ node);
        }
        /**
         * Visits an AccessorDeclaration of an ObjectLiteralExpression.
         *
         * @param node An AccessorDeclaration node.
         */
        function visitAccessorDeclaration(node) {
            ts.Debug.assert(!ts.isComputedPropertyName(node.name));
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */);
            var updated;
            var parameters = ts.visitParameterList(node.parameters, visitor, context);
            var body = transformFunctionBody(node);
            if (node.kind === 163 /* GetAccessor */) {
                updated = ts.updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body);
            }
            else {
                updated = ts.updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body);
            }
            exitSubtree(ancestorFacts, 49152 /* FunctionSubtreeExcludes */, 0 /* None */);
            convertedLoopState = savedConvertedLoopState;
            return updated;
        }
        /**
         * Visits a ShorthandPropertyAssignment and transforms it into a PropertyAssignment.
         *
         * @param node A ShorthandPropertyAssignment node.
         */
        function visitShorthandPropertyAssignment(node) {
            return ts.setTextRange(ts.createPropertyAssignment(node.name, ts.getSynthesizedClone(node.name)), 
            /*location*/ node);
        }
        function visitComputedPropertyName(node) {
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a YieldExpression node.
         *
         * @param node A YieldExpression node.
         */
        function visitYieldExpression(node) {
            // `yield` expressions are transformed using the generators transformer.
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits an ArrayLiteralExpression that contains a spread element.
         *
         * @param node An ArrayLiteralExpression node.
         */
        function visitArrayLiteralExpression(node) {
            if (ts.some(node.elements, ts.isSpreadElement)) {
                // We are here because we contain a SpreadElementExpression.
                return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, !!node.multiLine, /*hasTrailingComma*/ !!node.elements.hasTrailingComma);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a CallExpression that contains either a spread element or `super`.
         *
         * @param node a CallExpression.
         */
        function visitCallExpression(node) {
            if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) {
                return visitTypeScriptClassWrapper(node);
            }
            var expression = ts.skipOuterExpressions(node.expression);
            if (expression.kind === 102 /* SuperKeyword */ ||
                ts.isSuperProperty(expression) ||
                ts.some(node.arguments, ts.isSpreadElement)) {
                return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true);
            }
            return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), 
            /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression));
        }
        function visitTypeScriptClassWrapper(node) {
            // This is a call to a class wrapper function (an IIFE) created by the 'ts' transformer.
            // The wrapper has a form similar to:
            //
            //  (function() {
            //      class C { // 1
            //      }
            //      C.x = 1; // 2
            //      return C;
            //  }())
            //
            // When we transform the class, we end up with something like this:
            //
            //  (function () {
            //      var C = (function () { // 3
            //          function C() {
            //          }
            //          return C; // 4
            //      }());
            //      C.x = 1;
            //      return C;
            //  }())
            //
            // We want to simplify the two nested IIFEs to end up with something like this:
            //
            //  (function () {
            //      function C() {
            //      }
            //      C.x = 1;
            //      return C;
            //  }())
            // We skip any outer expressions in a number of places to get to the innermost
            // expression, but we will restore them later to preserve comments and source maps.
            var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock);
            // The class statements are the statements generated by visiting the first statement with initializer of the
            // body (1), while all other statements are added to remainingStatements (2)
            var isVariableStatementWithInitializer = function (stmt) { return ts.isVariableStatement(stmt) && !!ts.first(stmt.declarationList.declarations).initializer; };
            // visit the class body statements outside of any converted loop body.
            var savedConvertedLoopState = convertedLoopState;
            convertedLoopState = undefined;
            var bodyStatements = ts.visitNodes(body.statements, visitor, ts.isStatement);
            convertedLoopState = savedConvertedLoopState;
            var classStatements = ts.filter(bodyStatements, isVariableStatementWithInitializer);
            var remainingStatements = ts.filter(bodyStatements, function (stmt) { return !isVariableStatementWithInitializer(stmt); });
            var varStatement = ts.cast(ts.first(classStatements), ts.isVariableStatement);
            // We know there is only one variable declaration here as we verified this in an
            // earlier call to isTypeScriptClassWrapper
            var variable = varStatement.declarationList.declarations[0];
            var initializer = ts.skipOuterExpressions(variable.initializer);
            // Under certain conditions, the 'ts' transformer may introduce a class alias, which
            // we see as an assignment, for example:
            //
            //  (function () {
            //      var C_1;
            //      var C = C_1 = (function () {
            //          function C() {
            //          }
            //          C.x = function () { return C_1; }
            //          return C;
            //      }());
            //      C = C_1 = __decorate([dec], C);
            //      return C;
            //  }())
            //
            var aliasAssignment = ts.tryCast(initializer, ts.isAssignmentExpression);
            // The underlying call (3) is another IIFE that may contain a '_super' argument.
            var call = ts.cast(aliasAssignment ? ts.skipOuterExpressions(aliasAssignment.right) : initializer, ts.isCallExpression);
            var func = ts.cast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression);
            var funcStatements = func.body.statements;
            var classBodyStart = 0;
            var classBodyEnd = -1;
            var statements = [];
            if (aliasAssignment) {
                // If we have a class alias assignment, we need to move it to the down-level constructor
                // function we generated for the class.
                var extendsCall = ts.tryCast(funcStatements[classBodyStart], ts.isExpressionStatement);
                if (extendsCall) {
                    statements.push(extendsCall);
                    classBodyStart++;
                }
                // The next statement is the function declaration.
                statements.push(funcStatements[classBodyStart]);
                classBodyStart++;
                // Add the class alias following the declaration.
                statements.push(ts.createExpressionStatement(ts.createAssignment(aliasAssignment.left, ts.cast(variable.name, ts.isIdentifier))));
            }
            // Find the trailing 'return' statement (4)
            while (!ts.isReturnStatement(ts.elementAt(funcStatements, classBodyEnd))) {
                classBodyEnd--;
            }
            // When we extract the statements of the inner IIFE, we exclude the 'return' statement (4)
            // as we already have one that has been introduced by the 'ts' transformer.
            ts.addRange(statements, funcStatements, classBodyStart, classBodyEnd);
            if (classBodyEnd < -1) {
                // If there were any hoisted declarations following the return statement, we should
                // append them.
                ts.addRange(statements, funcStatements, classBodyEnd + 1);
            }
            // Add the remaining statements of the outer wrapper.
            ts.addRange(statements, remainingStatements);
            // The 'es2015' class transform may add an end-of-declaration marker. If so we will add it
            // after the remaining statements from the 'ts' transformer.
            ts.addRange(statements, classStatements, /*start*/ 1);
            // Recreate any outer parentheses or partially-emitted expressions to preserve source map
            // and comment locations.
            return ts.recreateOuterExpressions(node.expression, ts.recreateOuterExpressions(variable.initializer, ts.recreateOuterExpressions(aliasAssignment && aliasAssignment.right, ts.updateCall(call, ts.recreateOuterExpressions(call.expression, ts.updateFunctionExpression(func, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, func.parameters, 
            /*type*/ undefined, ts.updateBlock(func.body, statements))), 
            /*typeArguments*/ undefined, call.arguments))));
        }
        function visitImmediateSuperCallInBody(node) {
            return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ false);
        }
        function visitCallExpressionWithPotentialCapturedThisAssignment(node, assignToCapturedThis) {
            // We are here either because SuperKeyword was used somewhere in the expression, or
            // because we contain a SpreadElementExpression.
            if (node.transformFlags & 8192 /* ContainsRestOrSpread */ ||
                node.expression.kind === 102 /* SuperKeyword */ ||
                ts.isSuperProperty(ts.skipOuterExpressions(node.expression))) {
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                if (node.expression.kind === 102 /* SuperKeyword */) {
                    ts.setEmitFlags(thisArg, 4 /* NoSubstitution */);
                }
                var resultingCall = void 0;
                if (node.transformFlags & 8192 /* ContainsRestOrSpread */) {
                    // [source]
                    //      f(...a, b)
                    //      x.m(...a, b)
                    //      super(...a, b)
                    //      super.m(...a, b) // in static
                    //      super.m(...a, b) // in instance
                    //
                    // [output]
                    //      f.apply(void 0, a.concat([b]))
                    //      (_a = x).m.apply(_a, a.concat([b]))
                    //      _super.apply(this, a.concat([b]))
                    //      _super.m.apply(this, a.concat([b]))
                    //      _super.prototype.m.apply(this, a.concat([b]))
                    resultingCall = ts.createFunctionApply(ts.visitNode(target, callExpressionVisitor, ts.isExpression), node.expression.kind === 102 /* SuperKeyword */ ? thisArg : ts.visitNode(thisArg, visitor, ts.isExpression), transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false));
                }
                else {
                    // [source]
                    //      super(a)
                    //      super.m(a) // in static
                    //      super.m(a) // in instance
                    //
                    // [output]
                    //      _super.call(this, a)
                    //      _super.m.call(this, a)
                    //      _super.prototype.m.call(this, a)
                    resultingCall = ts.createFunctionCall(ts.visitNode(target, callExpressionVisitor, ts.isExpression), node.expression.kind === 102 /* SuperKeyword */ ? thisArg : ts.visitNode(thisArg, visitor, ts.isExpression), ts.visitNodes(node.arguments, visitor, ts.isExpression), 
                    /*location*/ node);
                }
                if (node.expression.kind === 102 /* SuperKeyword */) {
                    var initializer = ts.createLogicalOr(resultingCall, createActualThis());
                    resultingCall = assignToCapturedThis
                        ? ts.createAssignment(ts.createFileLevelUniqueName("_this"), initializer)
                        : initializer;
                }
                return ts.setOriginalNode(resultingCall, node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a NewExpression that contains a spread element.
         *
         * @param node A NewExpression node.
         */
        function visitNewExpression(node) {
            if (ts.some(node.arguments, ts.isSpreadElement)) {
                // We are here because we contain a SpreadElementExpression.
                // [source]
                //      new C(...a)
                //
                // [output]
                //      new ((_a = C).bind.apply(_a, [void 0].concat(a)))()
                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                return ts.createNew(ts.createFunctionApply(ts.visitNode(target, visitor, ts.isExpression), thisArg, transformAndSpreadElements(ts.createNodeArray(__spreadArrays([ts.createVoidZero()], node.arguments)), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)), 
                /*typeArguments*/ undefined, []);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Transforms an array of Expression nodes that contains a SpreadExpression.
         *
         * @param elements The array of Expression nodes.
         * @param needsUniqueCopy A value indicating whether to ensure that the result is a fresh array.
         * @param multiLine A value indicating whether the result should be emitted on multiple lines.
         */
        function transformAndSpreadElements(elements, needsUniqueCopy, multiLine, hasTrailingComma) {
            // [source]
            //      [a, ...b, c]
            //
            // [output (downlevelIteration)]
            //      __spread([a], b, [c])
            //
            // [output]
            //      __spreadArrays([a], b, [c])
            // Map spans of spread expressions into their expressions and spans of other
            // expressions into an array literal.
            var numElements = elements.length;
            var segments = ts.flatten(ts.spanMap(elements, partitionSpread, function (partition, visitPartition, _start, end) {
                return visitPartition(partition, multiLine, hasTrailingComma && end === numElements);
            }));
            if (compilerOptions.downlevelIteration) {
                if (segments.length === 1) {
                    var firstSegment = segments[0];
                    if (isCallToHelper(firstSegment, "___spread")) {
                        return segments[0];
                    }
                }
                return ts.createSpreadHelper(context, segments);
            }
            else {
                if (segments.length === 1) {
                    var firstSegment = segments[0];
                    if (!needsUniqueCopy
                        || isPackedArrayLiteral(firstSegment)
                        || isCallToHelper(firstSegment, "___spreadArrays")) {
                        return segments[0];
                    }
                }
                return ts.createSpreadArraysHelper(context, segments);
            }
        }
        function isPackedElement(node) {
            return !ts.isOmittedExpression(node);
        }
        function isPackedArrayLiteral(node) {
            return ts.isArrayLiteralExpression(node) && ts.every(node.elements, isPackedElement);
        }
        function isCallToHelper(firstSegment, helperName) {
            return ts.isCallExpression(firstSegment)
                && ts.isIdentifier(firstSegment.expression)
                && (ts.getEmitFlags(firstSegment.expression) & 4096 /* HelperName */)
                && firstSegment.expression.escapedText === helperName;
        }
        function partitionSpread(node) {
            return ts.isSpreadElement(node)
                ? visitSpanOfSpreads
                : visitSpanOfNonSpreads;
        }
        function visitSpanOfSpreads(chunk) {
            return ts.map(chunk, visitExpressionOfSpread);
        }
        function visitSpanOfNonSpreads(chunk, multiLine, hasTrailingComma) {
            return ts.createArrayLiteral(ts.visitNodes(ts.createNodeArray(chunk, hasTrailingComma), visitor, ts.isExpression), multiLine);
        }
        function visitSpreadElement(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        /**
         * Transforms the expression of a SpreadExpression node.
         *
         * @param node A SpreadExpression node.
         */
        function visitExpressionOfSpread(node) {
            return ts.visitNode(node.expression, visitor, ts.isExpression);
        }
        /**
         * Visits a template literal.
         *
         * @param node A template literal.
         */
        function visitTemplateLiteral(node) {
            return ts.setTextRange(ts.createLiteral(node.text), node);
        }
        /**
         * Visits a string literal with an extended unicode escape.
         *
         * @param node A string literal.
         */
        function visitStringLiteral(node) {
            if (node.hasExtendedUnicodeEscape) {
                return ts.setTextRange(ts.createLiteral(node.text), node);
            }
            return node;
        }
        /**
         * Visits a binary or octal (ES6) numeric literal.
         *
         * @param node A string literal.
         */
        function visitNumericLiteral(node) {
            if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) {
                return ts.setTextRange(ts.createNumericLiteral(node.text), node);
            }
            return node;
        }
        /**
         * Visits a TaggedTemplateExpression node.
         *
         * @param node A TaggedTemplateExpression node.
         */
        function visitTaggedTemplateExpression(node) {
            return ts.processTaggedTemplateExpression(context, node, visitor, currentSourceFile, recordTaggedTemplateString, ts.ProcessLevel.All);
        }
        /**
         * Visits a TemplateExpression node.
         *
         * @param node A TemplateExpression node.
         */
        function visitTemplateExpression(node) {
            var expressions = [];
            addTemplateHead(expressions, node);
            addTemplateSpans(expressions, node);
            // createAdd will check if each expression binds less closely than binary '+'.
            // If it does, it wraps the expression in parentheses. Otherwise, something like
            //    `abc${ 1 << 2 }`
            // becomes
            //    "abc" + 1 << 2 + ""
            // which is really
            //    ("abc" + 1) << (2 + "")
            // rather than
            //    "abc" + (1 << 2) + ""
            var expression = ts.reduceLeft(expressions, ts.createAdd);
            if (ts.nodeIsSynthesized(expression)) {
                expression.pos = node.pos;
                expression.end = node.end;
            }
            return expression;
        }
        /**
         * Gets a value indicating whether we need to include the head of a TemplateExpression.
         *
         * @param node A TemplateExpression node.
         */
        function shouldAddTemplateHead(node) {
            // If this expression has an empty head literal and the first template span has a non-empty
            // literal, then emitting the empty head literal is not necessary.
            //     `${ foo } and ${ bar }`
            // can be emitted as
            //     foo + " and " + bar
            // This is because it is only required that one of the first two operands in the emit
            // output must be a string literal, so that the other operand and all following operands
            // are forced into strings.
            //
            // If the first template span has an empty literal, then the head must still be emitted.
            //     `${ foo }${ bar }`
            // must still be emitted as
            //     "" + foo + bar
            // There is always atleast one templateSpan in this code path, since
            // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral()
            ts.Debug.assert(node.templateSpans.length !== 0);
            return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0;
        }
        /**
         * Adds the head of a TemplateExpression to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node A TemplateExpression node.
         */
        function addTemplateHead(expressions, node) {
            if (!shouldAddTemplateHead(node)) {
                return;
            }
            expressions.push(ts.createLiteral(node.head.text));
        }
        /**
         * Visits and adds the template spans of a TemplateExpression to an array of expressions.
         *
         * @param expressions An array of expressions.
         * @param node A TemplateExpression node.
         */
        function addTemplateSpans(expressions, node) {
            for (var _i = 0, _a = node.templateSpans; _i < _a.length; _i++) {
                var span = _a[_i];
                expressions.push(ts.visitNode(span.expression, visitor, ts.isExpression));
                // Only emit if the literal is non-empty.
                // The binary '+' operator is left-associative, so the first string concatenation
                // with the head will force the result up to this point to be a string.
                // Emitting a '+ ""' has no semantic effect for middles and tails.
                if (span.literal.text.length !== 0) {
                    expressions.push(ts.createLiteral(span.literal.text));
                }
            }
        }
        /**
         * Visits the `super` keyword
         */
        function visitSuperKeyword(isExpressionOfCall) {
            return hierarchyFacts & 8 /* NonStaticClassElement */ && !isExpressionOfCall ? ts.createPropertyAccess(ts.createFileLevelUniqueName("_super"), "prototype") :
                ts.createFileLevelUniqueName("_super");
        }
        function visitMetaProperty(node) {
            if (node.keywordToken === 99 /* NewKeyword */ && node.name.escapedText === "target") {
                hierarchyFacts |= 16384 /* NewTarget */;
                return ts.createFileLevelUniqueName("_newTarget");
            }
            return node;
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to be printed.
         * @param emitCallback The callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (enabledSubstitutions & 1 /* CapturedThis */ && ts.isFunctionLike(node)) {
                // If we are tracking a captured `this`, keep track of the enclosing function.
                var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, ts.getEmitFlags(node) & 8 /* CapturesThis */
                    ? 65 /* FunctionIncludes */ | 16 /* CapturesThis */
                    : 65 /* FunctionIncludes */);
                previousOnEmitNode(hint, node, emitCallback);
                exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */);
                return;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Enables a more costly code path for substitutions when we determine a source file
         * contains block-scoped bindings (e.g. `let` or `const`).
         */
        function enableSubstitutionsForBlockScopedBindings() {
            if ((enabledSubstitutions & 2 /* BlockScopedBindings */) === 0) {
                enabledSubstitutions |= 2 /* BlockScopedBindings */;
                context.enableSubstitution(75 /* Identifier */);
            }
        }
        /**
         * Enables a more costly code path for substitutions when we determine a source file
         * contains a captured `this`.
         */
        function enableSubstitutionsForCapturedThis() {
            if ((enabledSubstitutions & 1 /* CapturedThis */) === 0) {
                enabledSubstitutions |= 1 /* CapturedThis */;
                context.enableSubstitution(104 /* ThisKeyword */);
                context.enableEmitNotification(162 /* Constructor */);
                context.enableEmitNotification(161 /* MethodDeclaration */);
                context.enableEmitNotification(163 /* GetAccessor */);
                context.enableEmitNotification(164 /* SetAccessor */);
                context.enableEmitNotification(202 /* ArrowFunction */);
                context.enableEmitNotification(201 /* FunctionExpression */);
                context.enableEmitNotification(244 /* FunctionDeclaration */);
            }
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint The context for the emitter.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            if (ts.isIdentifier(node)) {
                return substituteIdentifier(node);
            }
            return node;
        }
        /**
         * Hooks substitutions for non-expression identifiers.
         */
        function substituteIdentifier(node) {
            // Only substitute the identifier if we have enabled substitutions for block-scoped
            // bindings.
            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
                var original = ts.getParseTreeNode(node, ts.isIdentifier);
                if (original && isNameOfDeclarationWithCollidingName(original)) {
                    return ts.setTextRange(ts.getGeneratedNameForNode(original), node);
                }
            }
            return node;
        }
        /**
         * Determines whether a name is the name of a declaration with a colliding name.
         * NOTE: This function expects to be called with an original source tree node.
         *
         * @param node An original source tree node.
         */
        function isNameOfDeclarationWithCollidingName(node) {
            switch (node.parent.kind) {
                case 191 /* BindingElement */:
                case 245 /* ClassDeclaration */:
                case 248 /* EnumDeclaration */:
                case 242 /* VariableDeclaration */:
                    return node.parent.name === node
                        && resolver.isDeclarationWithCollidingName(node.parent);
            }
            return false;
        }
        /**
         * Substitutes an expression.
         *
         * @param node An Expression node.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 104 /* ThisKeyword */:
                    return substituteThisKeyword(node);
            }
            return node;
        }
        /**
         * Substitutes an expression identifier.
         *
         * @param node An Identifier node.
         */
        function substituteExpressionIdentifier(node) {
            if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) {
                var declaration = resolver.getReferencedDeclarationWithCollidingName(node);
                if (declaration && !(ts.isClassLike(declaration) && isPartOfClassBody(declaration, node))) {
                    return ts.setTextRange(ts.getGeneratedNameForNode(ts.getNameOfDeclaration(declaration)), node);
                }
            }
            return node;
        }
        function isPartOfClassBody(declaration, node) {
            var currentNode = ts.getParseTreeNode(node);
            if (!currentNode || currentNode === declaration || currentNode.end <= declaration.pos || currentNode.pos >= declaration.end) {
                // if the node has no correlation to a parse tree node, its definitely not
                // part of the body.
                // if the node is outside of the document range of the declaration, its
                // definitely not part of the body.
                return false;
            }
            var blockScope = ts.getEnclosingBlockScopeContainer(declaration);
            while (currentNode) {
                if (currentNode === blockScope || currentNode === declaration) {
                    // if we are in the enclosing block scope of the declaration, we are definitely
                    // not inside the class body.
                    return false;
                }
                if (ts.isClassElement(currentNode) && currentNode.parent === declaration) {
                    return true;
                }
                currentNode = currentNode.parent;
            }
            return false;
        }
        /**
         * Substitutes `this` when contained within an arrow function.
         *
         * @param node The ThisKeyword node.
         */
        function substituteThisKeyword(node) {
            if (enabledSubstitutions & 1 /* CapturedThis */
                && hierarchyFacts & 16 /* CapturesThis */) {
                return ts.setTextRange(ts.createFileLevelUniqueName("_this"), node);
            }
            return node;
        }
        function getClassMemberPrefix(node, member) {
            return ts.hasModifier(member, 32 /* Static */)
                ? ts.getInternalName(node)
                : ts.createPropertyAccess(ts.getInternalName(node), "prototype");
        }
        function hasSynthesizedDefaultSuperCall(constructor, hasExtendsClause) {
            if (!constructor || !hasExtendsClause) {
                return false;
            }
            if (ts.some(constructor.parameters)) {
                return false;
            }
            var statement = ts.firstOrUndefined(constructor.body.statements);
            if (!statement || !ts.nodeIsSynthesized(statement) || statement.kind !== 226 /* ExpressionStatement */) {
                return false;
            }
            var statementExpression = statement.expression;
            if (!ts.nodeIsSynthesized(statementExpression) || statementExpression.kind !== 196 /* CallExpression */) {
                return false;
            }
            var callTarget = statementExpression.expression;
            if (!ts.nodeIsSynthesized(callTarget) || callTarget.kind !== 102 /* SuperKeyword */) {
                return false;
            }
            var callArgument = ts.singleOrUndefined(statementExpression.arguments);
            if (!callArgument || !ts.nodeIsSynthesized(callArgument) || callArgument.kind !== 213 /* SpreadElement */) {
                return false;
            }
            var expression = callArgument.expression;
            return ts.isIdentifier(expression) && expression.escapedText === "arguments";
        }
    }
    ts.transformES2015 = transformES2015;
    function createExtendsHelper(context, name) {
        context.requestEmitHelper(ts.extendsHelper);
        return ts.createCall(ts.getUnscopedHelperName("__extends"), 
        /*typeArguments*/ undefined, [
            name,
            ts.createFileLevelUniqueName("_super")
        ]);
    }
    ts.extendsHelper = {
        name: "typescript:extends",
        importName: "__extends",
        scoped: false,
        priority: 0,
        text: "\n            var __extends = (this && this.__extends) || (function () {\n                var extendStatics = function (d, b) {\n                    extendStatics = Object.setPrototypeOf ||\n                        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n                        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n                    return extendStatics(d, b);\n                };\n\n                return function (d, b) {\n                    extendStatics(d, b);\n                    function __() { this.constructor = d; }\n                    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n                };\n            })();"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    /**
     * Transforms ES5 syntax into ES3 syntax.
     *
     * @param context Context and state information for the transformation.
     */
    function transformES5(context) {
        var compilerOptions = context.getCompilerOptions();
        // enable emit notification only if using --jsx preserve or react-native
        var previousOnEmitNode;
        var noSubstitution;
        if (compilerOptions.jsx === 1 /* Preserve */ || compilerOptions.jsx === 3 /* ReactNative */) {
            previousOnEmitNode = context.onEmitNode;
            context.onEmitNode = onEmitNode;
            context.enableEmitNotification(268 /* JsxOpeningElement */);
            context.enableEmitNotification(269 /* JsxClosingElement */);
            context.enableEmitNotification(267 /* JsxSelfClosingElement */);
            noSubstitution = [];
        }
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        context.enableSubstitution(194 /* PropertyAccessExpression */);
        context.enableSubstitution(281 /* PropertyAssignment */);
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms an ES5 source file to ES3.
         *
         * @param node A SourceFile
         */
        function transformSourceFile(node) {
            return node;
        }
        /**
         * Called by the printer just before a node is printed.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback A callback used to emit the node.
         */
        function onEmitNode(hint, node, emitCallback) {
            switch (node.kind) {
                case 268 /* JsxOpeningElement */:
                case 269 /* JsxClosingElement */:
                case 267 /* JsxSelfClosingElement */:
                    var tagName = node.tagName;
                    noSubstitution[ts.getOriginalNodeId(tagName)] = true;
                    break;
            }
            previousOnEmitNode(hint, node, emitCallback);
        }
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            if (node.id && noSubstitution && noSubstitution[node.id]) {
                return previousOnSubstituteNode(hint, node);
            }
            node = previousOnSubstituteNode(hint, node);
            if (ts.isPropertyAccessExpression(node)) {
                return substitutePropertyAccessExpression(node);
            }
            else if (ts.isPropertyAssignment(node)) {
                return substitutePropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitutes a PropertyAccessExpression whose name is a reserved word.
         *
         * @param node A PropertyAccessExpression
         */
        function substitutePropertyAccessExpression(node) {
            if (ts.isPrivateIdentifier(node.name)) {
                return node;
            }
            var literalName = trySubstituteReservedName(node.name);
            if (literalName) {
                return ts.setTextRange(ts.createElementAccess(node.expression, literalName), node);
            }
            return node;
        }
        /**
         * Substitutes a PropertyAssignment whose name is a reserved word.
         *
         * @param node A PropertyAssignment
         */
        function substitutePropertyAssignment(node) {
            var literalName = ts.isIdentifier(node.name) && trySubstituteReservedName(node.name);
            if (literalName) {
                return ts.updatePropertyAssignment(node, literalName, node.initializer);
            }
            return node;
        }
        /**
         * If an identifier name is a reserved word, returns a string literal for the name.
         *
         * @param name An Identifier
         */
        function trySubstituteReservedName(name) {
            var token = name.originalKeywordKind || (ts.nodeIsSynthesized(name) ? ts.stringToToken(ts.idText(name)) : undefined);
            if (token !== undefined && token >= 77 /* FirstReservedWord */ && token <= 112 /* LastReservedWord */) {
                return ts.setTextRange(ts.createLiteral(name), name);
            }
            return undefined;
        }
    }
    ts.transformES5 = transformES5;
})(ts || (ts = {}));
// Transforms generator functions into a compatible ES5 representation with similar runtime
// semantics. This is accomplished by first transforming the body of each generator
// function into an intermediate representation that is the compiled into a JavaScript
// switch statement.
//
// Many functions in this transformer will contain comments indicating the expected
// intermediate representation. For illustrative purposes, the following intermediate
// language is used to define this intermediate representation:
//
//  .nop                            - Performs no operation.
//  .local NAME, ...                - Define local variable declarations.
//  .mark LABEL                     - Mark the location of a label.
//  .br LABEL                       - Jump to a label. If jumping out of a protected
//                                    region, all .finally blocks are executed.
//  .brtrue LABEL, (x)              - Jump to a label IIF the expression `x` is truthy.
//                                    If jumping out of a protected region, all .finally
//                                    blocks are executed.
//  .brfalse LABEL, (x)             - Jump to a label IIF the expression `x` is falsey.
//                                    If jumping out of a protected region, all .finally
//                                    blocks are executed.
//  .yield (x)                      - Yield the value of the optional expression `x`.
//                                    Resume at the next label.
//  .yieldstar (x)                  - Delegate yield to the value of the optional
//                                    expression `x`. Resume at the next label.
//                                    NOTE: `x` must be an Iterator, not an Iterable.
//  .loop CONTINUE, BREAK           - Marks the beginning of a loop. Any "continue" or
//                                    "break" abrupt completions jump to the CONTINUE or
//                                    BREAK labels, respectively.
//  .endloop                        - Marks the end of a loop.
//  .with (x)                       - Marks the beginning of a WithStatement block, using
//                                    the supplied expression.
//  .endwith                        - Marks the end of a WithStatement.
//  .switch                         - Marks the beginning of a SwitchStatement.
//  .endswitch                      - Marks the end of a SwitchStatement.
//  .labeled NAME                   - Marks the beginning of a LabeledStatement with the
//                                    supplied name.
//  .endlabeled                     - Marks the end of a LabeledStatement.
//  .try TRY, CATCH, FINALLY, END   - Marks the beginning of a protected region, and the
//                                    labels for each block.
//  .catch (x)                      - Marks the beginning of a catch block.
//  .finally                        - Marks the beginning of a finally block.
//  .endfinally                     - Marks the end of a finally block.
//  .endtry                         - Marks the end of a protected region.
//  .throw (x)                      - Throws the value of the expression `x`.
//  .return (x)                     - Returns the value of the expression `x`.
//
// In addition, the illustrative intermediate representation introduces some special
// variables:
//
//  %sent%                          - Either returns the next value sent to the generator,
//                                    returns the result of a delegated yield, or throws
//                                    the exception sent to the generator.
//  %error%                         - Returns the value of the current exception in a
//                                    catch block.
//
// This intermediate representation is then compiled into JavaScript syntax. The resulting
// compilation output looks something like the following:
//
//  function f() {
//      var /*locals*/;
//      /*functions*/
//      return __generator(function (state) {
//          switch (state.label) {
//              /*cases per label*/
//          }
//      });
//  }
//
// Each of the above instructions corresponds to JavaScript emit similar to the following:
//
//  .local NAME                   | var NAME;
// -------------------------------|----------------------------------------------
//  .mark LABEL                   | case LABEL:
// -------------------------------|----------------------------------------------
//  .br LABEL                     |     return [3 /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .brtrue LABEL, (x)            |     if (x) return [3 /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .brfalse LABEL, (x)           |     if (!(x)) return [3, /*break*/, LABEL];
// -------------------------------|----------------------------------------------
//  .yield (x)                    |     return [4 /*yield*/, x];
//  .mark RESUME                  | case RESUME:
//      a = %sent%;               |     a = state.sent();
// -------------------------------|----------------------------------------------
//  .yieldstar (x)                |     return [5 /*yield**/, x];
//  .mark RESUME                  | case RESUME:
//      a = %sent%;               |     a = state.sent();
// -------------------------------|----------------------------------------------
//  .with (_a)                    |     with (_a) {
//      a();                      |         a();
//                                |     }
//                                |     state.label = LABEL;
//  .mark LABEL                   | case LABEL:
//                                |     with (_a) {
//      b();                      |         b();
//                                |     }
//  .endwith                      |
// -------------------------------|----------------------------------------------
//                                | case 0:
//                                |     state.trys = [];
//                                | ...
//  .try TRY, CATCH, FINALLY, END |
//  .mark TRY                     | case TRY:
//                                |     state.trys.push([TRY, CATCH, FINALLY, END]);
//  .nop                          |
//      a();                      |     a();
//  .br END                       |     return [3 /*break*/, END];
//  .catch (e)                    |
//  .mark CATCH                   | case CATCH:
//                                |     e = state.sent();
//      b();                      |     b();
//  .br END                       |     return [3 /*break*/, END];
//  .finally                      |
//  .mark FINALLY                 | case FINALLY:
//      c();                      |     c();
//  .endfinally                   |     return [7 /*endfinally*/];
//  .endtry                       |
//  .mark END                     | case END:
/*@internal*/
var ts;
(function (ts) {
    var OpCode;
    (function (OpCode) {
        OpCode[OpCode["Nop"] = 0] = "Nop";
        OpCode[OpCode["Statement"] = 1] = "Statement";
        OpCode[OpCode["Assign"] = 2] = "Assign";
        OpCode[OpCode["Break"] = 3] = "Break";
        OpCode[OpCode["BreakWhenTrue"] = 4] = "BreakWhenTrue";
        OpCode[OpCode["BreakWhenFalse"] = 5] = "BreakWhenFalse";
        OpCode[OpCode["Yield"] = 6] = "Yield";
        OpCode[OpCode["YieldStar"] = 7] = "YieldStar";
        OpCode[OpCode["Return"] = 8] = "Return";
        OpCode[OpCode["Throw"] = 9] = "Throw";
        OpCode[OpCode["Endfinally"] = 10] = "Endfinally"; // Marks the end of a `finally` block
    })(OpCode || (OpCode = {}));
    // whether a generated code block is opening or closing at the current operation for a FunctionBuilder
    var BlockAction;
    (function (BlockAction) {
        BlockAction[BlockAction["Open"] = 0] = "Open";
        BlockAction[BlockAction["Close"] = 1] = "Close";
    })(BlockAction || (BlockAction = {}));
    // the kind for a generated code block in a FunctionBuilder
    var CodeBlockKind;
    (function (CodeBlockKind) {
        CodeBlockKind[CodeBlockKind["Exception"] = 0] = "Exception";
        CodeBlockKind[CodeBlockKind["With"] = 1] = "With";
        CodeBlockKind[CodeBlockKind["Switch"] = 2] = "Switch";
        CodeBlockKind[CodeBlockKind["Loop"] = 3] = "Loop";
        CodeBlockKind[CodeBlockKind["Labeled"] = 4] = "Labeled";
    })(CodeBlockKind || (CodeBlockKind = {}));
    // the state for a generated code exception block
    var ExceptionBlockState;
    (function (ExceptionBlockState) {
        ExceptionBlockState[ExceptionBlockState["Try"] = 0] = "Try";
        ExceptionBlockState[ExceptionBlockState["Catch"] = 1] = "Catch";
        ExceptionBlockState[ExceptionBlockState["Finally"] = 2] = "Finally";
        ExceptionBlockState[ExceptionBlockState["Done"] = 3] = "Done";
    })(ExceptionBlockState || (ExceptionBlockState = {}));
    // NOTE: changes to this enum should be reflected in the __generator helper.
    var Instruction;
    (function (Instruction) {
        Instruction[Instruction["Next"] = 0] = "Next";
        Instruction[Instruction["Throw"] = 1] = "Throw";
        Instruction[Instruction["Return"] = 2] = "Return";
        Instruction[Instruction["Break"] = 3] = "Break";
        Instruction[Instruction["Yield"] = 4] = "Yield";
        Instruction[Instruction["YieldStar"] = 5] = "YieldStar";
        Instruction[Instruction["Catch"] = 6] = "Catch";
        Instruction[Instruction["Endfinally"] = 7] = "Endfinally";
    })(Instruction || (Instruction = {}));
    function getInstructionName(instruction) {
        switch (instruction) {
            case 2 /* Return */: return "return";
            case 3 /* Break */: return "break";
            case 4 /* Yield */: return "yield";
            case 5 /* YieldStar */: return "yield*";
            case 7 /* Endfinally */: return "endfinally";
            default: return undefined; // TODO: GH#18217
        }
    }
    function transformGenerators(context) {
        var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistFunctionDeclaration = context.hoistFunctionDeclaration, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var resolver = context.getEmitResolver();
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onSubstituteNode = onSubstituteNode;
        var renamedCatchVariables;
        var renamedCatchVariableDeclarations;
        var inGeneratorFunctionBody;
        var inStatementContainingYield;
        // The following three arrays store information about generated code blocks.
        // All three arrays are correlated by their index. This approach is used over allocating
        // objects to store the same information to avoid GC overhead.
        //
        var blocks; // Information about the code block
        var blockOffsets; // The operation offset at which a code block begins or ends
        var blockActions; // Whether the code block is opened or closed
        var blockStack; // A stack of currently open code blocks
        // Labels are used to mark locations in the code that can be the target of a Break (jump)
        // operation. These are translated into case clauses in a switch statement.
        // The following two arrays are correlated by their index. This approach is used over
        // allocating objects to store the same information to avoid GC overhead.
        //
        var labelOffsets; // The operation offset at which the label is defined.
        var labelExpressions; // The NumericLiteral nodes bound to each label.
        var nextLabelId = 1; // The next label id to use.
        // Operations store information about generated code for the function body. This
        // Includes things like statements, assignments, breaks (jumps), and yields.
        // The following three arrays are correlated by their index. This approach is used over
        // allocating objects to store the same information to avoid GC overhead.
        //
        var operations; // The operation to perform.
        var operationArguments; // The arguments to the operation.
        var operationLocations; // The source map location for the operation.
        var state; // The name of the state object used by the generator at runtime.
        // The following variables store information used by the `build` function:
        //
        var blockIndex = 0; // The index of the current block.
        var labelNumber = 0; // The current label number.
        var labelNumbers;
        var lastOperationWasAbrupt; // Indicates whether the last operation was abrupt (break/continue).
        var lastOperationWasCompletion; // Indicates whether the last operation was a completion (return/throw).
        var clauses; // The case clauses generated for labels.
        var statements; // The statements for the current label.
        var exceptionBlockStack; // A stack of containing exception blocks.
        var currentExceptionBlock; // The current exception block.
        var withBlockStack; // A stack containing `with` blocks.
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile || (node.transformFlags & 512 /* ContainsGenerator */) === 0) {
                return node;
            }
            var visited = ts.visitEachChild(node, visitor, context);
            ts.addEmitHelpers(visited, context.readEmitHelpers());
            return visited;
        }
        /**
         * Visits a node.
         *
         * @param node The node to visit.
         */
        function visitor(node) {
            var transformFlags = node.transformFlags;
            if (inStatementContainingYield) {
                return visitJavaScriptInStatementContainingYield(node);
            }
            else if (inGeneratorFunctionBody) {
                return visitJavaScriptInGeneratorFunctionBody(node);
            }
            else if (ts.isFunctionLikeDeclaration(node) && node.asteriskToken) {
                return visitGenerator(node);
            }
            else if (transformFlags & 512 /* ContainsGenerator */) {
                return ts.visitEachChild(node, visitor, context);
            }
            else {
                return node;
            }
        }
        /**
         * Visits a node that is contained within a statement that contains yield.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptInStatementContainingYield(node) {
            switch (node.kind) {
                case 228 /* DoStatement */:
                    return visitDoStatement(node);
                case 229 /* WhileStatement */:
                    return visitWhileStatement(node);
                case 237 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 238 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                default:
                    return visitJavaScriptInGeneratorFunctionBody(node);
            }
        }
        /**
         * Visits a node that is contained within a generator function.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptInGeneratorFunctionBody(node) {
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 201 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return visitAccessorDeclaration(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 230 /* ForStatement */:
                    return visitForStatement(node);
                case 231 /* ForInStatement */:
                    return visitForInStatement(node);
                case 234 /* BreakStatement */:
                    return visitBreakStatement(node);
                case 233 /* ContinueStatement */:
                    return visitContinueStatement(node);
                case 235 /* ReturnStatement */:
                    return visitReturnStatement(node);
                default:
                    if (node.transformFlags & 262144 /* ContainsYield */) {
                        return visitJavaScriptContainingYield(node);
                    }
                    else if (node.transformFlags & (512 /* ContainsGenerator */ | 1048576 /* ContainsHoistedDeclarationOrCompletion */)) {
                        return ts.visitEachChild(node, visitor, context);
                    }
                    else {
                        return node;
                    }
            }
        }
        /**
         * Visits a node that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitJavaScriptContainingYield(node) {
            switch (node.kind) {
                case 209 /* BinaryExpression */:
                    return visitBinaryExpression(node);
                case 210 /* ConditionalExpression */:
                    return visitConditionalExpression(node);
                case 212 /* YieldExpression */:
                    return visitYieldExpression(node);
                case 192 /* ArrayLiteralExpression */:
                    return visitArrayLiteralExpression(node);
                case 193 /* ObjectLiteralExpression */:
                    return visitObjectLiteralExpression(node);
                case 195 /* ElementAccessExpression */:
                    return visitElementAccessExpression(node);
                case 196 /* CallExpression */:
                    return visitCallExpression(node);
                case 197 /* NewExpression */:
                    return visitNewExpression(node);
                default:
                    return ts.visitEachChild(node, visitor, context);
            }
        }
        /**
         * Visits a generator function.
         *
         * @param node The node to visit.
         */
        function visitGenerator(node) {
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 201 /* FunctionExpression */:
                    return visitFunctionExpression(node);
                default:
                    return ts.Debug.failBadSyntaxKind(node);
            }
        }
        /**
         * Visits a function declaration.
         *
         * This will be called when one of the following conditions are met:
         * - The function declaration is a generator function.
         * - The function declaration is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            // Currently, we only support generators that were originally async functions.
            if (node.asteriskToken) {
                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
                /*decorators*/ undefined, node.modifiers, 
                /*asteriskToken*/ undefined, node.name, 
                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
                /*location*/ node), node);
            }
            else {
                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
                var savedInStatementContainingYield = inStatementContainingYield;
                inGeneratorFunctionBody = false;
                inStatementContainingYield = false;
                node = ts.visitEachChild(node, visitor, context);
                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
                inStatementContainingYield = savedInStatementContainingYield;
            }
            if (inGeneratorFunctionBody) {
                // Function declarations in a generator function body are hoisted
                // to the top of the lexical scope and elided from the current statement.
                hoistFunctionDeclaration(node);
                return undefined;
            }
            else {
                return node;
            }
        }
        /**
         * Visits a function expression.
         *
         * This will be called when one of the following conditions are met:
         * - The function expression is a generator function.
         * - The function expression is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitFunctionExpression(node) {
            // Currently, we only support generators that were originally async functions.
            if (node.asteriskToken) {
                node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, node.name, 
                /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), 
                /*type*/ undefined, transformGeneratorFunctionBody(node.body)), 
                /*location*/ node), node);
            }
            else {
                var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
                var savedInStatementContainingYield = inStatementContainingYield;
                inGeneratorFunctionBody = false;
                inStatementContainingYield = false;
                node = ts.visitEachChild(node, visitor, context);
                inGeneratorFunctionBody = savedInGeneratorFunctionBody;
                inStatementContainingYield = savedInStatementContainingYield;
            }
            return node;
        }
        /**
         * Visits a get or set accessor declaration.
         *
         * This will be called when one of the following conditions are met:
         * - The accessor is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitAccessorDeclaration(node) {
            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
            var savedInStatementContainingYield = inStatementContainingYield;
            inGeneratorFunctionBody = false;
            inStatementContainingYield = false;
            node = ts.visitEachChild(node, visitor, context);
            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
            inStatementContainingYield = savedInStatementContainingYield;
            return node;
        }
        /**
         * Transforms the body of a generator function declaration.
         *
         * @param node The function body to transform.
         */
        function transformGeneratorFunctionBody(body) {
            // Save existing generator state
            var statements = [];
            var savedInGeneratorFunctionBody = inGeneratorFunctionBody;
            var savedInStatementContainingYield = inStatementContainingYield;
            var savedBlocks = blocks;
            var savedBlockOffsets = blockOffsets;
            var savedBlockActions = blockActions;
            var savedBlockStack = blockStack;
            var savedLabelOffsets = labelOffsets;
            var savedLabelExpressions = labelExpressions;
            var savedNextLabelId = nextLabelId;
            var savedOperations = operations;
            var savedOperationArguments = operationArguments;
            var savedOperationLocations = operationLocations;
            var savedState = state;
            // Initialize generator state
            inGeneratorFunctionBody = true;
            inStatementContainingYield = false;
            blocks = undefined;
            blockOffsets = undefined;
            blockActions = undefined;
            blockStack = undefined;
            labelOffsets = undefined;
            labelExpressions = undefined;
            nextLabelId = 1;
            operations = undefined;
            operationArguments = undefined;
            operationLocations = undefined;
            state = ts.createTempVariable(/*recordTempVariable*/ undefined);
            // Build the generator
            resumeLexicalEnvironment();
            var statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor);
            transformAndEmitStatements(body.statements, statementOffset);
            var buildResult = build();
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            statements.push(ts.createReturn(buildResult));
            // Restore previous generator state
            inGeneratorFunctionBody = savedInGeneratorFunctionBody;
            inStatementContainingYield = savedInStatementContainingYield;
            blocks = savedBlocks;
            blockOffsets = savedBlockOffsets;
            blockActions = savedBlockActions;
            blockStack = savedBlockStack;
            labelOffsets = savedLabelOffsets;
            labelExpressions = savedLabelExpressions;
            nextLabelId = savedNextLabelId;
            operations = savedOperations;
            operationArguments = savedOperationArguments;
            operationLocations = savedOperationLocations;
            state = savedState;
            return ts.setTextRange(ts.createBlock(statements, body.multiLine), body);
        }
        /**
         * Visits a variable statement.
         *
         * This will be called when one of the following conditions are met:
         * - The variable statement is contained within the body of a generator function.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            if (node.transformFlags & 262144 /* ContainsYield */) {
                transformAndEmitVariableDeclarationList(node.declarationList);
                return undefined;
            }
            else {
                // Do not hoist custom prologues.
                if (ts.getEmitFlags(node) & 1048576 /* CustomPrologue */) {
                    return node;
                }
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                var variables = ts.getInitializedVariables(node.declarationList);
                if (variables.length === 0) {
                    return undefined;
                }
                return ts.setSourceMapRange(ts.createExpressionStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node);
            }
        }
        /**
         * Visits a binary expression.
         *
         * This will be called when one of the following conditions are met:
         * - The node contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitBinaryExpression(node) {
            var assoc = ts.getExpressionAssociativity(node);
            switch (assoc) {
                case 0 /* Left */:
                    return visitLeftAssociativeBinaryExpression(node);
                case 1 /* Right */:
                    return visitRightAssociativeBinaryExpression(node);
                default:
                    return ts.Debug.assertNever(assoc);
            }
        }
        /**
         * Visits a right-associative binary expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitRightAssociativeBinaryExpression(node) {
            var left = node.left, right = node.right;
            if (containsYield(right)) {
                var target = void 0;
                switch (left.kind) {
                    case 194 /* PropertyAccessExpression */:
                        // [source]
                        //      a.b = yield;
                        //
                        // [intermediate]
                        //  .local _a
                        //      _a = a;
                        //  .yield resumeLabel
                        //  .mark resumeLabel
                        //      _a.b = %sent%;
                        target = ts.updatePropertyAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), left.name);
                        break;
                    case 195 /* ElementAccessExpression */:
                        // [source]
                        //      a[b] = yield;
                        //
                        // [intermediate]
                        //  .local _a, _b
                        //      _a = a;
                        //      _b = b;
                        //  .yield resumeLabel
                        //  .mark resumeLabel
                        //      _a[_b] = %sent%;
                        target = ts.updateElementAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), cacheExpression(ts.visitNode(left.argumentExpression, visitor, ts.isExpression)));
                        break;
                    default:
                        target = ts.visitNode(left, visitor, ts.isExpression);
                        break;
                }
                var operator = node.operatorToken.kind;
                if (ts.isCompoundAssignment(operator)) {
                    return ts.setTextRange(ts.createAssignment(target, ts.setTextRange(ts.createBinary(cacheExpression(target), ts.getNonAssignmentOperatorForCompoundAssignment(operator), ts.visitNode(right, visitor, ts.isExpression)), node)), node);
                }
                else {
                    return ts.updateBinary(node, target, ts.visitNode(right, visitor, ts.isExpression));
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitLeftAssociativeBinaryExpression(node) {
            if (containsYield(node.right)) {
                if (ts.isLogicalOperator(node.operatorToken.kind)) {
                    return visitLogicalBinaryExpression(node);
                }
                else if (node.operatorToken.kind === 27 /* CommaToken */) {
                    return visitCommaExpression(node);
                }
                // [source]
                //      a() + (yield) + c()
                //
                // [intermediate]
                //  .local _a
                //      _a = a();
                //  .yield resumeLabel
                //      _a + %sent% + c()
                var clone_6 = ts.getMutableClone(node);
                clone_6.left = cacheExpression(ts.visitNode(node.left, visitor, ts.isExpression));
                clone_6.right = ts.visitNode(node.right, visitor, ts.isExpression);
                return clone_6;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a logical binary expression containing `yield`.
         *
         * @param node A node to visit.
         */
        function visitLogicalBinaryExpression(node) {
            // Logical binary expressions (`&&` and `||`) are shortcutting expressions and need
            // to be transformed as such:
            //
            // [source]
            //      x = a() && yield;
            //
            // [intermediate]
            //  .local _a
            //      _a = a();
            //  .brfalse resultLabel, (_a)
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .mark resultLabel
            //      x = _a;
            //
            // [source]
            //      x = a() || yield;
            //
            // [intermediate]
            //  .local _a
            //      _a = a();
            //  .brtrue resultLabel, (_a)
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .mark resultLabel
            //      x = _a;
            var resultLabel = defineLabel();
            var resultLocal = declareLocal();
            emitAssignment(resultLocal, ts.visitNode(node.left, visitor, ts.isExpression), /*location*/ node.left);
            if (node.operatorToken.kind === 55 /* AmpersandAmpersandToken */) {
                // Logical `&&` shortcuts when the left-hand operand is falsey.
                emitBreakWhenFalse(resultLabel, resultLocal, /*location*/ node.left);
            }
            else {
                // Logical `||` shortcuts when the left-hand operand is truthy.
                emitBreakWhenTrue(resultLabel, resultLocal, /*location*/ node.left);
            }
            emitAssignment(resultLocal, ts.visitNode(node.right, visitor, ts.isExpression), /*location*/ node.right);
            markLabel(resultLabel);
            return resultLocal;
        }
        /**
         * Visits a comma expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitCommaExpression(node) {
            // [source]
            //      x = a(), yield, b();
            //
            // [intermediate]
            //      a();
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      x = %sent%, b();
            var pendingExpressions = [];
            visit(node.left);
            visit(node.right);
            return ts.inlineExpressions(pendingExpressions);
            function visit(node) {
                if (ts.isBinaryExpression(node) && node.operatorToken.kind === 27 /* CommaToken */) {
                    visit(node.left);
                    visit(node.right);
                }
                else {
                    if (containsYield(node) && pendingExpressions.length > 0) {
                        emitWorker(1 /* Statement */, [ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions))]);
                        pendingExpressions = [];
                    }
                    pendingExpressions.push(ts.visitNode(node, visitor, ts.isExpression));
                }
            }
        }
        /**
         * Visits a conditional expression containing `yield`.
         *
         * @param node The node to visit.
         */
        function visitConditionalExpression(node) {
            // [source]
            //      x = a() ? yield : b();
            //
            // [intermediate]
            //  .local _a
            //  .brfalse whenFalseLabel, (a())
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      _a = %sent%;
            //  .br resultLabel
            //  .mark whenFalseLabel
            //      _a = b();
            //  .mark resultLabel
            //      x = _a;
            // We only need to perform a specific transformation if a `yield` expression exists
            // in either the `whenTrue` or `whenFalse` branches.
            // A `yield` in the condition will be handled by the normal visitor.
            if (containsYield(node.whenTrue) || containsYield(node.whenFalse)) {
                var whenFalseLabel = defineLabel();
                var resultLabel = defineLabel();
                var resultLocal = declareLocal();
                emitBreakWhenFalse(whenFalseLabel, ts.visitNode(node.condition, visitor, ts.isExpression), /*location*/ node.condition);
                emitAssignment(resultLocal, ts.visitNode(node.whenTrue, visitor, ts.isExpression), /*location*/ node.whenTrue);
                emitBreak(resultLabel);
                markLabel(whenFalseLabel);
                emitAssignment(resultLocal, ts.visitNode(node.whenFalse, visitor, ts.isExpression), /*location*/ node.whenFalse);
                markLabel(resultLabel);
                return resultLocal;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        /**
         * Visits a `yield` expression.
         *
         * @param node The node to visit.
         */
        function visitYieldExpression(node) {
            // [source]
            //      x = yield a();
            //
            // [intermediate]
            //  .yield resumeLabel, (a())
            //  .mark resumeLabel
            //      x = %sent%;
            var resumeLabel = defineLabel();
            var expression = ts.visitNode(node.expression, visitor, ts.isExpression);
            if (node.asteriskToken) {
                var iterator = (ts.getEmitFlags(node.expression) & 8388608 /* Iterator */) === 0
                    ? ts.createValuesHelper(context, expression, /*location*/ node)
                    : expression;
                emitYieldStar(iterator, /*location*/ node);
            }
            else {
                emitYield(expression, /*location*/ node);
            }
            markLabel(resumeLabel);
            return createGeneratorResume(/*location*/ node);
        }
        /**
         * Visits an ArrayLiteralExpression that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitArrayLiteralExpression(node) {
            return visitElements(node.elements, /*leadingElement*/ undefined, /*location*/ undefined, node.multiLine);
        }
        /**
         * Visits an array of expressions containing one or more YieldExpression nodes
         * and returns an expression for the resulting value.
         *
         * @param elements The elements to visit.
         * @param multiLine Whether array literals created should be emitted on multiple lines.
         */
        function visitElements(elements, leadingElement, location, multiLine) {
            // [source]
            //      ar = [1, yield, 2];
            //
            // [intermediate]
            //  .local _a
            //      _a = [1];
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      ar = _a.concat([%sent%, 2]);
            var numInitialElements = countInitialNodesWithoutYield(elements);
            var temp;
            if (numInitialElements > 0) {
                temp = declareLocal();
                var initialElements = ts.visitNodes(elements, visitor, ts.isExpression, 0, numInitialElements);
                emitAssignment(temp, ts.createArrayLiteral(leadingElement
                    ? __spreadArrays([leadingElement], initialElements) : initialElements));
                leadingElement = undefined;
            }
            var expressions = ts.reduceLeft(elements, reduceElement, [], numInitialElements);
            return temp
                ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
                : ts.setTextRange(ts.createArrayLiteral(leadingElement ? __spreadArrays([leadingElement], expressions) : expressions, multiLine), location);
            function reduceElement(expressions, element) {
                if (containsYield(element) && expressions.length > 0) {
                    var hasAssignedTemp = temp !== undefined;
                    if (!temp) {
                        temp = declareLocal();
                    }
                    emitAssignment(temp, hasAssignedTemp
                        ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)])
                        : ts.createArrayLiteral(leadingElement ? __spreadArrays([leadingElement], expressions) : expressions, multiLine));
                    leadingElement = undefined;
                    expressions = [];
                }
                expressions.push(ts.visitNode(element, visitor, ts.isExpression));
                return expressions;
            }
        }
        function visitObjectLiteralExpression(node) {
            // [source]
            //      o = {
            //          a: 1,
            //          b: yield,
            //          c: 2
            //      };
            //
            // [intermediate]
            //  .local _a
            //      _a = {
            //          a: 1
            //      };
            //  .yield resumeLabel
            //  .mark resumeLabel
            //      o = (_a.b = %sent%,
            //          _a.c = 2,
            //          _a);
            var properties = node.properties;
            var multiLine = node.multiLine;
            var numInitialProperties = countInitialNodesWithoutYield(properties);
            var temp = declareLocal();
            emitAssignment(temp, ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), multiLine));
            var expressions = ts.reduceLeft(properties, reduceProperty, [], numInitialProperties);
            expressions.push(multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp);
            return ts.inlineExpressions(expressions);
            function reduceProperty(expressions, property) {
                if (containsYield(property) && expressions.length > 0) {
                    emitStatement(ts.createExpressionStatement(ts.inlineExpressions(expressions)));
                    expressions = [];
                }
                var expression = ts.createExpressionForObjectLiteralElementLike(node, property, temp);
                var visited = ts.visitNode(expression, visitor, ts.isExpression);
                if (visited) {
                    if (multiLine) {
                        ts.startOnNewLine(visited);
                    }
                    expressions.push(visited);
                }
                return expressions;
            }
        }
        /**
         * Visits an ElementAccessExpression that contains a YieldExpression.
         *
         * @param node The node to visit.
         */
        function visitElementAccessExpression(node) {
            if (containsYield(node.argumentExpression)) {
                // [source]
                //      a = x[yield];
                //
                // [intermediate]
                //  .local _a
                //      _a = x;
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      a = _a[%sent%]
                var clone_7 = ts.getMutableClone(node);
                clone_7.expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression));
                clone_7.argumentExpression = ts.visitNode(node.argumentExpression, visitor, ts.isExpression);
                return clone_7;
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitCallExpression(node) {
            if (!ts.isImportCall(node) && ts.forEach(node.arguments, containsYield)) {
                // [source]
                //      a.b(1, yield, 2);
                //
                // [intermediate]
                //  .local _a, _b, _c
                //      _b = (_a = a).b;
                //      _c = [1];
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      _b.apply(_a, _c.concat([%sent%, 2]));
                var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true), target = _a.target, thisArg = _a.thisArg;
                return ts.setOriginalNode(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isLeftHandSideExpression)), thisArg, visitElements(node.arguments), 
                /*location*/ node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function visitNewExpression(node) {
            if (ts.forEach(node.arguments, containsYield)) {
                // [source]
                //      new a.b(1, yield, 2);
                //
                // [intermediate]
                //  .local _a, _b, _c
                //      _b = (_a = a.b).bind;
                //      _c = [1];
                //  .yield resumeLabel
                //  .mark resumeLabel
                //      new (_b.apply(_a, _c.concat([%sent%, 2])));
                var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg;
                return ts.setOriginalNode(ts.setTextRange(ts.createNew(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isExpression)), thisArg, visitElements(node.arguments, 
                /*leadingElement*/ ts.createVoidZero())), 
                /*typeArguments*/ undefined, []), node), node);
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitStatements(statements, start) {
            if (start === void 0) { start = 0; }
            var numStatements = statements.length;
            for (var i = start; i < numStatements; i++) {
                transformAndEmitStatement(statements[i]);
            }
        }
        function transformAndEmitEmbeddedStatement(node) {
            if (ts.isBlock(node)) {
                transformAndEmitStatements(node.statements);
            }
            else {
                transformAndEmitStatement(node);
            }
        }
        function transformAndEmitStatement(node) {
            var savedInStatementContainingYield = inStatementContainingYield;
            if (!inStatementContainingYield) {
                inStatementContainingYield = containsYield(node);
            }
            transformAndEmitStatementWorker(node);
            inStatementContainingYield = savedInStatementContainingYield;
        }
        function transformAndEmitStatementWorker(node) {
            switch (node.kind) {
                case 223 /* Block */:
                    return transformAndEmitBlock(node);
                case 226 /* ExpressionStatement */:
                    return transformAndEmitExpressionStatement(node);
                case 227 /* IfStatement */:
                    return transformAndEmitIfStatement(node);
                case 228 /* DoStatement */:
                    return transformAndEmitDoStatement(node);
                case 229 /* WhileStatement */:
                    return transformAndEmitWhileStatement(node);
                case 230 /* ForStatement */:
                    return transformAndEmitForStatement(node);
                case 231 /* ForInStatement */:
                    return transformAndEmitForInStatement(node);
                case 233 /* ContinueStatement */:
                    return transformAndEmitContinueStatement(node);
                case 234 /* BreakStatement */:
                    return transformAndEmitBreakStatement(node);
                case 235 /* ReturnStatement */:
                    return transformAndEmitReturnStatement(node);
                case 236 /* WithStatement */:
                    return transformAndEmitWithStatement(node);
                case 237 /* SwitchStatement */:
                    return transformAndEmitSwitchStatement(node);
                case 238 /* LabeledStatement */:
                    return transformAndEmitLabeledStatement(node);
                case 239 /* ThrowStatement */:
                    return transformAndEmitThrowStatement(node);
                case 240 /* TryStatement */:
                    return transformAndEmitTryStatement(node);
                default:
                    return emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitBlock(node) {
            if (containsYield(node)) {
                transformAndEmitStatements(node.statements);
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitExpressionStatement(node) {
            emitStatement(ts.visitNode(node, visitor, ts.isStatement));
        }
        function transformAndEmitVariableDeclarationList(node) {
            for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
                var variable = _a[_i];
                var name = ts.getSynthesizedClone(variable.name);
                ts.setCommentRange(name, variable.name);
                hoistVariableDeclaration(name);
            }
            var variables = ts.getInitializedVariables(node);
            var numVariables = variables.length;
            var variablesWritten = 0;
            var pendingExpressions = [];
            while (variablesWritten < numVariables) {
                for (var i = variablesWritten; i < numVariables; i++) {
                    var variable = variables[i];
                    if (containsYield(variable.initializer) && pendingExpressions.length > 0) {
                        break;
                    }
                    pendingExpressions.push(transformInitializedVariable(variable));
                }
                if (pendingExpressions.length) {
                    emitStatement(ts.createExpressionStatement(ts.inlineExpressions(pendingExpressions)));
                    variablesWritten += pendingExpressions.length;
                    pendingExpressions = [];
                }
            }
            return undefined;
        }
        function transformInitializedVariable(node) {
            return ts.setSourceMapRange(ts.createAssignment(ts.setSourceMapRange(ts.getSynthesizedClone(node.name), node.name), ts.visitNode(node.initializer, visitor, ts.isExpression)), node);
        }
        function transformAndEmitIfStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      if (x)
                //          /*thenStatement*/
                //      else
                //          /*elseStatement*/
                //
                // [intermediate]
                //  .brfalse elseLabel, (x)
                //      /*thenStatement*/
                //  .br endLabel
                //  .mark elseLabel
                //      /*elseStatement*/
                //  .mark endLabel
                if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) {
                    var endLabel = defineLabel();
                    var elseLabel = node.elseStatement ? defineLabel() : undefined;
                    emitBreakWhenFalse(node.elseStatement ? elseLabel : endLabel, ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node.expression);
                    transformAndEmitEmbeddedStatement(node.thenStatement);
                    if (node.elseStatement) {
                        emitBreak(endLabel);
                        markLabel(elseLabel);
                        transformAndEmitEmbeddedStatement(node.elseStatement);
                    }
                    markLabel(endLabel);
                }
                else {
                    emitStatement(ts.visitNode(node, visitor, ts.isStatement));
                }
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitDoStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      do {
                //          /*body*/
                //      }
                //      while (i < 10);
                //
                // [intermediate]
                //  .loop conditionLabel, endLabel
                //  .mark loopLabel
                //      /*body*/
                //  .mark conditionLabel
                //  .brtrue loopLabel, (i < 10)
                //  .endloop
                //  .mark endLabel
                var conditionLabel = defineLabel();
                var loopLabel = defineLabel();
                beginLoopBlock(/*continueLabel*/ conditionLabel);
                markLabel(loopLabel);
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(conditionLabel);
                emitBreakWhenTrue(loopLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitDoStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
                node = ts.visitEachChild(node, visitor, context);
                endLoopBlock();
                return node;
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformAndEmitWhileStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      while (i < 10) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .loop loopLabel, endLabel
                //  .mark loopLabel
                //  .brfalse endLabel, (i < 10)
                //      /*body*/
                //  .br loopLabel
                //  .endloop
                //  .mark endLabel
                var loopLabel = defineLabel();
                var endLabel = beginLoopBlock(loopLabel);
                markLabel(loopLabel);
                emitBreakWhenFalse(endLabel, ts.visitNode(node.expression, visitor, ts.isExpression));
                transformAndEmitEmbeddedStatement(node.statement);
                emitBreak(loopLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitWhileStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
                node = ts.visitEachChild(node, visitor, context);
                endLoopBlock();
                return node;
            }
            else {
                return ts.visitEachChild(node, visitor, context);
            }
        }
        function transformAndEmitForStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      for (var i = 0; i < 10; i++) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .local i
                //      i = 0;
                //  .loop incrementLabel, endLoopLabel
                //  .mark conditionLabel
                //  .brfalse endLoopLabel, (i < 10)
                //      /*body*/
                //  .mark incrementLabel
                //      i++;
                //  .br conditionLabel
                //  .endloop
                //  .mark endLoopLabel
                var conditionLabel = defineLabel();
                var incrementLabel = defineLabel();
                var endLabel = beginLoopBlock(incrementLabel);
                if (node.initializer) {
                    var initializer = node.initializer;
                    if (ts.isVariableDeclarationList(initializer)) {
                        transformAndEmitVariableDeclarationList(initializer);
                    }
                    else {
                        emitStatement(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(initializer, visitor, ts.isExpression)), initializer));
                    }
                }
                markLabel(conditionLabel);
                if (node.condition) {
                    emitBreakWhenFalse(endLabel, ts.visitNode(node.condition, visitor, ts.isExpression));
                }
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(incrementLabel);
                if (node.incrementor) {
                    emitStatement(ts.setTextRange(ts.createExpressionStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), node.incrementor));
                }
                emitBreak(conditionLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitForStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
            }
            var initializer = node.initializer;
            if (initializer && ts.isVariableDeclarationList(initializer)) {
                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                var variables = ts.getInitializedVariables(initializer);
                node = ts.updateFor(node, variables.length > 0
                    ? ts.inlineExpressions(ts.map(variables, transformInitializedVariable))
                    : undefined, ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            }
            else {
                node = ts.visitEachChild(node, visitor, context);
            }
            if (inStatementContainingYield) {
                endLoopBlock();
            }
            return node;
        }
        function transformAndEmitForInStatement(node) {
            // TODO(rbuckton): Source map locations
            if (containsYield(node)) {
                // [source]
                //      for (var p in o) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .local _a, _b, _i
                //      _a = [];
                //      for (_b in o) _a.push(_b);
                //      _i = 0;
                //  .loop incrementLabel, endLoopLabel
                //  .mark conditionLabel
                //  .brfalse endLoopLabel, (_i < _a.length)
                //      p = _a[_i];
                //      /*body*/
                //  .mark incrementLabel
                //      _b++;
                //  .br conditionLabel
                //  .endloop
                //  .mark endLoopLabel
                var keysArray = declareLocal(); // _a
                var key = declareLocal(); // _b
                var keysIndex = ts.createLoopVariable(); // _i
                var initializer = node.initializer;
                hoistVariableDeclaration(keysIndex);
                emitAssignment(keysArray, ts.createArrayLiteral());
                emitStatement(ts.createForIn(key, ts.visitNode(node.expression, visitor, ts.isExpression), ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(keysArray, "push"), 
                /*typeArguments*/ undefined, [key]))));
                emitAssignment(keysIndex, ts.createLiteral(0));
                var conditionLabel = defineLabel();
                var incrementLabel = defineLabel();
                var endLabel = beginLoopBlock(incrementLabel);
                markLabel(conditionLabel);
                emitBreakWhenFalse(endLabel, ts.createLessThan(keysIndex, ts.createPropertyAccess(keysArray, "length")));
                var variable = void 0;
                if (ts.isVariableDeclarationList(initializer)) {
                    for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                        var variable_1 = _a[_i];
                        hoistVariableDeclaration(variable_1.name);
                    }
                    variable = ts.getSynthesizedClone(initializer.declarations[0].name);
                }
                else {
                    variable = ts.visitNode(initializer, visitor, ts.isExpression);
                    ts.Debug.assert(ts.isLeftHandSideExpression(variable));
                }
                emitAssignment(variable, ts.createElementAccess(keysArray, keysIndex));
                transformAndEmitEmbeddedStatement(node.statement);
                markLabel(incrementLabel);
                emitStatement(ts.createExpressionStatement(ts.createPostfixIncrement(keysIndex)));
                emitBreak(conditionLabel);
                endLoopBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitForInStatement(node) {
            // [source]
            //      for (var x in a) {
            //          /*body*/
            //      }
            //
            // [intermediate]
            //  .local x
            //  .loop
            //      for (x in a) {
            //          /*body*/
            //      }
            //  .endloop
            if (inStatementContainingYield) {
                beginScriptLoopBlock();
            }
            var initializer = node.initializer;
            if (ts.isVariableDeclarationList(initializer)) {
                for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    hoistVariableDeclaration(variable.name);
                }
                node = ts.updateForIn(node, initializer.declarations[0].name, ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock));
            }
            else {
                node = ts.visitEachChild(node, visitor, context);
            }
            if (inStatementContainingYield) {
                endLoopBlock();
            }
            return node;
        }
        function transformAndEmitContinueStatement(node) {
            var label = findContinueTarget(node.label ? ts.idText(node.label) : undefined);
            if (label > 0) {
                emitBreak(label, /*location*/ node);
            }
            else {
                // invalid continue without a containing loop. Leave the node as is, per #17875.
                emitStatement(node);
            }
        }
        function visitContinueStatement(node) {
            if (inStatementContainingYield) {
                var label = findContinueTarget(node.label && ts.idText(node.label));
                if (label > 0) {
                    return createInlineBreak(label, /*location*/ node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitBreakStatement(node) {
            var label = findBreakTarget(node.label ? ts.idText(node.label) : undefined);
            if (label > 0) {
                emitBreak(label, /*location*/ node);
            }
            else {
                // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875.
                emitStatement(node);
            }
        }
        function visitBreakStatement(node) {
            if (inStatementContainingYield) {
                var label = findBreakTarget(node.label && ts.idText(node.label));
                if (label > 0) {
                    return createInlineBreak(label, /*location*/ node);
                }
            }
            return ts.visitEachChild(node, visitor, context);
        }
        function transformAndEmitReturnStatement(node) {
            emitReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function visitReturnStatement(node) {
            return createInlineReturn(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function transformAndEmitWithStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      with (x) {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .with (x)
                //      /*body*/
                //  .endwith
                beginWithBlock(cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression)));
                transformAndEmitEmbeddedStatement(node.statement);
                endWithBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function transformAndEmitSwitchStatement(node) {
            if (containsYield(node.caseBlock)) {
                // [source]
                //      switch (x) {
                //          case a:
                //              /*caseStatements*/
                //          case b:
                //              /*caseStatements*/
                //          default:
                //              /*defaultStatements*/
                //      }
                //
                // [intermediate]
                //  .local _a
                //  .switch endLabel
                //      _a = x;
                //      switch (_a) {
                //          case a:
                //  .br clauseLabels[0]
                //      }
                //      switch (_a) {
                //          case b:
                //  .br clauseLabels[1]
                //      }
                //  .br clauseLabels[2]
                //  .mark clauseLabels[0]
                //      /*caseStatements*/
                //  .mark clauseLabels[1]
                //      /*caseStatements*/
                //  .mark clauseLabels[2]
                //      /*caseStatements*/
                //  .endswitch
                //  .mark endLabel
                var caseBlock = node.caseBlock;
                var numClauses = caseBlock.clauses.length;
                var endLabel = beginSwitchBlock();
                var expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression));
                // Create labels for each clause and find the index of the first default clause.
                var clauseLabels = [];
                var defaultClauseIndex = -1;
                for (var i = 0; i < numClauses; i++) {
                    var clause = caseBlock.clauses[i];
                    clauseLabels.push(defineLabel());
                    if (clause.kind === 278 /* DefaultClause */ && defaultClauseIndex === -1) {
                        defaultClauseIndex = i;
                    }
                }
                // Emit switch statements for each run of case clauses either from the first case
                // clause or the next case clause with a `yield` in its expression, up to the next
                // case clause with a `yield` in its expression.
                var clausesWritten = 0;
                var pendingClauses = [];
                while (clausesWritten < numClauses) {
                    var defaultClausesSkipped = 0;
                    for (var i = clausesWritten; i < numClauses; i++) {
                        var clause = caseBlock.clauses[i];
                        if (clause.kind === 277 /* CaseClause */) {
                            if (containsYield(clause.expression) && pendingClauses.length > 0) {
                                break;
                            }
                            pendingClauses.push(ts.createCaseClause(ts.visitNode(clause.expression, visitor, ts.isExpression), [
                                createInlineBreak(clauseLabels[i], /*location*/ clause.expression)
                            ]));
                        }
                        else {
                            defaultClausesSkipped++;
                        }
                    }
                    if (pendingClauses.length) {
                        emitStatement(ts.createSwitch(expression, ts.createCaseBlock(pendingClauses)));
                        clausesWritten += pendingClauses.length;
                        pendingClauses = [];
                    }
                    if (defaultClausesSkipped > 0) {
                        clausesWritten += defaultClausesSkipped;
                        defaultClausesSkipped = 0;
                    }
                }
                if (defaultClauseIndex >= 0) {
                    emitBreak(clauseLabels[defaultClauseIndex]);
                }
                else {
                    emitBreak(endLabel);
                }
                for (var i = 0; i < numClauses; i++) {
                    markLabel(clauseLabels[i]);
                    transformAndEmitStatements(caseBlock.clauses[i].statements);
                }
                endSwitchBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitSwitchStatement(node) {
            if (inStatementContainingYield) {
                beginScriptSwitchBlock();
            }
            node = ts.visitEachChild(node, visitor, context);
            if (inStatementContainingYield) {
                endSwitchBlock();
            }
            return node;
        }
        function transformAndEmitLabeledStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      x: {
                //          /*body*/
                //      }
                //
                // [intermediate]
                //  .labeled "x", endLabel
                //      /*body*/
                //  .endlabeled
                //  .mark endLabel
                beginLabeledBlock(ts.idText(node.label));
                transformAndEmitEmbeddedStatement(node.statement);
                endLabeledBlock();
            }
            else {
                emitStatement(ts.visitNode(node, visitor, ts.isStatement));
            }
        }
        function visitLabeledStatement(node) {
            if (inStatementContainingYield) {
                beginScriptLabeledBlock(ts.idText(node.label));
            }
            node = ts.visitEachChild(node, visitor, context);
            if (inStatementContainingYield) {
                endLabeledBlock();
            }
            return node;
        }
        function transformAndEmitThrowStatement(node) {
            emitThrow(ts.visitNode(node.expression, visitor, ts.isExpression), 
            /*location*/ node);
        }
        function transformAndEmitTryStatement(node) {
            if (containsYield(node)) {
                // [source]
                //      try {
                //          /*tryBlock*/
                //      }
                //      catch (e) {
                //          /*catchBlock*/
                //      }
                //      finally {
                //          /*finallyBlock*/
                //      }
                //
                // [intermediate]
                //  .local _a
                //  .try tryLabel, catchLabel, finallyLabel, endLabel
                //  .mark tryLabel
                //  .nop
                //      /*tryBlock*/
                //  .br endLabel
                //  .catch
                //  .mark catchLabel
                //      _a = %error%;
                //      /*catchBlock*/
                //  .br endLabel
                //  .finally
                //  .mark finallyLabel
                //      /*finallyBlock*/
                //  .endfinally
                //  .endtry
                //  .mark endLabel
                beginExceptionBlock();
                transformAndEmitEmbeddedStatement(node.tryBlock);
                if (node.catchClause) {
                    beginCatchBlock(node.catchClause.variableDeclaration); // TODO: GH#18217
                    transformAndEmitEmbeddedStatement(node.catchClause.block);
                }
                if (node.finallyBlock) {
                    beginFinallyBlock();
                    transformAndEmitEmbeddedStatement(node.finallyBlock);
                }
                endExceptionBlock();
            }
            else {
                emitStatement(ts.visitEachChild(node, visitor, context));
            }
        }
        function containsYield(node) {
            return !!node && (node.transformFlags & 262144 /* ContainsYield */) !== 0;
        }
        function countInitialNodesWithoutYield(nodes) {
            var numNodes = nodes.length;
            for (var i = 0; i < numNodes; i++) {
                if (containsYield(nodes[i])) {
                    return i;
                }
            }
            return -1;
        }
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            return node;
        }
        function substituteExpression(node) {
            if (ts.isIdentifier(node)) {
                return substituteExpressionIdentifier(node);
            }
            return node;
        }
        function substituteExpressionIdentifier(node) {
            if (!ts.isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(ts.idText(node))) {
                var original = ts.getOriginalNode(node);
                if (ts.isIdentifier(original) && original.parent) {
                    var declaration = resolver.getReferencedValueDeclaration(original);
                    if (declaration) {
                        var name = renamedCatchVariableDeclarations[ts.getOriginalNodeId(declaration)];
                        if (name) {
                            var clone_8 = ts.getMutableClone(name);
                            ts.setSourceMapRange(clone_8, node);
                            ts.setCommentRange(clone_8, node);
                            return clone_8;
                        }
                    }
                }
            }
            return node;
        }
        function cacheExpression(node) {
            if (ts.isGeneratedIdentifier(node) || ts.getEmitFlags(node) & 4096 /* HelperName */) {
                return node;
            }
            var temp = ts.createTempVariable(hoistVariableDeclaration);
            emitAssignment(temp, node, /*location*/ node);
            return temp;
        }
        function declareLocal(name) {
            var temp = name
                ? ts.createUniqueName(name)
                : ts.createTempVariable(/*recordTempVariable*/ undefined);
            hoistVariableDeclaration(temp);
            return temp;
        }
        /**
         * Defines a label, uses as the target of a Break operation.
         */
        function defineLabel() {
            if (!labelOffsets) {
                labelOffsets = [];
            }
            var label = nextLabelId;
            nextLabelId++;
            labelOffsets[label] = -1;
            return label;
        }
        /**
         * Marks the current operation with the specified label.
         */
        function markLabel(label) {
            ts.Debug.assert(labelOffsets !== undefined, "No labels were defined.");
            labelOffsets[label] = operations ? operations.length : 0;
        }
        /**
         * Begins a block operation (With, Break/Continue, Try/Catch/Finally)
         *
         * @param block Information about the block.
         */
        function beginBlock(block) {
            if (!blocks) {
                blocks = [];
                blockActions = [];
                blockOffsets = [];
                blockStack = [];
            }
            var index = blockActions.length;
            blockActions[index] = 0 /* Open */;
            blockOffsets[index] = operations ? operations.length : 0;
            blocks[index] = block;
            blockStack.push(block);
            return index;
        }
        /**
         * Ends the current block operation.
         */
        function endBlock() {
            var block = peekBlock();
            if (block === undefined)
                return ts.Debug.fail("beginBlock was never called.");
            var index = blockActions.length;
            blockActions[index] = 1 /* Close */;
            blockOffsets[index] = operations ? operations.length : 0;
            blocks[index] = block;
            blockStack.pop();
            return block;
        }
        /**
         * Gets the current open block.
         */
        function peekBlock() {
            return ts.lastOrUndefined(blockStack);
        }
        /**
         * Gets the kind of the current open block.
         */
        function peekBlockKind() {
            var block = peekBlock();
            return block && block.kind;
        }
        /**
         * Begins a code block for a generated `with` statement.
         *
         * @param expression An identifier representing expression for the `with` block.
         */
        function beginWithBlock(expression) {
            var startLabel = defineLabel();
            var endLabel = defineLabel();
            markLabel(startLabel);
            beginBlock({
                kind: 1 /* With */,
                expression: expression,
                startLabel: startLabel,
                endLabel: endLabel
            });
        }
        /**
         * Ends a code block for a generated `with` statement.
         */
        function endWithBlock() {
            ts.Debug.assert(peekBlockKind() === 1 /* With */);
            var block = endBlock();
            markLabel(block.endLabel);
        }
        /**
         * Begins a code block for a generated `try` statement.
         */
        function beginExceptionBlock() {
            var startLabel = defineLabel();
            var endLabel = defineLabel();
            markLabel(startLabel);
            beginBlock({
                kind: 0 /* Exception */,
                state: 0 /* Try */,
                startLabel: startLabel,
                endLabel: endLabel
            });
            emitNop();
            return endLabel;
        }
        /**
         * Enters the `catch` clause of a generated `try` statement.
         *
         * @param variable The catch variable.
         */
        function beginCatchBlock(variable) {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            // generated identifiers should already be unique within a file
            var name;
            if (ts.isGeneratedIdentifier(variable.name)) {
                name = variable.name;
                hoistVariableDeclaration(variable.name);
            }
            else {
                var text = ts.idText(variable.name);
                name = declareLocal(text);
                if (!renamedCatchVariables) {
                    renamedCatchVariables = ts.createMap();
                    renamedCatchVariableDeclarations = [];
                    context.enableSubstitution(75 /* Identifier */);
                }
                renamedCatchVariables.set(text, true);
                renamedCatchVariableDeclarations[ts.getOriginalNodeId(variable)] = name;
            }
            var exception = peekBlock();
            ts.Debug.assert(exception.state < 1 /* Catch */);
            var endLabel = exception.endLabel;
            emitBreak(endLabel);
            var catchLabel = defineLabel();
            markLabel(catchLabel);
            exception.state = 1 /* Catch */;
            exception.catchVariable = name;
            exception.catchLabel = catchLabel;
            emitAssignment(name, ts.createCall(ts.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, []));
            emitNop();
        }
        /**
         * Enters the `finally` block of a generated `try` statement.
         */
        function beginFinallyBlock() {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            var exception = peekBlock();
            ts.Debug.assert(exception.state < 2 /* Finally */);
            var endLabel = exception.endLabel;
            emitBreak(endLabel);
            var finallyLabel = defineLabel();
            markLabel(finallyLabel);
            exception.state = 2 /* Finally */;
            exception.finallyLabel = finallyLabel;
        }
        /**
         * Ends the code block for a generated `try` statement.
         */
        function endExceptionBlock() {
            ts.Debug.assert(peekBlockKind() === 0 /* Exception */);
            var exception = endBlock();
            var state = exception.state;
            if (state < 2 /* Finally */) {
                emitBreak(exception.endLabel);
            }
            else {
                emitEndfinally();
            }
            markLabel(exception.endLabel);
            emitNop();
            exception.state = 3 /* Done */;
        }
        /**
         * Begins a code block that supports `break` or `continue` statements that are defined in
         * the source tree and not from generated code.
         *
         * @param labelText Names from containing labeled statements.
         */
        function beginScriptLoopBlock() {
            beginBlock({
                kind: 3 /* Loop */,
                isScript: true,
                breakLabel: -1,
                continueLabel: -1
            });
        }
        /**
         * Begins a code block that supports `break` or `continue` statements that are defined in
         * generated code. Returns a label used to mark the operation to which to jump when a
         * `break` statement targets this block.
         *
         * @param continueLabel A Label used to mark the operation to which to jump when a
         *                      `continue` statement targets this block.
         */
        function beginLoopBlock(continueLabel) {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 3 /* Loop */,
                isScript: false,
                breakLabel: breakLabel,
                continueLabel: continueLabel,
            });
            return breakLabel;
        }
        /**
         * Ends a code block that supports `break` or `continue` statements that are defined in
         * generated code or in the source tree.
         */
        function endLoopBlock() {
            ts.Debug.assert(peekBlockKind() === 3 /* Loop */);
            var block = endBlock();
            var breakLabel = block.breakLabel;
            if (!block.isScript) {
                markLabel(breakLabel);
            }
        }
        /**
         * Begins a code block that supports `break` statements that are defined in the source
         * tree and not from generated code.
         *
         */
        function beginScriptSwitchBlock() {
            beginBlock({
                kind: 2 /* Switch */,
                isScript: true,
                breakLabel: -1
            });
        }
        /**
         * Begins a code block that supports `break` statements that are defined in generated code.
         * Returns a label used to mark the operation to which to jump when a `break` statement
         * targets this block.
         */
        function beginSwitchBlock() {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 2 /* Switch */,
                isScript: false,
                breakLabel: breakLabel,
            });
            return breakLabel;
        }
        /**
         * Ends a code block that supports `break` statements that are defined in generated code.
         */
        function endSwitchBlock() {
            ts.Debug.assert(peekBlockKind() === 2 /* Switch */);
            var block = endBlock();
            var breakLabel = block.breakLabel;
            if (!block.isScript) {
                markLabel(breakLabel);
            }
        }
        function beginScriptLabeledBlock(labelText) {
            beginBlock({
                kind: 4 /* Labeled */,
                isScript: true,
                labelText: labelText,
                breakLabel: -1
            });
        }
        function beginLabeledBlock(labelText) {
            var breakLabel = defineLabel();
            beginBlock({
                kind: 4 /* Labeled */,
                isScript: false,
                labelText: labelText,
                breakLabel: breakLabel
            });
        }
        function endLabeledBlock() {
            ts.Debug.assert(peekBlockKind() === 4 /* Labeled */);
            var block = endBlock();
            if (!block.isScript) {
                markLabel(block.breakLabel);
            }
        }
        /**
         * Indicates whether the provided block supports `break` statements.
         *
         * @param block A code block.
         */
        function supportsUnlabeledBreak(block) {
            return block.kind === 2 /* Switch */
                || block.kind === 3 /* Loop */;
        }
        /**
         * Indicates whether the provided block supports `break` statements with labels.
         *
         * @param block A code block.
         */
        function supportsLabeledBreakOrContinue(block) {
            return block.kind === 4 /* Labeled */;
        }
        /**
         * Indicates whether the provided block supports `continue` statements.
         *
         * @param block A code block.
         */
        function supportsUnlabeledContinue(block) {
            return block.kind === 3 /* Loop */;
        }
        function hasImmediateContainingLabeledBlock(labelText, start) {
            for (var j = start; j >= 0; j--) {
                var containingBlock = blockStack[j];
                if (supportsLabeledBreakOrContinue(containingBlock)) {
                    if (containingBlock.labelText === labelText) {
                        return true;
                    }
                }
                else {
                    break;
                }
            }
            return false;
        }
        /**
         * Finds the label that is the target for a `break` statement.
         *
         * @param labelText An optional name of a containing labeled statement.
         */
        function findBreakTarget(labelText) {
            if (blockStack) {
                if (labelText) {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) {
                            return block.breakLabel;
                        }
                        else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
                            return block.breakLabel;
                        }
                    }
                }
                else {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledBreak(block)) {
                            return block.breakLabel;
                        }
                    }
                }
            }
            return 0;
        }
        /**
         * Finds the label that is the target for a `continue` statement.
         *
         * @param labelText An optional name of a containing labeled statement.
         */
        function findContinueTarget(labelText) {
            if (blockStack) {
                if (labelText) {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) {
                            return block.continueLabel;
                        }
                    }
                }
                else {
                    for (var i = blockStack.length - 1; i >= 0; i--) {
                        var block = blockStack[i];
                        if (supportsUnlabeledContinue(block)) {
                            return block.continueLabel;
                        }
                    }
                }
            }
            return 0;
        }
        /**
         * Creates an expression that can be used to indicate the value for a label.
         *
         * @param label A label.
         */
        function createLabel(label) {
            if (label !== undefined && label > 0) {
                if (labelExpressions === undefined) {
                    labelExpressions = [];
                }
                var expression = ts.createLiteral(-1);
                if (labelExpressions[label] === undefined) {
                    labelExpressions[label] = [expression];
                }
                else {
                    labelExpressions[label].push(expression);
                }
                return expression;
            }
            return ts.createOmittedExpression();
        }
        /**
         * Creates a numeric literal for the provided instruction.
         */
        function createInstruction(instruction) {
            var literal = ts.createLiteral(instruction);
            ts.addSyntheticTrailingComment(literal, 3 /* MultiLineCommentTrivia */, getInstructionName(instruction));
            return literal;
        }
        /**
         * Creates a statement that can be used indicate a Break operation to the provided label.
         *
         * @param label A label.
         * @param location An optional source map location for the statement.
         */
        function createInlineBreak(label, location) {
            ts.Debug.assertLessThan(0, label, "Invalid label");
            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), location);
        }
        /**
         * Creates a statement that can be used indicate a Return operation.
         *
         * @param expression The expression for the return statement.
         * @param location An optional source map location for the statement.
         */
        function createInlineReturn(expression, location) {
            return ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(2 /* Return */), expression]
                : [createInstruction(2 /* Return */)])), location);
        }
        /**
         * Creates an expression that can be used to resume from a Yield operation.
         */
        function createGeneratorResume(location) {
            return ts.setTextRange(ts.createCall(ts.createPropertyAccess(state, "sent"), 
            /*typeArguments*/ undefined, []), location);
        }
        /**
         * Emits an empty instruction.
         */
        function emitNop() {
            emitWorker(0 /* Nop */);
        }
        /**
         * Emits a Statement.
         *
         * @param node A statement.
         */
        function emitStatement(node) {
            if (node) {
                emitWorker(1 /* Statement */, [node]);
            }
            else {
                emitNop();
            }
        }
        /**
         * Emits an Assignment operation.
         *
         * @param left The left-hand side of the assignment.
         * @param right The right-hand side of the assignment.
         * @param location An optional source map location for the assignment.
         */
        function emitAssignment(left, right, location) {
            emitWorker(2 /* Assign */, [left, right], location);
        }
        /**
         * Emits a Break operation to the specified label.
         *
         * @param label A label.
         * @param location An optional source map location for the assignment.
         */
        function emitBreak(label, location) {
            emitWorker(3 /* Break */, [label], location);
        }
        /**
         * Emits a Break operation to the specified label when a condition evaluates to a truthy
         * value at runtime.
         *
         * @param label A label.
         * @param condition The condition.
         * @param location An optional source map location for the assignment.
         */
        function emitBreakWhenTrue(label, condition, location) {
            emitWorker(4 /* BreakWhenTrue */, [label, condition], location);
        }
        /**
         * Emits a Break to the specified label when a condition evaluates to a falsey value at
         * runtime.
         *
         * @param label A label.
         * @param condition The condition.
         * @param location An optional source map location for the assignment.
         */
        function emitBreakWhenFalse(label, condition, location) {
            emitWorker(5 /* BreakWhenFalse */, [label, condition], location);
        }
        /**
         * Emits a YieldStar operation for the provided expression.
         *
         * @param expression An optional value for the yield operation.
         * @param location An optional source map location for the assignment.
         */
        function emitYieldStar(expression, location) {
            emitWorker(7 /* YieldStar */, [expression], location);
        }
        /**
         * Emits a Yield operation for the provided expression.
         *
         * @param expression An optional value for the yield operation.
         * @param location An optional source map location for the assignment.
         */
        function emitYield(expression, location) {
            emitWorker(6 /* Yield */, [expression], location);
        }
        /**
         * Emits a Return operation for the provided expression.
         *
         * @param expression An optional value for the operation.
         * @param location An optional source map location for the assignment.
         */
        function emitReturn(expression, location) {
            emitWorker(8 /* Return */, [expression], location);
        }
        /**
         * Emits a Throw operation for the provided expression.
         *
         * @param expression A value for the operation.
         * @param location An optional source map location for the assignment.
         */
        function emitThrow(expression, location) {
            emitWorker(9 /* Throw */, [expression], location);
        }
        /**
         * Emits an Endfinally operation. This is used to handle `finally` block semantics.
         */
        function emitEndfinally() {
            emitWorker(10 /* Endfinally */);
        }
        /**
         * Emits an operation.
         *
         * @param code The OpCode for the operation.
         * @param args The optional arguments for the operation.
         */
        function emitWorker(code, args, location) {
            if (operations === undefined) {
                operations = [];
                operationArguments = [];
                operationLocations = [];
            }
            if (labelOffsets === undefined) {
                // mark entry point
                markLabel(defineLabel());
            }
            var operationIndex = operations.length;
            operations[operationIndex] = code;
            operationArguments[operationIndex] = args;
            operationLocations[operationIndex] = location;
        }
        /**
         * Builds the generator function body.
         */
        function build() {
            blockIndex = 0;
            labelNumber = 0;
            labelNumbers = undefined;
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            clauses = undefined;
            statements = undefined;
            exceptionBlockStack = undefined;
            currentExceptionBlock = undefined;
            withBlockStack = undefined;
            var buildResult = buildStatements();
            return createGeneratorHelper(context, ts.setEmitFlags(ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)], 
            /*type*/ undefined, ts.createBlock(buildResult, 
            /*multiLine*/ buildResult.length > 0)), 524288 /* ReuseTempVariableScope */));
        }
        /**
         * Builds the statements for the generator function body.
         */
        function buildStatements() {
            if (operations) {
                for (var operationIndex = 0; operationIndex < operations.length; operationIndex++) {
                    writeOperation(operationIndex);
                }
                flushFinalLabel(operations.length);
            }
            else {
                flushFinalLabel(0);
            }
            if (clauses) {
                var labelExpression = ts.createPropertyAccess(state, "label");
                var switchStatement = ts.createSwitch(labelExpression, ts.createCaseBlock(clauses));
                return [ts.startOnNewLine(switchStatement)];
            }
            if (statements) {
                return statements;
            }
            return [];
        }
        /**
         * Flush the current label and advance to a new label.
         */
        function flushLabel() {
            if (!statements) {
                return;
            }
            appendLabel(/*markLabelEnd*/ !lastOperationWasAbrupt);
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            labelNumber++;
        }
        /**
         * Flush the final label of the generator function body.
         */
        function flushFinalLabel(operationIndex) {
            if (isFinalLabelReachable(operationIndex)) {
                tryEnterLabel(operationIndex);
                withBlockStack = undefined;
                writeReturn(/*expression*/ undefined, /*operationLocation*/ undefined);
            }
            if (statements && clauses) {
                appendLabel(/*markLabelEnd*/ false);
            }
            updateLabelExpressions();
        }
        /**
         * Tests whether the final label of the generator function body
         * is reachable by user code.
         */
        function isFinalLabelReachable(operationIndex) {
            // if the last operation was *not* a completion (return/throw) then
            // the final label is reachable.
            if (!lastOperationWasCompletion) {
                return true;
            }
            // if there are no labels defined or referenced, then the final label is
            // not reachable.
            if (!labelOffsets || !labelExpressions) {
                return false;
            }
            // if the label for this offset is referenced, then the final label
            // is reachable.
            for (var label = 0; label < labelOffsets.length; label++) {
                if (labelOffsets[label] === operationIndex && labelExpressions[label]) {
                    return true;
                }
            }
            return false;
        }
        /**
         * Appends a case clause for the last label and sets the new label.
         *
         * @param markLabelEnd Indicates that the transition between labels was a fall-through
         *                     from a previous case clause and the change in labels should be
         *                     reflected on the `state` object.
         */
        function appendLabel(markLabelEnd) {
            if (!clauses) {
                clauses = [];
            }
            if (statements) {
                if (withBlockStack) {
                    // The previous label was nested inside one or more `with` blocks, so we
                    // surround the statements in generated `with` blocks to create the same environment.
                    for (var i = withBlockStack.length - 1; i >= 0; i--) {
                        var withBlock = withBlockStack[i];
                        statements = [ts.createWith(withBlock.expression, ts.createBlock(statements))];
                    }
                }
                if (currentExceptionBlock) {
                    // The previous label was nested inside of an exception block, so we must
                    // indicate entry into a protected region by pushing the label numbers
                    // for each block in the protected region.
                    var startLabel = currentExceptionBlock.startLabel, catchLabel = currentExceptionBlock.catchLabel, finallyLabel = currentExceptionBlock.finallyLabel, endLabel = currentExceptionBlock.endLabel;
                    statements.unshift(ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(state, "trys"), "push"), 
                    /*typeArguments*/ undefined, [
                        ts.createArrayLiteral([
                            createLabel(startLabel),
                            createLabel(catchLabel),
                            createLabel(finallyLabel),
                            createLabel(endLabel)
                        ])
                    ])));
                    currentExceptionBlock = undefined;
                }
                if (markLabelEnd) {
                    // The case clause for the last label falls through to this label, so we
                    // add an assignment statement to reflect the change in labels.
                    statements.push(ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(state, "label"), ts.createLiteral(labelNumber + 1))));
                }
            }
            clauses.push(ts.createCaseClause(ts.createLiteral(labelNumber), statements || []));
            statements = undefined;
        }
        /**
         * Tries to enter into a new label at the current operation index.
         */
        function tryEnterLabel(operationIndex) {
            if (!labelOffsets) {
                return;
            }
            for (var label = 0; label < labelOffsets.length; label++) {
                if (labelOffsets[label] === operationIndex) {
                    flushLabel();
                    if (labelNumbers === undefined) {
                        labelNumbers = [];
                    }
                    if (labelNumbers[labelNumber] === undefined) {
                        labelNumbers[labelNumber] = [label];
                    }
                    else {
                        labelNumbers[labelNumber].push(label);
                    }
                }
            }
        }
        /**
         * Updates literal expressions for labels with actual label numbers.
         */
        function updateLabelExpressions() {
            if (labelExpressions !== undefined && labelNumbers !== undefined) {
                for (var labelNumber_1 = 0; labelNumber_1 < labelNumbers.length; labelNumber_1++) {
                    var labels = labelNumbers[labelNumber_1];
                    if (labels !== undefined) {
                        for (var _i = 0, labels_1 = labels; _i < labels_1.length; _i++) {
                            var label = labels_1[_i];
                            var expressions = labelExpressions[label];
                            if (expressions !== undefined) {
                                for (var _a = 0, expressions_1 = expressions; _a < expressions_1.length; _a++) {
                                    var expression = expressions_1[_a];
                                    expression.text = String(labelNumber_1);
                                }
                            }
                        }
                    }
                }
            }
        }
        /**
         * Tries to enter or leave a code block.
         */
        function tryEnterOrLeaveBlock(operationIndex) {
            if (blocks) {
                for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) {
                    var block = blocks[blockIndex];
                    var blockAction = blockActions[blockIndex];
                    switch (block.kind) {
                        case 0 /* Exception */:
                            if (blockAction === 0 /* Open */) {
                                if (!exceptionBlockStack) {
                                    exceptionBlockStack = [];
                                }
                                if (!statements) {
                                    statements = [];
                                }
                                exceptionBlockStack.push(currentExceptionBlock);
                                currentExceptionBlock = block;
                            }
                            else if (blockAction === 1 /* Close */) {
                                currentExceptionBlock = exceptionBlockStack.pop();
                            }
                            break;
                        case 1 /* With */:
                            if (blockAction === 0 /* Open */) {
                                if (!withBlockStack) {
                                    withBlockStack = [];
                                }
                                withBlockStack.push(block);
                            }
                            else if (blockAction === 1 /* Close */) {
                                withBlockStack.pop();
                            }
                            break;
                        // default: do nothing
                    }
                }
            }
        }
        /**
         * Writes an operation as a statement to the current label's statement list.
         *
         * @param operation The OpCode of the operation
         */
        function writeOperation(operationIndex) {
            tryEnterLabel(operationIndex);
            tryEnterOrLeaveBlock(operationIndex);
            // early termination, nothing else to process in this label
            if (lastOperationWasAbrupt) {
                return;
            }
            lastOperationWasAbrupt = false;
            lastOperationWasCompletion = false;
            var opcode = operations[operationIndex];
            if (opcode === 0 /* Nop */) {
                return;
            }
            else if (opcode === 10 /* Endfinally */) {
                return writeEndfinally();
            }
            var args = operationArguments[operationIndex];
            if (opcode === 1 /* Statement */) {
                return writeStatement(args[0]);
            }
            var location = operationLocations[operationIndex];
            switch (opcode) {
                case 2 /* Assign */:
                    return writeAssign(args[0], args[1], location);
                case 3 /* Break */:
                    return writeBreak(args[0], location);
                case 4 /* BreakWhenTrue */:
                    return writeBreakWhenTrue(args[0], args[1], location);
                case 5 /* BreakWhenFalse */:
                    return writeBreakWhenFalse(args[0], args[1], location);
                case 6 /* Yield */:
                    return writeYield(args[0], location);
                case 7 /* YieldStar */:
                    return writeYieldStar(args[0], location);
                case 8 /* Return */:
                    return writeReturn(args[0], location);
                case 9 /* Throw */:
                    return writeThrow(args[0], location);
            }
        }
        /**
         * Writes a statement to the current label's statement list.
         *
         * @param statement A statement to write.
         */
        function writeStatement(statement) {
            if (statement) {
                if (!statements) {
                    statements = [statement];
                }
                else {
                    statements.push(statement);
                }
            }
        }
        /**
         * Writes an Assign operation to the current label's statement list.
         *
         * @param left The left-hand side of the assignment.
         * @param right The right-hand side of the assignment.
         * @param operationLocation The source map location for the operation.
         */
        function writeAssign(left, right, operationLocation) {
            writeStatement(ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(left, right)), operationLocation));
        }
        /**
         * Writes a Throw operation to the current label's statement list.
         *
         * @param expression The value to throw.
         * @param operationLocation The source map location for the operation.
         */
        function writeThrow(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            lastOperationWasCompletion = true;
            writeStatement(ts.setTextRange(ts.createThrow(expression), operationLocation));
        }
        /**
         * Writes a Return operation to the current label's statement list.
         *
         * @param expression The value to return.
         * @param operationLocation The source map location for the operation.
         */
        function writeReturn(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            lastOperationWasCompletion = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(2 /* Return */), expression]
                : [createInstruction(2 /* Return */)])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a Break operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreak(label, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a BreakWhenTrue operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param condition The condition for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreakWhenTrue(label, condition, operationLocation) {
            writeStatement(ts.setEmitFlags(ts.createIf(condition, ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
        }
        /**
         * Writes a BreakWhenFalse operation to the current label's statement list.
         *
         * @param label The label for the Break.
         * @param condition The condition for the Break.
         * @param operationLocation The source map location for the operation.
         */
        function writeBreakWhenFalse(label, condition, operationLocation) {
            writeStatement(ts.setEmitFlags(ts.createIf(ts.createLogicalNot(condition), ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(3 /* Break */),
                createLabel(label)
            ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */));
        }
        /**
         * Writes a Yield operation to the current label's statement list.
         *
         * @param expression The expression to yield.
         * @param operationLocation The source map location for the operation.
         */
        function writeYield(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression
                ? [createInstruction(4 /* Yield */), expression]
                : [createInstruction(4 /* Yield */)])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes a YieldStar instruction to the current label's statement list.
         *
         * @param expression The expression to yield.
         * @param operationLocation The source map location for the operation.
         */
        function writeYieldStar(expression, operationLocation) {
            lastOperationWasAbrupt = true;
            writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([
                createInstruction(5 /* YieldStar */),
                expression
            ])), operationLocation), 384 /* NoTokenSourceMaps */));
        }
        /**
         * Writes an Endfinally instruction to the current label's statement list.
         */
        function writeEndfinally() {
            lastOperationWasAbrupt = true;
            writeStatement(ts.createReturn(ts.createArrayLiteral([
                createInstruction(7 /* Endfinally */)
            ])));
        }
    }
    ts.transformGenerators = transformGenerators;
    function createGeneratorHelper(context, body) {
        context.requestEmitHelper(ts.generatorHelper);
        return ts.createCall(ts.getUnscopedHelperName("__generator"), 
        /*typeArguments*/ undefined, [ts.createThis(), body]);
    }
    // The __generator helper is used by down-level transformations to emulate the runtime
    // semantics of an ES2015 generator function. When called, this helper returns an
    // object that implements the Iterator protocol, in that it has `next`, `return`, and
    // `throw` methods that step through the generator when invoked.
    //
    // parameters:
    //  @param thisArg  The value to use as the `this` binding for the transformed generator body.
    //  @param body     A function that acts as the transformed generator body.
    //
    // variables:
    //  _       Persistent state for the generator that is shared between the helper and the
    //          generator body. The state object has the following members:
    //            sent() - A method that returns or throws the current completion value.
    //            label  - The next point at which to resume evaluation of the generator body.
    //            trys   - A stack of protected regions (try/catch/finally blocks).
    //            ops    - A stack of pending instructions when inside of a finally block.
    //  f       A value indicating whether the generator is executing.
    //  y       An iterator to delegate for a yield*.
    //  t       A temporary variable that holds one of the following values (note that these
    //          cases do not overlap):
    //          - The completion value when resuming from a `yield` or `yield*`.
    //          - The error value for a catch block.
    //          - The current protected region (array of try/catch/finally/end labels).
    //          - The verb (`next`, `throw`, or `return` method) to delegate to the expression
    //            of a `yield*`.
    //          - The result of evaluating the verb delegated to the expression of a `yield*`.
    //
    // functions:
    //  verb(n)     Creates a bound callback to the `step` function for opcode `n`.
    //  step(op)    Evaluates opcodes in a generator body until execution is suspended or
    //              completed.
    //
    // The __generator helper understands a limited set of instructions:
    //  0: next(value?)     - Start or resume the generator with the specified value.
    //  1: throw(error)     - Resume the generator with an exception. If the generator is
    //                        suspended inside of one or more protected regions, evaluates
    //                        any intervening finally blocks between the current label and
    //                        the nearest catch block or function boundary. If uncaught, the
    //                        exception is thrown to the caller.
    //  2: return(value?)   - Resume the generator as if with a return. If the generator is
    //                        suspended inside of one or more protected regions, evaluates any
    //                        intervening finally blocks.
    //  3: break(label)     - Jump to the specified label. If the label is outside of the
    //                        current protected region, evaluates any intervening finally
    //                        blocks.
    //  4: yield(value?)    - Yield execution to the caller with an optional value. When
    //                        resumed, the generator will continue at the next label.
    //  5: yield*(value)    - Delegates evaluation to the supplied iterator. When
    //                        delegation completes, the generator will continue at the next
    //                        label.
    //  6: catch(error)     - Handles an exception thrown from within the generator body. If
    //                        the current label is inside of one or more protected regions,
    //                        evaluates any intervening finally blocks between the current
    //                        label and the nearest catch block or function boundary. If
    //                        uncaught, the exception is thrown to the caller.
    //  7: endfinally       - Ends a finally block, resuming the last instruction prior to
    //                        entering a finally block.
    //
    // For examples of how these are used, see the comments in ./transformers/generators.ts
    ts.generatorHelper = {
        name: "typescript:generator",
        importName: "__generator",
        scoped: false,
        priority: 6,
        text: "\n            var __generator = (this && this.__generator) || function (thisArg, body) {\n                var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n                return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n                function verb(n) { return function (v) { return step([n, v]); }; }\n                function step(op) {\n                    if (f) throw new TypeError(\"Generator is already executing.\");\n                    while (_) try {\n                        if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n                        if (y = 0, t) op = [op[0] & 2, t.value];\n                        switch (op[0]) {\n                            case 0: case 1: t = op; break;\n                            case 4: _.label++; return { value: op[1], done: false };\n                            case 5: _.label++; y = op[1]; op = [0]; continue;\n                            case 7: op = _.ops.pop(); _.trys.pop(); continue;\n                            default:\n                                if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n                                if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n                                if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n                                if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n                                if (t[2]) _.ops.pop();\n                                _.trys.pop(); continue;\n                        }\n                        op = body.call(thisArg, _);\n                    } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n                    if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n                }\n            };"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformModule(context) {
        function getTransformModuleDelegate(moduleKind) {
            switch (moduleKind) {
                case ts.ModuleKind.AMD: return transformAMDModule;
                case ts.ModuleKind.UMD: return transformUMDModule;
                default: return transformCommonJSModule;
            }
        }
        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var host = context.getEmitHost();
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.enableSubstitution(75 /* Identifier */); // Substitutes expression identifiers with imported/exported symbols.
        context.enableSubstitution(209 /* BinaryExpression */); // Substitutes assignments to exported symbols.
        context.enableSubstitution(207 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(208 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(282 /* ShorthandPropertyAssignment */); // Substitutes shorthand property assignments for imported/exported symbols.
        context.enableEmitNotification(290 /* SourceFile */); // Restore state when substituting nodes in a file.
        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
        var currentSourceFile; // The current file.
        var currentModuleInfo; // The ExternalModuleInfo for the current file.
        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
        var needUMDDynamicImportHelper;
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms the module aspects of a SourceFile.
         *
         * @param node The SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile ||
                !(ts.isEffectiveExternalModule(node, compilerOptions) ||
                    node.transformFlags & 2097152 /* ContainsDynamicImport */ ||
                    (ts.isJsonSourceFile(node) && ts.hasJsonModuleEmitEnabled(compilerOptions) && (compilerOptions.out || compilerOptions.outFile)))) {
                return node;
            }
            currentSourceFile = node;
            currentModuleInfo = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
            moduleInfoMap[ts.getOriginalNodeId(node)] = currentModuleInfo;
            // Perform the transformation.
            var transformModule = getTransformModuleDelegate(moduleKind);
            var updated = transformModule(node);
            currentSourceFile = undefined;
            currentModuleInfo = undefined;
            needUMDDynamicImportHelper = false;
            return ts.aggregateTransformFlags(updated);
        }
        function shouldEmitUnderscoreUnderscoreESModule() {
            if (!currentModuleInfo.exportEquals && ts.isExternalModule(currentSourceFile)) {
                return true;
            }
            return false;
        }
        /**
         * Transforms a SourceFile into a CommonJS module.
         *
         * @param node The SourceFile node.
         */
        function transformCommonJSModule(node) {
            startLexicalEnvironment();
            var statements = [];
            var ensureUseStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict && !ts.isJsonSourceFile(node), sourceElementVisitor);
            if (shouldEmitUnderscoreUnderscoreESModule()) {
                ts.append(statements, createUnderscoreUnderscoreESModule());
            }
            if (ts.length(currentModuleInfo.exportedNames)) {
                ts.append(statements, ts.createExpressionStatement(ts.reduceLeft(currentModuleInfo.exportedNames, function (prev, nextId) { return ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.createIdentifier(ts.idText(nextId))), prev); }, ts.createVoidZero())));
            }
            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Transforms a SourceFile into an AMD module.
         *
         * @param node The SourceFile node.
         */
        function transformAMDModule(node) {
            var define = ts.createIdentifier("define");
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var jsonSourceFile = ts.isJsonSourceFile(node) && node;
            // An AMD define function has the following shape:
            //
            //     define(id?, dependencies?, factory);
            //
            // This has the shape of the following:
            //
            //     define(name, ["module1", "module2"], function (module1Alias) { ... }
            //
            // The location of the alias in the parameter list in the factory function needs to
            // match the position of the module name in the dependency list.
            //
            // To ensure this is true in cases of modules with no aliases, e.g.:
            //
            //     import "module"
            //
            // or
            //
            //     /// <amd-dependency path= "a.css" />
            //
            // we need to add modules without alias names to the end of the dependencies list
            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ true), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
            // Create an updated SourceFile:
            //
            //     define(moduleName?, ["module1", "module2"], function ...
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(define, 
                /*typeArguments*/ undefined, __spreadArrays((moduleName ? [moduleName] : []), [
                    // Add the dependency array argument:
                    //
                    //     ["require", "exports", module1", "module2", ...]
                    ts.createArrayLiteral(jsonSourceFile ? ts.emptyArray : __spreadArrays([
                        ts.createLiteral("require"),
                        ts.createLiteral("exports")
                    ], aliasedModuleNames, unaliasedModuleNames)),
                    // Add the module body function argument:
                    //
                    //     function (require, exports, module1, module2) ...
                    jsonSourceFile ?
                        jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : ts.createObjectLiteral() :
                        ts.createFunctionExpression(
                        /*modifiers*/ undefined, 
                        /*asteriskToken*/ undefined, 
                        /*name*/ undefined, 
                        /*typeParameters*/ undefined, __spreadArrays([
                            ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
                            ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
                        ], importAliasNames), 
                        /*type*/ undefined, transformAsynchronousModuleBody(node))
                ])))
            ]), 
            /*location*/ node.statements));
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Transforms a SourceFile into a UMD module.
         *
         * @param node The SourceFile node.
         */
        function transformUMDModule(node) {
            var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ false), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames;
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var umdHeader = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], 
            /*type*/ undefined, ts.setTextRange(ts.createBlock([
                ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("module"), "object"), ts.createTypeCheck(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), "object")), ts.createBlock([
                    ts.createVariableStatement(
                    /*modifiers*/ undefined, [
                        ts.createVariableDeclaration("v", 
                        /*type*/ undefined, ts.createCall(ts.createIdentifier("factory"), 
                        /*typeArguments*/ undefined, [
                            ts.createIdentifier("require"),
                            ts.createIdentifier("exports")
                        ]))
                    ]),
                    ts.setEmitFlags(ts.createIf(ts.createStrictInequality(ts.createIdentifier("v"), ts.createIdentifier("undefined")), ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), ts.createIdentifier("v")))), 1 /* SingleLine */)
                ]), ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("define"), "function"), ts.createPropertyAccess(ts.createIdentifier("define"), "amd")), ts.createBlock([
                    ts.createExpressionStatement(ts.createCall(ts.createIdentifier("define"), 
                    /*typeArguments*/ undefined, __spreadArrays((moduleName ? [moduleName] : []), [
                        ts.createArrayLiteral(__spreadArrays([
                            ts.createLiteral("require"),
                            ts.createLiteral("exports")
                        ], aliasedModuleNames, unaliasedModuleNames)),
                        ts.createIdentifier("factory")
                    ])))
                ])))
            ], 
            /*multiLine*/ true), 
            /*location*/ undefined));
            // Create an updated SourceFile:
            //
            //  (function (factory) {
            //      if (typeof module === "object" && typeof module.exports === "object") {
            //          var v = factory(require, exports);
            //          if (v !== undefined) module.exports = v;
            //      }
            //      else if (typeof define === 'function' && define.amd) {
            //          define(["require", "exports"], factory);
            //      }
            //  })(function ...)
            var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(umdHeader, 
                /*typeArguments*/ undefined, [
                    // Add the module body function argument:
                    //
                    //     function (require, exports) ...
                    ts.createFunctionExpression(
                    /*modifiers*/ undefined, 
                    /*asteriskToken*/ undefined, 
                    /*name*/ undefined, 
                    /*typeParameters*/ undefined, __spreadArrays([
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"),
                        ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports")
                    ], importAliasNames), 
                    /*type*/ undefined, transformAsynchronousModuleBody(node))
                ]))
            ]), 
            /*location*/ node.statements));
            ts.addEmitHelpers(updated, context.readEmitHelpers());
            return updated;
        }
        /**
         * Collect the additional asynchronous dependencies for the module.
         *
         * @param node The source file.
         * @param includeNonAmdDependencies A value indicating whether to include non-AMD dependencies.
         */
        function collectAsynchronousDependencies(node, includeNonAmdDependencies) {
            // names of modules with corresponding parameter in the factory function
            var aliasedModuleNames = [];
            // names of modules with no corresponding parameters in factory function
            var unaliasedModuleNames = [];
            // names of the parameters in the factory function; these
            // parameters need to match the indexes of the corresponding
            // module names in aliasedModuleNames.
            var importAliasNames = [];
            // Fill in amd-dependency tags
            for (var _i = 0, _a = node.amdDependencies; _i < _a.length; _i++) {
                var amdDependency = _a[_i];
                if (amdDependency.name) {
                    aliasedModuleNames.push(ts.createLiteral(amdDependency.path));
                    importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, amdDependency.name));
                }
                else {
                    unaliasedModuleNames.push(ts.createLiteral(amdDependency.path));
                }
            }
            for (var _b = 0, _c = currentModuleInfo.externalImports; _b < _c.length; _b++) {
                var importNode = _c[_b];
                // Find the name of the external module
                var externalModuleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
                // Find the name of the module alias, if there is one
                var importAliasName = ts.getLocalNameForExternalImport(importNode, currentSourceFile);
                // It is possible that externalModuleName is undefined if it is not string literal.
                // This can happen in the invalid import syntax.
                // E.g : "import * from alias from 'someLib';"
                if (externalModuleName) {
                    if (includeNonAmdDependencies && importAliasName) {
                        // Set emitFlags on the name of the classDeclaration
                        // This is so that when printer will not substitute the identifier
                        ts.setEmitFlags(importAliasName, 4 /* NoSubstitution */);
                        aliasedModuleNames.push(externalModuleName);
                        importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName));
                    }
                    else {
                        unaliasedModuleNames.push(externalModuleName);
                    }
                }
            }
            return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames };
        }
        function getAMDImportExpressionForImport(node) {
            if (ts.isImportEqualsDeclaration(node) || ts.isExportDeclaration(node) || !ts.getExternalModuleNameLiteral(node, currentSourceFile, host, resolver, compilerOptions)) {
                return undefined;
            }
            var name = ts.getLocalNameForExternalImport(node, currentSourceFile); // TODO: GH#18217
            var expr = getHelperExpressionForImport(node, name);
            if (expr === name) {
                return undefined;
            }
            return ts.createExpressionStatement(ts.createAssignment(name, expr));
        }
        /**
         * Transforms a SourceFile into an AMD or UMD module body.
         *
         * @param node The SourceFile node.
         */
        function transformAsynchronousModuleBody(node) {
            startLexicalEnvironment();
            var statements = [];
            var statementOffset = ts.addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor);
            if (shouldEmitUnderscoreUnderscoreESModule()) {
                ts.append(statements, createUnderscoreUnderscoreESModule());
            }
            if (ts.length(currentModuleInfo.exportedNames)) {
                ts.append(statements, ts.createExpressionStatement(ts.reduceLeft(currentModuleInfo.exportedNames, function (prev, nextId) { return ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.createIdentifier(ts.idText(nextId))), prev); }, ts.createVoidZero())));
            }
            // Visit each statement of the module body.
            ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement));
            if (moduleKind === ts.ModuleKind.AMD) {
                ts.addRange(statements, ts.mapDefined(currentModuleInfo.externalImports, getAMDImportExpressionForImport));
            }
            ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset));
            // Append the 'export =' statement if provided.
            addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
            // End the lexical environment for the module body
            // and merge any new lexical declarations.
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var body = ts.createBlock(statements, /*multiLine*/ true);
            if (needUMDDynamicImportHelper) {
                ts.addEmitHelper(body, dynamicImportUMDHelper);
            }
            return body;
        }
        /**
         * Adds the down-level representation of `export=` to the statement list if one exists
         * in the source file.
         *
         * @param statements The Statement list to modify.
         * @param emitAsReturn A value indicating whether to emit the `export=` statement as a
         * return statement.
         */
        function addExportEqualsIfNeeded(statements, emitAsReturn) {
            if (currentModuleInfo.exportEquals) {
                var expressionResult = ts.visitNode(currentModuleInfo.exportEquals.expression, moduleExpressionElementVisitor);
                if (expressionResult) {
                    if (emitAsReturn) {
                        var statement = ts.createReturn(expressionResult);
                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
                        ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */);
                        statements.push(statement);
                    }
                    else {
                        var statement = ts.createExpressionStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult));
                        ts.setTextRange(statement, currentModuleInfo.exportEquals);
                        ts.setEmitFlags(statement, 1536 /* NoComments */);
                        statements.push(statement);
                    }
                }
            }
        }
        //
        // Top-Level Source Element Visitors
        //
        /**
         * Visits a node at the top level of the source file.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 260 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                case 259 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 245 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 328 /* MergeDeclarationMarker */:
                    return visitMergeDeclarationMarker(node);
                case 329 /* EndOfDeclarationMarker */:
                    return visitEndOfDeclarationMarker(node);
                default:
                    return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
            }
        }
        function moduleExpressionElementVisitor(node) {
            // This visitor does not need to descend into the tree if there is no dynamic import or destructuring assignment,
            // as export/import statements are only transformed at the top level of a file.
            if (!(node.transformFlags & 2097152 /* ContainsDynamicImport */) && !(node.transformFlags & 1024 /* ContainsDestructuringAssignment */)) {
                return node;
            }
            if (ts.isImportCall(node)) {
                return visitImportCallExpression(node);
            }
            else if (ts.isDestructuringAssignment(node)) {
                return visitDestructuringAssignment(node);
            }
            else {
                return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
            }
        }
        function destructuringNeedsFlattening(node) {
            if (ts.isObjectLiteralExpression(node)) {
                for (var _i = 0, _a = node.properties; _i < _a.length; _i++) {
                    var elem = _a[_i];
                    switch (elem.kind) {
                        case 281 /* PropertyAssignment */:
                            if (destructuringNeedsFlattening(elem.initializer)) {
                                return true;
                            }
                            break;
                        case 282 /* ShorthandPropertyAssignment */:
                            if (destructuringNeedsFlattening(elem.name)) {
                                return true;
                            }
                            break;
                        case 283 /* SpreadAssignment */:
                            if (destructuringNeedsFlattening(elem.expression)) {
                                return true;
                            }
                            break;
                        case 161 /* MethodDeclaration */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                            return false;
                        default: ts.Debug.assertNever(elem, "Unhandled object member kind");
                    }
                }
            }
            else if (ts.isArrayLiteralExpression(node)) {
                for (var _b = 0, _c = node.elements; _b < _c.length; _b++) {
                    var elem = _c[_b];
                    if (ts.isSpreadElement(elem)) {
                        if (destructuringNeedsFlattening(elem.expression)) {
                            return true;
                        }
                    }
                    else if (destructuringNeedsFlattening(elem)) {
                        return true;
                    }
                }
            }
            else if (ts.isIdentifier(node)) {
                return ts.length(getExports(node)) > (ts.isExportName(node) ? 1 : 0);
            }
            return false;
        }
        function visitDestructuringAssignment(node) {
            if (destructuringNeedsFlattening(node.left)) {
                return ts.flattenDestructuringAssignment(node, moduleExpressionElementVisitor, context, 0 /* All */, /*needsValue*/ false, createAllExportExpressions);
            }
            return ts.visitEachChild(node, moduleExpressionElementVisitor, context);
        }
        function visitImportCallExpression(node) {
            var argument = ts.visitNode(ts.firstOrUndefined(node.arguments), moduleExpressionElementVisitor);
            var containsLexicalThis = !!(node.transformFlags & 4096 /* ContainsLexicalThis */);
            switch (compilerOptions.module) {
                case ts.ModuleKind.AMD:
                    return createImportCallExpressionAMD(argument, containsLexicalThis);
                case ts.ModuleKind.UMD:
                    return createImportCallExpressionUMD(argument, containsLexicalThis);
                case ts.ModuleKind.CommonJS:
                default:
                    return createImportCallExpressionCommonJS(argument, containsLexicalThis);
            }
        }
        function createImportCallExpressionUMD(arg, containsLexicalThis) {
            // (function (factory) {
            //      ... (regular UMD)
            // }
            // })(function (require, exports, useSyncRequire) {
            //      "use strict";
            //      Object.defineProperty(exports, "__esModule", { value: true });
            //      var __syncRequire = typeof module === "object" && typeof module.exports === "object";
            //      var __resolved = new Promise(function (resolve) { resolve(); });
            //      .....
            //      __syncRequire
            //          ? __resolved.then(function () { return require(x); }) /*CommonJs Require*/
            //          : new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
            // });
            needUMDDynamicImportHelper = true;
            if (ts.isSimpleCopiableExpression(arg)) {
                var argClone = ts.isGeneratedIdentifier(arg) ? arg : ts.isStringLiteral(arg) ? ts.createLiteral(arg) : ts.setEmitFlags(ts.setTextRange(ts.getSynthesizedClone(arg), arg), 1536 /* NoComments */);
                return ts.createConditional(
                /*condition*/ ts.createIdentifier("__syncRequire"), 
                /*whenTrue*/ createImportCallExpressionCommonJS(arg, containsLexicalThis), 
                /*whenFalse*/ createImportCallExpressionAMD(argClone, containsLexicalThis));
            }
            else {
                var temp = ts.createTempVariable(hoistVariableDeclaration);
                return ts.createComma(ts.createAssignment(temp, arg), ts.createConditional(
                /*condition*/ ts.createIdentifier("__syncRequire"), 
                /*whenTrue*/ createImportCallExpressionCommonJS(temp, containsLexicalThis), 
                /*whenFalse*/ createImportCallExpressionAMD(temp, containsLexicalThis)));
            }
        }
        function createImportCallExpressionAMD(arg, containsLexicalThis) {
            // improt("./blah")
            // emit as
            // define(["require", "exports", "blah"], function (require, exports) {
            //     ...
            //     new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/
            // });
            var resolve = ts.createUniqueName("resolve");
            var reject = ts.createUniqueName("reject");
            var parameters = [
                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve),
                ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject)
            ];
            var body = ts.createBlock([
                ts.createExpressionStatement(ts.createCall(ts.createIdentifier("require"), 
                /*typeArguments*/ undefined, [ts.createArrayLiteral([arg || ts.createOmittedExpression()]), resolve, reject]))
            ]);
            var func;
            if (languageVersion >= 2 /* ES2015 */) {
                func = ts.createArrowFunction(
                /*modifiers*/ undefined, 
                /*typeParameters*/ undefined, parameters, 
                /*type*/ undefined, 
                /*equalsGreaterThanToken*/ undefined, body);
            }
            else {
                func = ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, parameters, 
                /*type*/ undefined, body);
                // if there is a lexical 'this' in the import call arguments, ensure we indicate
                // that this new function expression indicates it captures 'this' so that the
                // es2015 transformer will properly substitute 'this' with '_this'.
                if (containsLexicalThis) {
                    ts.setEmitFlags(func, 8 /* CapturesThis */);
                }
            }
            var promise = ts.createNew(ts.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
            if (compilerOptions.esModuleInterop) {
                context.requestEmitHelper(ts.importStarHelper);
                return ts.createCall(ts.createPropertyAccess(promise, ts.createIdentifier("then")), /*typeArguments*/ undefined, [ts.getUnscopedHelperName("__importStar")]);
            }
            return promise;
        }
        function createImportCallExpressionCommonJS(arg, containsLexicalThis) {
            // import("./blah")
            // emit as
            // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/
            // We have to wrap require in then callback so that require is done in asynchronously
            // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately
            var promiseResolveCall = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []);
            var requireCall = ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
            if (compilerOptions.esModuleInterop) {
                context.requestEmitHelper(ts.importStarHelper);
                requireCall = ts.createCall(ts.getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]);
            }
            var func;
            if (languageVersion >= 2 /* ES2015 */) {
                func = ts.createArrowFunction(
                /*modifiers*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, 
                /*equalsGreaterThanToken*/ undefined, requireCall);
            }
            else {
                func = ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, ts.createBlock([ts.createReturn(requireCall)]));
                // if there is a lexical 'this' in the import call arguments, ensure we indicate
                // that this new function expression indicates it captures 'this' so that the
                // es2015 transformer will properly substitute 'this' with '_this'.
                if (containsLexicalThis) {
                    ts.setEmitFlags(func, 8 /* CapturesThis */);
                }
            }
            return ts.createCall(ts.createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
        }
        function getHelperExpressionForExport(node, innerExpr) {
            if (!compilerOptions.esModuleInterop || ts.getEmitFlags(node) & 67108864 /* NeverApplyImportHelper */) {
                return innerExpr;
            }
            if (ts.getExportNeedsImportStarHelper(node)) {
                context.requestEmitHelper(ts.importStarHelper);
                return ts.createCall(ts.getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
            }
            return innerExpr;
        }
        function getHelperExpressionForImport(node, innerExpr) {
            if (!compilerOptions.esModuleInterop || ts.getEmitFlags(node) & 67108864 /* NeverApplyImportHelper */) {
                return innerExpr;
            }
            if (ts.getImportNeedsImportStarHelper(node)) {
                context.requestEmitHelper(ts.importStarHelper);
                return ts.createCall(ts.getUnscopedHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
            }
            if (ts.getImportNeedsImportDefaultHelper(node)) {
                context.requestEmitHelper(ts.importDefaultHelper);
                return ts.createCall(ts.getUnscopedHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]);
            }
            return innerExpr;
        }
        /**
         * Visits an ImportDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportDeclaration(node) {
            var statements;
            var namespaceDeclaration = ts.getNamespaceDeclarationNode(node);
            if (moduleKind !== ts.ModuleKind.AMD) {
                if (!node.importClause) {
                    // import "mod";
                    return ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createRequireCall(node)), node), node);
                }
                else {
                    var variables = [];
                    if (namespaceDeclaration && !ts.isDefaultImport(node)) {
                        // import * as n from "mod";
                        variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                        /*type*/ undefined, getHelperExpressionForImport(node, createRequireCall(node))));
                    }
                    else {
                        // import d from "mod";
                        // import { x, y } from "mod";
                        // import d, { x, y } from "mod";
                        // import d, * as n from "mod";
                        variables.push(ts.createVariableDeclaration(ts.getGeneratedNameForNode(node), 
                        /*type*/ undefined, getHelperExpressionForImport(node, createRequireCall(node))));
                        if (namespaceDeclaration && ts.isDefaultImport(node)) {
                            variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                            /*type*/ undefined, ts.getGeneratedNameForNode(node)));
                        }
                    }
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList(variables, languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), 
                    /*location*/ node), 
                    /*original*/ node));
                }
            }
            else if (namespaceDeclaration && ts.isDefaultImport(node)) {
                // import d, * as n from "mod";
                statements = ts.append(statements, ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), 
                    /*type*/ undefined, ts.getGeneratedNameForNode(node)), 
                    /*location*/ node), 
                    /*original*/ node)
                ], languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Creates a `require()` call to import an external module.
         *
         * @param importNode The declararation to import.
         */
        function createRequireCall(importNode) {
            var moduleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions);
            var args = [];
            if (moduleName) {
                args.push(moduleName);
            }
            return ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, args);
        }
        /**
         * Visits an ImportEqualsDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportEqualsDeclaration(node) {
            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
            var statements;
            if (moduleKind !== ts.ModuleKind.AMD) {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(node.name, createRequireCall(node))), node), node));
                }
                else {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(ts.getSynthesizedClone(node.name), 
                        /*type*/ undefined, createRequireCall(node))
                    ], 
                    /*flags*/ languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), node), node));
                }
            }
            else {
                if (ts.hasModifier(node, 1 /* Export */)) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(ts.getExportName(node), ts.getLocalName(node))), node), node));
                }
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportEqualsDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ExportDeclaration node.
         *
         * @param The node to visit.
         */
        function visitExportDeclaration(node) {
            if (!node.moduleSpecifier) {
                // Elide export declarations with no module specifier as they are handled
                // elsewhere.
                return undefined;
            }
            var generatedName = ts.getGeneratedNameForNode(node);
            if (node.exportClause && ts.isNamedExports(node.exportClause)) {
                var statements = [];
                // export { x, y } from "mod";
                if (moduleKind !== ts.ModuleKind.AMD) {
                    statements.push(ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList([
                        ts.createVariableDeclaration(generatedName, 
                        /*type*/ undefined, createRequireCall(node))
                    ])), 
                    /*location*/ node), 
                    /* original */ node));
                }
                for (var _i = 0, _a = node.exportClause.elements; _i < _a.length; _i++) {
                    var specifier = _a[_i];
                    if (languageVersion === 0 /* ES3 */) {
                        statements.push(ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createCreateBindingHelper(context, generatedName, ts.createLiteral(specifier.propertyName || specifier.name), specifier.propertyName ? ts.createLiteral(specifier.name) : undefined)), specifier), specifier));
                    }
                    else {
                        var exportedValue = ts.createPropertyAccess(generatedName, specifier.propertyName || specifier.name);
                        statements.push(ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(ts.getExportName(specifier), exportedValue, /* location */ undefined, /* liveBinding */ true)), specifier), specifier));
                    }
                }
                return ts.singleOrMany(statements);
            }
            else if (node.exportClause) {
                var statements = [];
                // export * as ns from "mod";
                statements.push(ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportExpression(ts.getSynthesizedClone(node.exportClause.name), moduleKind !== ts.ModuleKind.AMD ?
                    getHelperExpressionForExport(node, createRequireCall(node)) :
                    ts.createIdentifier(ts.idText(node.exportClause.name)))), node), node));
                return ts.singleOrMany(statements);
            }
            else {
                // export * from "mod";
                return ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(createExportStarHelper(context, moduleKind !== ts.ModuleKind.AMD ? createRequireCall(node) : generatedName)), node), node);
            }
        }
        /**
         * Visits an ExportAssignment node.
         *
         * @param node The node to visit.
         */
        function visitExportAssignment(node) {
            if (node.isExportEquals) {
                return undefined;
            }
            var statements;
            var original = node.original;
            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), ts.visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true);
            }
            else {
                statements = appendExportStatement(statements, ts.createIdentifier("default"), ts.visitNode(node.expression, moduleExpressionElementVisitor), /*location*/ node, /*allowComments*/ true);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a FunctionDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            var statements;
            if (ts.hasModifier(node, 1 /* Export */)) {
                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration(
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, moduleExpressionElementVisitor), 
                /*type*/ undefined, ts.visitEachChild(node.body, moduleExpressionElementVisitor, context)), 
                /*location*/ node), 
                /*original*/ node));
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a ClassDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitClassDeclaration(node) {
            var statements;
            if (ts.hasModifier(node, 1 /* Export */)) {
                statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createClassDeclaration(
                /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, moduleExpressionElementVisitor), ts.visitNodes(node.members, moduleExpressionElementVisitor)), node), node));
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a VariableStatement node.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            var statements;
            var variables;
            var expressions;
            if (ts.hasModifier(node, 1 /* Export */)) {
                var modifiers = void 0;
                // If we're exporting these variables, then these just become assignments to 'exports.x'.
                for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    if (ts.isIdentifier(variable.name) && ts.isLocalName(variable.name)) {
                        if (!modifiers) {
                            modifiers = ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier);
                        }
                        variables = ts.append(variables, variable);
                    }
                    else if (variable.initializer) {
                        expressions = ts.append(expressions, transformInitializedVariable(variable));
                    }
                }
                if (variables) {
                    statements = ts.append(statements, ts.updateVariableStatement(node, modifiers, ts.updateVariableDeclarationList(node.declarationList, variables)));
                }
                if (expressions) {
                    statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(expressions)), node), node));
                }
            }
            else {
                statements = ts.append(statements, ts.visitEachChild(node, moduleExpressionElementVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfVariableStatement(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        function createAllExportExpressions(name, value, location) {
            var exportedNames = getExports(name);
            if (exportedNames) {
                // For each additional export of the declaration, apply an export assignment.
                var expression = ts.isExportName(name) ? value : ts.createAssignment(name, value);
                for (var _i = 0, exportedNames_1 = exportedNames; _i < exportedNames_1.length; _i++) {
                    var exportName = exportedNames_1[_i];
                    // Mark the node to prevent triggering substitution.
                    ts.setEmitFlags(expression, 4 /* NoSubstitution */);
                    expression = createExportExpression(exportName, expression, /*location*/ location);
                }
                return expression;
            }
            return ts.createAssignment(name, value);
        }
        /**
         * Transforms an exported variable with an initializer into an expression.
         *
         * @param node The node to transform.
         */
        function transformInitializedVariable(node) {
            if (ts.isBindingPattern(node.name)) {
                return ts.flattenDestructuringAssignment(ts.visitNode(node, moduleExpressionElementVisitor), 
                /*visitor*/ undefined, context, 0 /* All */, 
                /*needsValue*/ false, createAllExportExpressions);
            }
            else {
                return ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), node.name), 
                /*location*/ node.name), node.initializer ? ts.visitNode(node.initializer, moduleExpressionElementVisitor) : ts.createVoidZero());
            }
        }
        /**
         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
         * and transformed declaration.
         *
         * @param node The node to visit.
         */
        function visitMergeDeclarationMarker(node) {
            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
            // declaration we do not emit a leading variable declaration. To preserve the
            // begin/end semantics of the declararation and to properly handle exports
            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
            //
            // To balance the declaration, add the exports of the elided variable
            // statement.
            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 225 /* VariableStatement */) {
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original);
            }
            return node;
        }
        /**
         * Determines whether a node has an associated EndOfDeclarationMarker.
         *
         * @param node The node to test.
         */
        function hasAssociatedEndOfDeclarationMarker(node) {
            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
        }
        /**
         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
         * declaration.
         *
         * @param node The node to visit.
         */
        function visitEndOfDeclarationMarker(node) {
            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
            // end of the transformed declaration. We use this marker to emit any deferred exports
            // of the declaration.
            var id = ts.getOriginalNodeId(node);
            var statements = deferredExports[id];
            if (statements) {
                delete deferredExports[id];
                return ts.append(statements, node);
            }
            return node;
        }
        /**
         * Appends the exports of an ImportDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            var importClause = decl.importClause;
            if (!importClause) {
                return statements;
            }
            if (importClause.name) {
                statements = appendExportsOfDeclaration(statements, importClause);
            }
            var namedBindings = importClause.namedBindings;
            if (namedBindings) {
                switch (namedBindings.kind) {
                    case 256 /* NamespaceImport */:
                        statements = appendExportsOfDeclaration(statements, namedBindings);
                        break;
                    case 257 /* NamedImports */:
                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                            var importBinding = _a[_i];
                            statements = appendExportsOfDeclaration(statements, importBinding, /* liveBinding */ true);
                        }
                        break;
                }
            }
            return statements;
        }
        /**
         * Appends the exports of an ImportEqualsDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportEqualsDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            return appendExportsOfDeclaration(statements, decl);
        }
        /**
         * Appends the exports of a VariableStatement to a statement list, returning the statement
         * list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param node The VariableStatement whose exports are to be recorded.
         */
        function appendExportsOfVariableStatement(statements, node) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                statements = appendExportsOfBindingElement(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfBindingElement(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            if (ts.isBindingPattern(decl.name)) {
                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        statements = appendExportsOfBindingElement(statements, element);
                    }
                }
            }
            else if (!ts.isGeneratedIdentifier(decl.name)) {
                statements = appendExportsOfDeclaration(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfHoistedDeclaration(statements, decl) {
            if (currentModuleInfo.exportEquals) {
                return statements;
            }
            if (ts.hasModifier(decl, 1 /* Export */)) {
                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : ts.getDeclarationName(decl);
                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), /*location*/ decl);
            }
            if (decl.name) {
                statements = appendExportsOfDeclaration(statements, decl);
            }
            return statements;
        }
        /**
         * Appends the exports of a declaration to a statement list, returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration to export.
         */
        function appendExportsOfDeclaration(statements, decl, liveBinding) {
            var name = ts.getDeclarationName(decl);
            var exportSpecifiers = currentModuleInfo.exportSpecifiers.get(ts.idText(name));
            if (exportSpecifiers) {
                for (var _i = 0, exportSpecifiers_1 = exportSpecifiers; _i < exportSpecifiers_1.length; _i++) {
                    var exportSpecifier = exportSpecifiers_1[_i];
                    statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name, /* allowComments */ undefined, liveBinding);
                }
            }
            return statements;
        }
        /**
         * Appends the down-level representation of an export to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param exportName The name of the export.
         * @param expression The expression to export.
         * @param location The location to use for source maps and comments for the export.
         * @param allowComments Whether to allow comments on the export.
         */
        function appendExportStatement(statements, exportName, expression, location, allowComments, liveBinding) {
            statements = ts.append(statements, createExportStatement(exportName, expression, location, allowComments, liveBinding));
            return statements;
        }
        function createUnderscoreUnderscoreESModule() {
            var statement;
            if (languageVersion === 0 /* ES3 */) {
                statement = ts.createExpressionStatement(createExportExpression(ts.createIdentifier("__esModule"), ts.createLiteral(/*value*/ true)));
            }
            else {
                statement = ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
                /*typeArguments*/ undefined, [
                    ts.createIdentifier("exports"),
                    ts.createLiteral("__esModule"),
                    ts.createObjectLiteral([
                        ts.createPropertyAssignment("value", ts.createLiteral(/*value*/ true))
                    ])
                ]));
            }
            ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param location The location to use for source maps and comments for the export.
         * @param allowComments An optional value indicating whether to emit comments for the statement.
         */
        function createExportStatement(name, value, location, allowComments, liveBinding) {
            var statement = ts.setTextRange(ts.createExpressionStatement(createExportExpression(name, value, /* location */ undefined, liveBinding)), location);
            ts.startOnNewLine(statement);
            if (!allowComments) {
                ts.setEmitFlags(statement, 1536 /* NoComments */);
            }
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param location The location to use for source maps and comments for the export.
         */
        function createExportExpression(name, value, location, liveBinding) {
            return ts.setTextRange(liveBinding && languageVersion !== 0 /* ES3 */ ? ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), 
            /*typeArguments*/ undefined, [
                ts.createIdentifier("exports"),
                ts.createLiteral(name),
                ts.createObjectLiteral([
                    ts.createPropertyAssignment("enumerable", ts.createLiteral(/*value*/ true)),
                    ts.createPropertyAssignment("get", ts.createFunctionExpression(
                    /*modifiers*/ undefined, 
                    /*asteriskToken*/ undefined, 
                    /*name*/ undefined, 
                    /*typeParameters*/ undefined, 
                    /*parameters*/ [], 
                    /*type*/ undefined, ts.createBlock([ts.createReturn(value)])))
                ])
            ]) : ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(name)), value), location);
        }
        //
        // Modifier Visitors
        //
        /**
         * Visit nodes to elide module-specific modifiers.
         *
         * @param node The node to visit.
         */
        function modifierVisitor(node) {
            // Elide module-specific modifiers.
            switch (node.kind) {
                case 89 /* ExportKeyword */:
                case 84 /* DefaultKeyword */:
                    return undefined;
            }
            return node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit notifications.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (node.kind === 290 /* SourceFile */) {
                currentSourceFile = node;
                currentModuleInfo = moduleInfoMap[ts.getOriginalNodeId(currentSourceFile)];
                noSubstitution = [];
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
                currentModuleInfo = undefined;
                noSubstitution = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (node.id && noSubstitution[node.id]) {
                return node;
            }
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitution for a ShorthandPropertyAssignment whose declaration name is an imported
         * or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteShorthandPropertyAssignment(node) {
            var name = node.name;
            var exportedOrImportedName = substituteExpressionIdentifier(name);
            if (exportedOrImportedName !== name) {
                // A shorthand property with an assignment initializer is probably part of a
                // destructuring assignment
                if (node.objectAssignmentInitializer) {
                    var initializer = ts.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer);
                    return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node);
                }
                return ts.setTextRange(ts.createPropertyAssignment(name, exportedOrImportedName), node);
            }
            return node;
        }
        /**
         * Substitution for an Expression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 209 /* BinaryExpression */:
                    return substituteBinaryExpression(node);
                case 208 /* PostfixUnaryExpression */:
                case 207 /* PrefixUnaryExpression */:
                    return substituteUnaryExpression(node);
            }
            return node;
        }
        /**
         * Substitution for an Identifier expression that may contain an imported or exported
         * symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
                return node;
            }
            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                var exportContainer = resolver.getReferencedExportContainer(node, ts.isExportName(node));
                if (exportContainer && exportContainer.kind === 290 /* SourceFile */) {
                    return ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(node)), 
                    /*location*/ node);
                }
                var importDeclaration = resolver.getReferencedImportDeclaration(node);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        var name = importDeclaration.propertyName || importDeclaration.name;
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(name)), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteBinaryExpression(node) {
            // When we see an assignment expression whose left-hand side is an exported symbol,
            // we should ensure all exports of that symbol are updated with the correct value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if (ts.isAssignmentOperator(node.operatorToken.kind)
                && ts.isIdentifier(node.left)
                && !ts.isGeneratedIdentifier(node.left)
                && !ts.isLocalName(node.left)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
                var exportedNames = getExports(node.left);
                if (exportedNames) {
                    // For each additional export of the declaration, apply an export assignment.
                    var expression = node;
                    for (var _i = 0, exportedNames_2 = exportedNames; _i < exportedNames_2.length; _i++) {
                        var exportName = exportedNames_2[_i];
                        // Mark the node to prevent triggering this rule again.
                        noSubstitution[ts.getNodeId(expression)] = true;
                        expression = createExportExpression(exportName, expression, /*location*/ node);
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteUnaryExpression(node) {
            // When we see a prefix or postfix increment expression whose operand is an exported
            // symbol, we should ensure all exports of that symbol are updated with the correct
            // value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if ((node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */)
                && ts.isIdentifier(node.operand)
                && !ts.isGeneratedIdentifier(node.operand)
                && !ts.isLocalName(node.operand)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
                var exportedNames = getExports(node.operand);
                if (exportedNames) {
                    var expression = node.kind === 208 /* PostfixUnaryExpression */
                        ? ts.setTextRange(ts.createBinary(node.operand, ts.createToken(node.operator === 45 /* PlusPlusToken */ ? 63 /* PlusEqualsToken */ : 64 /* MinusEqualsToken */), ts.createLiteral(1)), 
                        /*location*/ node)
                        : node;
                    for (var _i = 0, exportedNames_3 = exportedNames; _i < exportedNames_3.length; _i++) {
                        var exportName = exportedNames_3[_i];
                        // Mark the node to prevent triggering this rule again.
                        noSubstitution[ts.getNodeId(expression)] = true;
                        expression = createExportExpression(exportName, expression);
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Gets the additional exports of a name.
         *
         * @param name The name.
         */
        function getExports(name) {
            if (!ts.isGeneratedIdentifier(name)) {
                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
                    || resolver.getReferencedValueDeclaration(name);
                if (valueDeclaration) {
                    return currentModuleInfo
                        && currentModuleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)];
                }
            }
        }
    }
    ts.transformModule = transformModule;
    ts.createBindingHelper = {
        name: "typescript:commonjscreatebinding",
        importName: "__createBinding",
        scoped: false,
        priority: 1,
        text: "\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n    if (k2 === undefined) k2 = k;\n    o[k2] = m[k];\n}));"
    };
    function createCreateBindingHelper(context, module, inputName, outputName) {
        context.requestEmitHelper(ts.createBindingHelper);
        return ts.createCall(ts.getUnscopedHelperName("__createBinding"), /*typeArguments*/ undefined, __spreadArrays([ts.createIdentifier("exports"), module, inputName], (outputName ? [outputName] : [])));
    }
    ts.setModuleDefaultHelper = {
        name: "typescript:commonjscreatevalue",
        importName: "__setModuleDefault",
        scoped: false,
        priority: 1,
        text: "\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n    Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n    o[\"default\"] = v;\n});"
    };
    // emit output for the __export helper function
    var exportStarHelper = {
        name: "typescript:export-star",
        importName: "__exportStar",
        scoped: false,
        dependencies: [ts.createBindingHelper],
        priority: 2,
        text: "\n            var __exportStar = (this && this.__exportStar) || function(m, exports) {\n                for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);\n            };"
    };
    function createExportStarHelper(context, module) {
        context.requestEmitHelper(exportStarHelper);
        return ts.createCall(ts.getUnscopedHelperName("__exportStar"), /*typeArguments*/ undefined, [module, ts.createIdentifier("exports")]);
    }
    // emit helper for dynamic import
    var dynamicImportUMDHelper = {
        name: "typescript:dynamicimport-sync-require",
        scoped: true,
        text: "\n            var __syncRequire = typeof module === \"object\" && typeof module.exports === \"object\";"
    };
    // emit helper for `import * as Name from "foo"`
    ts.importStarHelper = {
        name: "typescript:commonjsimportstar",
        importName: "__importStar",
        scoped: false,
        dependencies: [ts.createBindingHelper, ts.setModuleDefaultHelper],
        priority: 2,
        text: "\nvar __importStar = (this && this.__importStar) || function (mod) {\n    if (mod && mod.__esModule) return mod;\n    var result = {};\n    if (mod != null) for (var k in mod) if (k !== \"default\" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n    __setModuleDefault(result, mod);\n    return result;\n};"
    };
    // emit helper for `import Name from "foo"`
    ts.importDefaultHelper = {
        name: "typescript:commonjsimportdefault",
        importName: "__importDefault",
        scoped: false,
        text: "\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n    return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};"
    };
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformSystemModule(context) {
        var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration;
        var compilerOptions = context.getCompilerOptions();
        var resolver = context.getEmitResolver();
        var host = context.getEmitHost();
        var previousOnSubstituteNode = context.onSubstituteNode;
        var previousOnEmitNode = context.onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.enableSubstitution(75 /* Identifier */); // Substitutes expression identifiers for imported symbols.
        context.enableSubstitution(282 /* ShorthandPropertyAssignment */); // Substitutes expression identifiers for imported symbols
        context.enableSubstitution(209 /* BinaryExpression */); // Substitutes assignments to exported symbols.
        context.enableSubstitution(207 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(208 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols.
        context.enableSubstitution(219 /* MetaProperty */); // Substitutes 'import.meta'
        context.enableEmitNotification(290 /* SourceFile */); // Restore state when substituting nodes in a file.
        var moduleInfoMap = []; // The ExternalModuleInfo for each file.
        var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found.
        var exportFunctionsMap = []; // The export function associated with a source file.
        var noSubstitutionMap = []; // Set of nodes for which substitution rules should be ignored for each file.
        var contextObjectMap = []; // The context object associated with a source file.
        var currentSourceFile; // The current file.
        var moduleInfo; // ExternalModuleInfo for the current file.
        var exportFunction; // The export function for the current file.
        var contextObject; // The context object for the current file.
        var hoistedStatements;
        var enclosingBlockScopedContainer;
        var noSubstitution; // Set of nodes for which substitution rules should be ignored.
        return ts.chainBundle(transformSourceFile);
        /**
         * Transforms the module aspects of a SourceFile.
         *
         * @param node The SourceFile node.
         */
        function transformSourceFile(node) {
            if (node.isDeclarationFile || !(ts.isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 2097152 /* ContainsDynamicImport */)) {
                return node;
            }
            var id = ts.getOriginalNodeId(node);
            currentSourceFile = node;
            enclosingBlockScopedContainer = node;
            // System modules have the following shape:
            //
            //     System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
            //
            // The parameter 'exports' here is a callback '<T>(name: string, value: T) => T' that
            // is used to publish exported values. 'exports' returns its 'value' argument so in
            // most cases expressions that mutate exported values can be rewritten as:
            //
            //     expr -> exports('name', expr)
            //
            // The only exception in this rule is postfix unary operators,
            // see comment to 'substitutePostfixUnaryExpression' for more details
            // Collect information about the external module and dependency groups.
            moduleInfo = moduleInfoMap[id] = ts.collectExternalModuleInfo(node, resolver, compilerOptions);
            // Make sure that the name of the 'exports' function does not conflict with
            // existing identifiers.
            exportFunction = ts.createUniqueName("exports");
            exportFunctionsMap[id] = exportFunction;
            contextObject = contextObjectMap[id] = ts.createUniqueName("context");
            // Add the body of the module.
            var dependencyGroups = collectDependencyGroups(moduleInfo.externalImports);
            var moduleBodyBlock = createSystemModuleBody(node, dependencyGroups);
            var moduleBodyFunction = ts.createFunctionExpression(
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, 
            /*name*/ undefined, 
            /*typeParameters*/ undefined, [
                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, exportFunction),
                ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject)
            ], 
            /*type*/ undefined, moduleBodyBlock);
            // Write the call to `System.register`
            // Clear the emit-helpers flag for later passes since we'll have already used it in the module body
            // So the helper will be emit at the correct position instead of at the top of the source-file
            var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions);
            var dependencies = ts.createArrayLiteral(ts.map(dependencyGroups, function (dependencyGroup) { return dependencyGroup.name; }));
            var updated = ts.setEmitFlags(ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([
                ts.createExpressionStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("System"), "register"), 
                /*typeArguments*/ undefined, moduleName
                    ? [moduleName, dependencies, moduleBodyFunction]
                    : [dependencies, moduleBodyFunction]))
            ]), node.statements)), 1024 /* NoTrailingComments */);
            if (!(compilerOptions.outFile || compilerOptions.out)) {
                ts.moveEmitHelpers(updated, moduleBodyBlock, function (helper) { return !helper.scoped; });
            }
            if (noSubstitution) {
                noSubstitutionMap[id] = noSubstitution;
                noSubstitution = undefined;
            }
            currentSourceFile = undefined;
            moduleInfo = undefined;
            exportFunction = undefined;
            contextObject = undefined;
            hoistedStatements = undefined;
            enclosingBlockScopedContainer = undefined;
            return ts.aggregateTransformFlags(updated);
        }
        /**
         * Collects the dependency groups for this files imports.
         *
         * @param externalImports The imports for the file.
         */
        function collectDependencyGroups(externalImports) {
            var groupIndices = ts.createMap();
            var dependencyGroups = [];
            for (var _i = 0, externalImports_1 = externalImports; _i < externalImports_1.length; _i++) {
                var externalImport = externalImports_1[_i];
                var externalModuleName = ts.getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions);
                if (externalModuleName) {
                    var text = externalModuleName.text;
                    var groupIndex = groupIndices.get(text);
                    if (groupIndex !== undefined) {
                        // deduplicate/group entries in dependency list by the dependency name
                        dependencyGroups[groupIndex].externalImports.push(externalImport);
                    }
                    else {
                        groupIndices.set(text, dependencyGroups.length);
                        dependencyGroups.push({
                            name: externalModuleName,
                            externalImports: [externalImport]
                        });
                    }
                }
            }
            return dependencyGroups;
        }
        /**
         * Adds the statements for the module body function for the source file.
         *
         * @param node The source file for the module.
         * @param dependencyGroups The grouped dependencies of the module.
         */
        function createSystemModuleBody(node, dependencyGroups) {
            // Shape of the body in system modules:
            //
            //  function (exports) {
            //      <list of local aliases for imports>
            //      <hoisted variable declarations>
            //      <hoisted function declarations>
            //      return {
            //          setters: [
            //              <list of setter function for imports>
            //          ],
            //          execute: function() {
            //              <module statements>
            //          }
            //      }
            //      <temp declarations>
            //  }
            //
            // i.e:
            //
            //   import {x} from 'file1'
            //   var y = 1;
            //   export function foo() { return y + x(); }
            //   console.log(y);
            //
            // Will be transformed to:
            //
            //  function(exports) {
            //      function foo() { return y + file_1.x(); }
            //      exports("foo", foo);
            //      var file_1, y;
            //      return {
            //          setters: [
            //              function(v) { file_1 = v }
            //          ],
            //          execute(): function() {
            //              y = 1;
            //              console.log(y);
            //          }
            //      };
            //  }
            var statements = [];
            // We start a new lexical environment in this function body, but *not* in the
            // body of the execute function. This allows us to emit temporary declarations
            // only in the outer module body and not in the inner one.
            startLexicalEnvironment();
            // Add any prologue directives.
            var ensureUseStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile));
            var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
            // var __moduleName = context_1 && context_1.id;
            statements.push(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration("__moduleName", 
                /*type*/ undefined, ts.createLogicalAnd(contextObject, ts.createPropertyAccess(contextObject, "id")))
            ])));
            // Visit the synthetic external helpers import declaration if present
            ts.visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement);
            // Visit the statements of the source file, emitting any transformations into
            // the `executeStatements` array. We do this *before* we fill the `setters` array
            // as we both emit transformations as well as aggregate some data used when creating
            // setters. This allows us to reduce the number of times we need to loop through the
            // statements of the source file.
            var executeStatements = ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset);
            // Emit early exports for function declarations.
            ts.addRange(statements, hoistedStatements);
            // We emit hoisted variables early to align roughly with our previous emit output.
            // Two key differences in this approach are:
            // - Temporary variables will appear at the top rather than at the bottom of the file
            ts.insertStatementsAfterStandardPrologue(statements, endLexicalEnvironment());
            var exportStarFunction = addExportStarIfNeeded(statements); // TODO: GH#18217
            var modifiers = node.transformFlags & 524288 /* ContainsAwait */ ?
                ts.createModifiersFromModifierFlags(256 /* Async */) :
                undefined;
            var moduleObject = ts.createObjectLiteral([
                ts.createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups)),
                ts.createPropertyAssignment("execute", ts.createFunctionExpression(modifiers, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, 
                /*parameters*/ [], 
                /*type*/ undefined, ts.createBlock(executeStatements, /*multiLine*/ true)))
            ]);
            moduleObject.multiLine = true;
            statements.push(ts.createReturn(moduleObject));
            return ts.createBlock(statements, /*multiLine*/ true);
        }
        /**
         * Adds an exportStar function to a statement list if it is needed for the file.
         *
         * @param statements A statement list.
         */
        function addExportStarIfNeeded(statements) {
            if (!moduleInfo.hasExportStarsToExportValues) {
                return;
            }
            // when resolving exports local exported entries/indirect exported entries in the module
            // should always win over entries with similar names that were added via star exports
            // to support this we store names of local/indirect exported entries in a set.
            // this set is used to filter names brought by star expors.
            // local names set should only be added if we have anything exported
            if (!moduleInfo.exportedNames && moduleInfo.exportSpecifiers.size === 0) {
                // no exported declarations (export var ...) or export specifiers (export {x})
                // check if we have any non star export declarations.
                var hasExportDeclarationWithExportClause = false;
                for (var _i = 0, _a = moduleInfo.externalImports; _i < _a.length; _i++) {
                    var externalImport = _a[_i];
                    if (externalImport.kind === 260 /* ExportDeclaration */ && externalImport.exportClause) {
                        hasExportDeclarationWithExportClause = true;
                        break;
                    }
                }
                if (!hasExportDeclarationWithExportClause) {
                    // we still need to emit exportStar helper
                    var exportStarFunction_1 = createExportStarFunction(/*localNames*/ undefined);
                    statements.push(exportStarFunction_1);
                    return exportStarFunction_1.name;
                }
            }
            var exportedNames = [];
            if (moduleInfo.exportedNames) {
                for (var _b = 0, _c = moduleInfo.exportedNames; _b < _c.length; _b++) {
                    var exportedLocalName = _c[_b];
                    if (exportedLocalName.escapedText === "default") {
                        continue;
                    }
                    // write name of exported declaration, i.e 'export var x...'
                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(exportedLocalName), ts.createTrue()));
                }
            }
            for (var _d = 0, _e = moduleInfo.externalImports; _d < _e.length; _d++) {
                var externalImport = _e[_d];
                if (externalImport.kind !== 260 /* ExportDeclaration */) {
                    continue;
                }
                if (!externalImport.exportClause) {
                    // export * from ...
                    continue;
                }
                if (ts.isNamedExports(externalImport.exportClause)) {
                    for (var _f = 0, _g = externalImport.exportClause.elements; _f < _g.length; _f++) {
                        var element = _g[_f];
                        // write name of indirectly exported entry, i.e. 'export {x} from ...'
                        exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(element.name || element.propertyName)), ts.createTrue()));
                    }
                }
                else {
                    exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(externalImport.exportClause.name)), ts.createTrue()));
                }
            }
            var exportedNamesStorageRef = ts.createUniqueName("exportedNames");
            statements.push(ts.createVariableStatement(
            /*modifiers*/ undefined, ts.createVariableDeclarationList([
                ts.createVariableDeclaration(exportedNamesStorageRef, 
                /*type*/ undefined, ts.createObjectLiteral(exportedNames, /*multiline*/ true))
            ])));
            var exportStarFunction = createExportStarFunction(exportedNamesStorageRef);
            statements.push(exportStarFunction);
            return exportStarFunction.name;
        }
        /**
         * Creates an exportStar function for the file, with an optional set of excluded local
         * names.
         *
         * @param localNames An optional reference to an object containing a set of excluded local
         * names.
         */
        function createExportStarFunction(localNames) {
            var exportStarFunction = ts.createUniqueName("exportStar");
            var m = ts.createIdentifier("m");
            var n = ts.createIdentifier("n");
            var exports = ts.createIdentifier("exports");
            var condition = ts.createStrictInequality(n, ts.createLiteral("default"));
            if (localNames) {
                condition = ts.createLogicalAnd(condition, ts.createLogicalNot(ts.createCall(ts.createPropertyAccess(localNames, "hasOwnProperty"), 
                /*typeArguments*/ undefined, [n])));
            }
            return ts.createFunctionDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, 
            /*asteriskToken*/ undefined, exportStarFunction, 
            /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, m)], 
            /*type*/ undefined, ts.createBlock([
                ts.createVariableStatement(
                /*modifiers*/ undefined, ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(exports, 
                    /*type*/ undefined, ts.createObjectLiteral([]))
                ])),
                ts.createForIn(ts.createVariableDeclarationList([
                    ts.createVariableDeclaration(n, /*type*/ undefined)
                ]), m, ts.createBlock([
                    ts.setEmitFlags(ts.createIf(condition, ts.createExpressionStatement(ts.createAssignment(ts.createElementAccess(exports, n), ts.createElementAccess(m, n)))), 1 /* SingleLine */)
                ])),
                ts.createExpressionStatement(ts.createCall(exportFunction, 
                /*typeArguments*/ undefined, [exports]))
            ], /*multiline*/ true));
        }
        /**
         * Creates an array setter callbacks for each dependency group.
         *
         * @param exportStarFunction A reference to an exportStarFunction for the file.
         * @param dependencyGroups An array of grouped dependencies.
         */
        function createSettersArray(exportStarFunction, dependencyGroups) {
            var setters = [];
            for (var _i = 0, dependencyGroups_1 = dependencyGroups; _i < dependencyGroups_1.length; _i++) {
                var group_2 = dependencyGroups_1[_i];
                // derive a unique name for parameter from the first named entry in the group
                var localName = ts.forEach(group_2.externalImports, function (i) { return ts.getLocalNameForExternalImport(i, currentSourceFile); });
                var parameterName = localName ? ts.getGeneratedNameForNode(localName) : ts.createUniqueName("");
                var statements = [];
                for (var _a = 0, _b = group_2.externalImports; _a < _b.length; _a++) {
                    var entry = _b[_a];
                    var importVariableName = ts.getLocalNameForExternalImport(entry, currentSourceFile); // TODO: GH#18217
                    switch (entry.kind) {
                        case 254 /* ImportDeclaration */:
                            if (!entry.importClause) {
                                // 'import "..."' case
                                // module is imported only for side-effects, no emit required
                                break;
                            }
                        // falls through
                        case 253 /* ImportEqualsDeclaration */:
                            ts.Debug.assert(importVariableName !== undefined);
                            // save import into the local
                            statements.push(ts.createExpressionStatement(ts.createAssignment(importVariableName, parameterName)));
                            break;
                        case 260 /* ExportDeclaration */:
                            ts.Debug.assert(importVariableName !== undefined);
                            if (entry.exportClause) {
                                if (ts.isNamedExports(entry.exportClause)) {
                                    //  export {a, b as c} from 'foo'
                                    //
                                    // emit as:
                                    //
                                    //  exports_({
                                    //     "a": _["a"],
                                    //     "c": _["b"]
                                    //  });
                                    var properties = [];
                                    for (var _c = 0, _d = entry.exportClause.elements; _c < _d.length; _c++) {
                                        var e = _d[_c];
                                        properties.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(e.name)), ts.createElementAccess(parameterName, ts.createLiteral(ts.idText(e.propertyName || e.name)))));
                                    }
                                    statements.push(ts.createExpressionStatement(ts.createCall(exportFunction, 
                                    /*typeArguments*/ undefined, [ts.createObjectLiteral(properties, /*multiline*/ true)])));
                                }
                                else {
                                    statements.push(ts.createExpressionStatement(ts.createCall(exportFunction, 
                                    /*typeArguments*/ undefined, [
                                        ts.createLiteral(ts.idText(entry.exportClause.name)),
                                        parameterName
                                    ])));
                                }
                            }
                            else {
                                //  export * from 'foo'
                                //
                                // emit as:
                                //
                                //  exportStar(foo_1_1);
                                statements.push(ts.createExpressionStatement(ts.createCall(exportStarFunction, 
                                /*typeArguments*/ undefined, [parameterName])));
                            }
                            break;
                    }
                }
                setters.push(ts.createFunctionExpression(
                /*modifiers*/ undefined, 
                /*asteriskToken*/ undefined, 
                /*name*/ undefined, 
                /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], 
                /*type*/ undefined, ts.createBlock(statements, /*multiLine*/ true)));
            }
            return ts.createArrayLiteral(setters, /*multiLine*/ true);
        }
        //
        // Top-level Source Element Visitors
        //
        /**
         * Visit source elements at the top-level of a module.
         *
         * @param node The node to visit.
         */
        function sourceElementVisitor(node) {
            switch (node.kind) {
                case 254 /* ImportDeclaration */:
                    return visitImportDeclaration(node);
                case 253 /* ImportEqualsDeclaration */:
                    return visitImportEqualsDeclaration(node);
                case 260 /* ExportDeclaration */:
                    return visitExportDeclaration(node);
                case 259 /* ExportAssignment */:
                    return visitExportAssignment(node);
                default:
                    return nestedElementVisitor(node);
            }
        }
        /**
         * Visits an ImportDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportDeclaration(node) {
            var statements;
            if (node.importClause) {
                hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile)); // TODO: GH#18217
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        function visitExportDeclaration(node) {
            ts.Debug.assertIsDefined(node);
            return undefined;
        }
        /**
         * Visits an ImportEqualsDeclaration node.
         *
         * @param node The node to visit.
         */
        function visitImportEqualsDeclaration(node) {
            ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer.");
            var statements;
            hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile)); // TODO: GH#18217
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfImportEqualsDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits an ExportAssignment node.
         *
         * @param node The node to visit.
         */
        function visitExportAssignment(node) {
            if (node.isExportEquals) {
                // Elide `export=` as it is illegal in a SystemJS module.
                return undefined;
            }
            var expression = ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression);
            var original = node.original;
            if (original && hasAssociatedEndOfDeclarationMarker(original)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), expression, /*allowComments*/ true);
            }
            else {
                return createExportStatement(ts.createIdentifier("default"), expression, /*allowComments*/ true);
            }
        }
        /**
         * Visits a FunctionDeclaration, hoisting it to the outer module body function.
         *
         * @param node The node to visit.
         */
        function visitFunctionDeclaration(node) {
            if (ts.hasModifier(node, 1 /* Export */)) {
                hoistedStatements = ts.append(hoistedStatements, ts.updateFunctionDeclaration(node, node.decorators, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), 
                /*typeParameters*/ undefined, ts.visitNodes(node.parameters, destructuringAndImportCallVisitor, ts.isParameterDeclaration), 
                /*type*/ undefined, ts.visitNode(node.body, destructuringAndImportCallVisitor, ts.isBlock)));
            }
            else {
                hoistedStatements = ts.append(hoistedStatements, ts.visitEachChild(node, destructuringAndImportCallVisitor, context));
            }
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node);
            }
            return undefined;
        }
        /**
         * Visits a ClassDeclaration, hoisting its name to the outer module body function.
         *
         * @param node The node to visit.
         */
        function visitClassDeclaration(node) {
            var statements;
            // Hoist the name of the class declaration to the outer module body function.
            var name = ts.getLocalName(node);
            hoistVariableDeclaration(name);
            // Rewrite the class declaration into an assignment of a class expression.
            statements = ts.append(statements, ts.setTextRange(ts.createExpressionStatement(ts.createAssignment(name, ts.setTextRange(ts.createClassExpression(
            /*modifiers*/ undefined, node.name, 
            /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, destructuringAndImportCallVisitor, ts.isHeritageClause), ts.visitNodes(node.members, destructuringAndImportCallVisitor, ts.isClassElement)), node))), node));
            if (hasAssociatedEndOfDeclarationMarker(node)) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node);
            }
            else {
                statements = appendExportsOfHoistedDeclaration(statements, node);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Visits a variable statement, hoisting declared names to the top-level module body.
         * Each declaration is rewritten into an assignment expression.
         *
         * @param node The node to visit.
         */
        function visitVariableStatement(node) {
            if (!shouldHoistVariableDeclarationList(node.declarationList)) {
                return ts.visitNode(node, destructuringAndImportCallVisitor, ts.isStatement);
            }
            var expressions;
            var isExportedDeclaration = ts.hasModifier(node, 1 /* Export */);
            var isMarkedDeclaration = hasAssociatedEndOfDeclarationMarker(node);
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var variable = _a[_i];
                if (variable.initializer) {
                    expressions = ts.append(expressions, transformInitializedVariable(variable, isExportedDeclaration && !isMarkedDeclaration));
                }
                else {
                    hoistBindingElement(variable);
                }
            }
            var statements;
            if (expressions) {
                statements = ts.append(statements, ts.setTextRange(ts.createExpressionStatement(ts.inlineExpressions(expressions)), node));
            }
            if (isMarkedDeclaration) {
                // Defer exports until we encounter an EndOfDeclarationMarker node
                var id = ts.getOriginalNodeId(node);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node, isExportedDeclaration);
            }
            else {
                statements = appendExportsOfVariableStatement(statements, node, /*exportSelf*/ false);
            }
            return ts.singleOrMany(statements);
        }
        /**
         * Hoists the declared names of a VariableDeclaration or BindingElement.
         *
         * @param node The declaration to hoist.
         */
        function hoistBindingElement(node) {
            if (ts.isBindingPattern(node.name)) {
                for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        hoistBindingElement(element);
                    }
                }
            }
            else {
                hoistVariableDeclaration(ts.getSynthesizedClone(node.name));
            }
        }
        /**
         * Determines whether a VariableDeclarationList should be hoisted.
         *
         * @param node The node to test.
         */
        function shouldHoistVariableDeclarationList(node) {
            // hoist only non-block scoped declarations or block scoped declarations parented by source file
            return (ts.getEmitFlags(node) & 2097152 /* NoHoisting */) === 0
                && (enclosingBlockScopedContainer.kind === 290 /* SourceFile */
                    || (ts.getOriginalNode(node).flags & 3 /* BlockScoped */) === 0);
        }
        /**
         * Transform an initialized variable declaration into an expression.
         *
         * @param node The node to transform.
         * @param isExportedDeclaration A value indicating whether the variable is exported.
         */
        function transformInitializedVariable(node, isExportedDeclaration) {
            var createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment;
            return ts.isBindingPattern(node.name)
                ? ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
                /*needsValue*/ false, createAssignment)
                : node.initializer ? createAssignment(node.name, ts.visitNode(node.initializer, destructuringAndImportCallVisitor, ts.isExpression)) : node.name;
        }
        /**
         * Creates an assignment expression for an exported variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         */
        function createExportedVariableAssignment(name, value, location) {
            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ true);
        }
        /**
         * Creates an assignment expression for a non-exported variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         */
        function createNonExportedVariableAssignment(name, value, location) {
            return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ false);
        }
        /**
         * Creates an assignment expression for a variable declaration.
         *
         * @param name The name of the variable.
         * @param value The value of the variable's initializer.
         * @param location The source map location for the assignment.
         * @param isExportedDeclaration A value indicating whether the variable is exported.
         */
        function createVariableAssignment(name, value, location, isExportedDeclaration) {
            hoistVariableDeclaration(ts.getSynthesizedClone(name));
            return isExportedDeclaration
                ? createExportExpression(name, preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location)))
                : preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location));
        }
        /**
         * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged
         * and transformed declaration.
         *
         * @param node The node to visit.
         */
        function visitMergeDeclarationMarker(node) {
            // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding
            // declaration we do not emit a leading variable declaration. To preserve the
            // begin/end semantics of the declararation and to properly handle exports
            // we wrapped the leading variable declaration in a `MergeDeclarationMarker`.
            //
            // To balance the declaration, we defer the exports of the elided variable
            // statement until we visit this declaration's `EndOfDeclarationMarker`.
            if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 225 /* VariableStatement */) {
                var id = ts.getOriginalNodeId(node);
                var isExportedDeclaration = ts.hasModifier(node.original, 1 /* Export */);
                deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original, isExportedDeclaration);
            }
            return node;
        }
        /**
         * Determines whether a node has an associated EndOfDeclarationMarker.
         *
         * @param node The node to test.
         */
        function hasAssociatedEndOfDeclarationMarker(node) {
            return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0;
        }
        /**
         * Visits a DeclarationMarker used as a placeholder for the end of a transformed
         * declaration.
         *
         * @param node The node to visit.
         */
        function visitEndOfDeclarationMarker(node) {
            // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual
            // end of the transformed declaration. We use this marker to emit any deferred exports
            // of the declaration.
            var id = ts.getOriginalNodeId(node);
            var statements = deferredExports[id];
            if (statements) {
                delete deferredExports[id];
                return ts.append(statements, node);
            }
            else {
                var original = ts.getOriginalNode(node);
                if (ts.isModuleOrEnumDeclaration(original)) {
                    return ts.append(appendExportsOfDeclaration(statements, original), node);
                }
            }
            return node;
        }
        /**
         * Appends the exports of an ImportDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var importClause = decl.importClause;
            if (!importClause) {
                return statements;
            }
            if (importClause.name) {
                statements = appendExportsOfDeclaration(statements, importClause);
            }
            var namedBindings = importClause.namedBindings;
            if (namedBindings) {
                switch (namedBindings.kind) {
                    case 256 /* NamespaceImport */:
                        statements = appendExportsOfDeclaration(statements, namedBindings);
                        break;
                    case 257 /* NamedImports */:
                        for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
                            var importBinding = _a[_i];
                            statements = appendExportsOfDeclaration(statements, importBinding);
                        }
                        break;
                }
            }
            return statements;
        }
        /**
         * Appends the export of an ImportEqualsDeclaration to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfImportEqualsDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            return appendExportsOfDeclaration(statements, decl);
        }
        /**
         * Appends the exports of a VariableStatement to a statement list, returning the statement
         * list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param node The VariableStatement whose exports are to be recorded.
         * @param exportSelf A value indicating whether to also export each VariableDeclaration of
         * `nodes` declaration list.
         */
        function appendExportsOfVariableStatement(statements, node, exportSelf) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) {
                var decl = _a[_i];
                if (decl.initializer || exportSelf) {
                    statements = appendExportsOfBindingElement(statements, decl, exportSelf);
                }
            }
            return statements;
        }
        /**
         * Appends the exports of a VariableDeclaration or BindingElement to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         * @param exportSelf A value indicating whether to also export the declaration itself.
         */
        function appendExportsOfBindingElement(statements, decl, exportSelf) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            if (ts.isBindingPattern(decl.name)) {
                for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) {
                    var element = _a[_i];
                    if (!ts.isOmittedExpression(element)) {
                        statements = appendExportsOfBindingElement(statements, element, exportSelf);
                    }
                }
            }
            else if (!ts.isGeneratedIdentifier(decl.name)) {
                var excludeName = void 0;
                if (exportSelf) {
                    statements = appendExportStatement(statements, decl.name, ts.getLocalName(decl));
                    excludeName = ts.idText(decl.name);
                }
                statements = appendExportsOfDeclaration(statements, decl, excludeName);
            }
            return statements;
        }
        /**
         * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list,
         * returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration whose exports are to be recorded.
         */
        function appendExportsOfHoistedDeclaration(statements, decl) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var excludeName;
            if (ts.hasModifier(decl, 1 /* Export */)) {
                var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createLiteral("default") : decl.name;
                statements = appendExportStatement(statements, exportName, ts.getLocalName(decl));
                excludeName = ts.getTextOfIdentifierOrLiteral(exportName);
            }
            if (decl.name) {
                statements = appendExportsOfDeclaration(statements, decl, excludeName);
            }
            return statements;
        }
        /**
         * Appends the exports of a declaration to a statement list, returning the statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param decl The declaration to export.
         * @param excludeName An optional name to exclude from exports.
         */
        function appendExportsOfDeclaration(statements, decl, excludeName) {
            if (moduleInfo.exportEquals) {
                return statements;
            }
            var name = ts.getDeclarationName(decl);
            var exportSpecifiers = moduleInfo.exportSpecifiers.get(ts.idText(name));
            if (exportSpecifiers) {
                for (var _i = 0, exportSpecifiers_2 = exportSpecifiers; _i < exportSpecifiers_2.length; _i++) {
                    var exportSpecifier = exportSpecifiers_2[_i];
                    if (exportSpecifier.name.escapedText !== excludeName) {
                        statements = appendExportStatement(statements, exportSpecifier.name, name);
                    }
                }
            }
            return statements;
        }
        /**
         * Appends the down-level representation of an export to a statement list, returning the
         * statement list.
         *
         * @param statements A statement list to which the down-level export statements are to be
         * appended. If `statements` is `undefined`, a new array is allocated if statements are
         * appended.
         * @param exportName The name of the export.
         * @param expression The expression to export.
         * @param allowComments Whether to allow comments on the export.
         */
        function appendExportStatement(statements, exportName, expression, allowComments) {
            statements = ts.append(statements, createExportStatement(exportName, expression, allowComments));
            return statements;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         * @param allowComments An optional value indicating whether to emit comments for the statement.
         */
        function createExportStatement(name, value, allowComments) {
            var statement = ts.createExpressionStatement(createExportExpression(name, value));
            ts.startOnNewLine(statement);
            if (!allowComments) {
                ts.setEmitFlags(statement, 1536 /* NoComments */);
            }
            return statement;
        }
        /**
         * Creates a call to the current file's export function to export a value.
         *
         * @param name The bound name of the export.
         * @param value The exported value.
         */
        function createExportExpression(name, value) {
            var exportName = ts.isIdentifier(name) ? ts.createLiteral(name) : name;
            ts.setEmitFlags(value, ts.getEmitFlags(value) | 1536 /* NoComments */);
            return ts.setCommentRange(ts.createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value);
        }
        //
        // Top-Level or Nested Source Element Visitors
        //
        /**
         * Visit nested elements at the top-level of a module.
         *
         * @param node The node to visit.
         */
        function nestedElementVisitor(node) {
            switch (node.kind) {
                case 225 /* VariableStatement */:
                    return visitVariableStatement(node);
                case 244 /* FunctionDeclaration */:
                    return visitFunctionDeclaration(node);
                case 245 /* ClassDeclaration */:
                    return visitClassDeclaration(node);
                case 230 /* ForStatement */:
                    return visitForStatement(node);
                case 231 /* ForInStatement */:
                    return visitForInStatement(node);
                case 232 /* ForOfStatement */:
                    return visitForOfStatement(node);
                case 228 /* DoStatement */:
                    return visitDoStatement(node);
                case 229 /* WhileStatement */:
                    return visitWhileStatement(node);
                case 238 /* LabeledStatement */:
                    return visitLabeledStatement(node);
                case 236 /* WithStatement */:
                    return visitWithStatement(node);
                case 237 /* SwitchStatement */:
                    return visitSwitchStatement(node);
                case 251 /* CaseBlock */:
                    return visitCaseBlock(node);
                case 277 /* CaseClause */:
                    return visitCaseClause(node);
                case 278 /* DefaultClause */:
                    return visitDefaultClause(node);
                case 240 /* TryStatement */:
                    return visitTryStatement(node);
                case 280 /* CatchClause */:
                    return visitCatchClause(node);
                case 223 /* Block */:
                    return visitBlock(node);
                case 328 /* MergeDeclarationMarker */:
                    return visitMergeDeclarationMarker(node);
                case 329 /* EndOfDeclarationMarker */:
                    return visitEndOfDeclarationMarker(node);
                default:
                    return destructuringAndImportCallVisitor(node);
            }
        }
        /**
         * Visits the body of a ForStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateFor(node, node.initializer && visitForInitializer(node.initializer), ts.visitNode(node.condition, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.incrementor, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a ForInStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForInStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateForIn(node, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a ForOfStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitForOfStatement(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateForOf(node, node.awaitModifier, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Determines whether to hoist the initializer of a ForStatement, ForInStatement, or
         * ForOfStatement.
         *
         * @param node The node to test.
         */
        function shouldHoistForInitializer(node) {
            return ts.isVariableDeclarationList(node)
                && shouldHoistVariableDeclarationList(node);
        }
        /**
         * Visits the initializer of a ForStatement, ForInStatement, or ForOfStatement
         *
         * @param node The node to visit.
         */
        function visitForInitializer(node) {
            if (shouldHoistForInitializer(node)) {
                var expressions = void 0;
                for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) {
                    var variable = _a[_i];
                    expressions = ts.append(expressions, transformInitializedVariable(variable, /*isExportedDeclaration*/ false));
                    if (!variable.initializer) {
                        hoistBindingElement(variable);
                    }
                }
                return expressions ? ts.inlineExpressions(expressions) : ts.createOmittedExpression();
            }
            else {
                return ts.visitEachChild(node, nestedElementVisitor, context);
            }
        }
        /**
         * Visits the body of a DoStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitDoStatement(node) {
            return ts.updateDo(node, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression));
        }
        /**
         * Visits the body of a WhileStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitWhileStatement(node) {
            return ts.updateWhile(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a LabeledStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitLabeledStatement(node) {
            return ts.updateLabel(node, node.label, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a WithStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitWithStatement(node) {
            return ts.updateWith(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock));
        }
        /**
         * Visits the body of a SwitchStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitSwitchStatement(node) {
            return ts.updateSwitch(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.caseBlock, nestedElementVisitor, ts.isCaseBlock));
        }
        /**
         * Visits the body of a CaseBlock to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCaseBlock(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateCaseBlock(node, ts.visitNodes(node.clauses, nestedElementVisitor, ts.isCaseOrDefaultClause));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a CaseClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCaseClause(node) {
            return ts.updateCaseClause(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNodes(node.statements, nestedElementVisitor, ts.isStatement));
        }
        /**
         * Visits the body of a DefaultClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitDefaultClause(node) {
            return ts.visitEachChild(node, nestedElementVisitor, context);
        }
        /**
         * Visits the body of a TryStatement to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitTryStatement(node) {
            return ts.visitEachChild(node, nestedElementVisitor, context);
        }
        /**
         * Visits the body of a CatchClause to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitCatchClause(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.updateCatchClause(node, node.variableDeclaration, ts.visitNode(node.block, nestedElementVisitor, ts.isBlock));
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        /**
         * Visits the body of a Block to hoist declarations.
         *
         * @param node The node to visit.
         */
        function visitBlock(node) {
            var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer;
            enclosingBlockScopedContainer = node;
            node = ts.visitEachChild(node, nestedElementVisitor, context);
            enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
            return node;
        }
        //
        // Destructuring Assignment Visitors
        //
        /**
         * Visit nodes to flatten destructuring assignments to exported symbols.
         *
         * @param node The node to visit.
         */
        function destructuringAndImportCallVisitor(node) {
            if (ts.isDestructuringAssignment(node)) {
                return visitDestructuringAssignment(node);
            }
            else if (ts.isImportCall(node)) {
                return visitImportCallExpression(node);
            }
            else if ((node.transformFlags & 1024 /* ContainsDestructuringAssignment */) || (node.transformFlags & 2097152 /* ContainsDynamicImport */)) {
                return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
            }
            else {
                return node;
            }
        }
        function visitImportCallExpression(node) {
            // import("./blah")
            // emit as
            // System.register([], function (_export, _context) {
            //     return {
            //         setters: [],
            //         execute: () => {
            //             _context.import('./blah');
            //         }
            //     };
            // });
            return ts.createCall(ts.createPropertyAccess(contextObject, ts.createIdentifier("import")), 
            /*typeArguments*/ undefined, ts.some(node.arguments) ? [ts.visitNode(node.arguments[0], destructuringAndImportCallVisitor)] : []);
        }
        /**
         * Visits a DestructuringAssignment to flatten destructuring to exported symbols.
         *
         * @param node The node to visit.
         */
        function visitDestructuringAssignment(node) {
            if (hasExportedReferenceInDestructuringTarget(node.left)) {
                return ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, 
                /*needsValue*/ true);
            }
            return ts.visitEachChild(node, destructuringAndImportCallVisitor, context);
        }
        /**
         * Determines whether the target of a destructuring assigment refers to an exported symbol.
         *
         * @param node The destructuring target.
         */
        function hasExportedReferenceInDestructuringTarget(node) {
            if (ts.isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
                return hasExportedReferenceInDestructuringTarget(node.left);
            }
            else if (ts.isSpreadElement(node)) {
                return hasExportedReferenceInDestructuringTarget(node.expression);
            }
            else if (ts.isObjectLiteralExpression(node)) {
                return ts.some(node.properties, hasExportedReferenceInDestructuringTarget);
            }
            else if (ts.isArrayLiteralExpression(node)) {
                return ts.some(node.elements, hasExportedReferenceInDestructuringTarget);
            }
            else if (ts.isShorthandPropertyAssignment(node)) {
                return hasExportedReferenceInDestructuringTarget(node.name);
            }
            else if (ts.isPropertyAssignment(node)) {
                return hasExportedReferenceInDestructuringTarget(node.initializer);
            }
            else if (ts.isIdentifier(node)) {
                var container = resolver.getReferencedExportContainer(node);
                return container !== undefined && container.kind === 290 /* SourceFile */;
            }
            else {
                return false;
            }
        }
        //
        // Modifier Visitors
        //
        /**
         * Visit nodes to elide module-specific modifiers.
         *
         * @param node The node to visit.
         */
        function modifierVisitor(node) {
            switch (node.kind) {
                case 89 /* ExportKeyword */:
                case 84 /* DefaultKeyword */:
                    return undefined;
            }
            return node;
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit notifications.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (node.kind === 290 /* SourceFile */) {
                var id = ts.getOriginalNodeId(node);
                currentSourceFile = node;
                moduleInfo = moduleInfoMap[id];
                exportFunction = exportFunctionsMap[id];
                noSubstitution = noSubstitutionMap[id];
                contextObject = contextObjectMap[id];
                if (noSubstitution) {
                    delete noSubstitutionMap[id];
                }
                previousOnEmitNode(hint, node, emitCallback);
                currentSourceFile = undefined;
                moduleInfo = undefined;
                exportFunction = undefined;
                contextObject = undefined;
                noSubstitution = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (isSubstitutionPrevented(node)) {
                return node;
            }
            if (hint === 1 /* Expression */) {
                return substituteExpression(node);
            }
            else if (hint === 4 /* Unspecified */) {
                return substituteUnspecified(node);
            }
            return node;
        }
        /**
         * Substitute the node, if necessary.
         *
         * @param node The node to substitute.
         */
        function substituteUnspecified(node) {
            switch (node.kind) {
                case 282 /* ShorthandPropertyAssignment */:
                    return substituteShorthandPropertyAssignment(node);
            }
            return node;
        }
        /**
         * Substitution for a ShorthandPropertyAssignment whose name that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteShorthandPropertyAssignment(node) {
            var name = node.name;
            if (!ts.isGeneratedIdentifier(name) && !ts.isLocalName(name)) {
                var importDeclaration = resolver.getReferencedImportDeclaration(name);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAssignment(ts.getSynthesizedClone(name), ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default"))), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAssignment(ts.getSynthesizedClone(name), ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name))), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitute the expression, if necessary.
         *
         * @param node The node to substitute.
         */
        function substituteExpression(node) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return substituteExpressionIdentifier(node);
                case 209 /* BinaryExpression */:
                    return substituteBinaryExpression(node);
                case 207 /* PrefixUnaryExpression */:
                case 208 /* PostfixUnaryExpression */:
                    return substituteUnaryExpression(node);
                case 219 /* MetaProperty */:
                    return substituteMetaProperty(node);
            }
            return node;
        }
        /**
         * Substitution for an Identifier expression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteExpressionIdentifier(node) {
            if (ts.getEmitFlags(node) & 4096 /* HelperName */) {
                var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile);
                if (externalHelpersModuleName) {
                    return ts.createPropertyAccess(externalHelpersModuleName, node);
                }
                return node;
            }
            // When we see an identifier in an expression position that
            // points to an imported symbol, we should substitute a qualified
            // reference to the imported symbol if one is needed.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) {
                var importDeclaration = resolver.getReferencedImportDeclaration(node);
                if (importDeclaration) {
                    if (ts.isImportClause(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), 
                        /*location*/ node);
                    }
                    else if (ts.isImportSpecifier(importDeclaration)) {
                        return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)), 
                        /*location*/ node);
                    }
                }
            }
            return node;
        }
        /**
         * Substitution for a BinaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteBinaryExpression(node) {
            // When we see an assignment expression whose left-hand side is an exported symbol,
            // we should ensure all exports of that symbol are updated with the correct value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if (ts.isAssignmentOperator(node.operatorToken.kind)
                && ts.isIdentifier(node.left)
                && !ts.isGeneratedIdentifier(node.left)
                && !ts.isLocalName(node.left)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) {
                var exportedNames = getExports(node.left);
                if (exportedNames) {
                    // For each additional export of the declaration, apply an export assignment.
                    var expression = node;
                    for (var _i = 0, exportedNames_4 = exportedNames; _i < exportedNames_4.length; _i++) {
                        var exportName = exportedNames_4[_i];
                        expression = createExportExpression(exportName, preventSubstitution(expression));
                    }
                    return expression;
                }
            }
            return node;
        }
        /**
         * Substitution for a UnaryExpression that may contain an imported or exported symbol.
         *
         * @param node The node to substitute.
         */
        function substituteUnaryExpression(node) {
            // When we see a prefix or postfix increment expression whose operand is an exported
            // symbol, we should ensure all exports of that symbol are updated with the correct
            // value.
            //
            // - We do not substitute generated identifiers for any reason.
            // - We do not substitute identifiers tagged with the LocalName flag.
            // - We do not substitute identifiers that were originally the name of an enum or
            //   namespace due to how they are transformed in TypeScript.
            // - We only substitute identifiers that are exported at the top level.
            if ((node.operator === 45 /* PlusPlusToken */ || node.operator === 46 /* MinusMinusToken */)
                && ts.isIdentifier(node.operand)
                && !ts.isGeneratedIdentifier(node.operand)
                && !ts.isLocalName(node.operand)
                && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) {
                var exportedNames = getExports(node.operand);
                if (exportedNames) {
                    var expression = node.kind === 208 /* PostfixUnaryExpression */
                        ? ts.setTextRange(ts.createPrefix(node.operator, node.operand), node)
                        : node;
                    for (var _i = 0, exportedNames_5 = exportedNames; _i < exportedNames_5.length; _i++) {
                        var exportName = exportedNames_5[_i];
                        expression = createExportExpression(exportName, preventSubstitution(expression));
                    }
                    if (node.kind === 208 /* PostfixUnaryExpression */) {
                        expression = node.operator === 45 /* PlusPlusToken */
                            ? ts.createSubtract(preventSubstitution(expression), ts.createLiteral(1))
                            : ts.createAdd(preventSubstitution(expression), ts.createLiteral(1));
                    }
                    return expression;
                }
            }
            return node;
        }
        function substituteMetaProperty(node) {
            if (ts.isImportMeta(node)) {
                return ts.createPropertyAccess(contextObject, ts.createIdentifier("meta"));
            }
            return node;
        }
        /**
         * Gets the exports of a name.
         *
         * @param name The name.
         */
        function getExports(name) {
            var exportedNames;
            if (!ts.isGeneratedIdentifier(name)) {
                var valueDeclaration = resolver.getReferencedImportDeclaration(name)
                    || resolver.getReferencedValueDeclaration(name);
                if (valueDeclaration) {
                    var exportContainer = resolver.getReferencedExportContainer(name, /*prefixLocals*/ false);
                    if (exportContainer && exportContainer.kind === 290 /* SourceFile */) {
                        exportedNames = ts.append(exportedNames, ts.getDeclarationName(valueDeclaration));
                    }
                    exportedNames = ts.addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)]);
                }
            }
            return exportedNames;
        }
        /**
         * Prevent substitution of a node for this transformer.
         *
         * @param node The node which should not be substituted.
         */
        function preventSubstitution(node) {
            if (noSubstitution === undefined)
                noSubstitution = [];
            noSubstitution[ts.getNodeId(node)] = true;
            return node;
        }
        /**
         * Determines whether a node should not be substituted.
         *
         * @param node The node to test.
         */
        function isSubstitutionPrevented(node) {
            return noSubstitution && node.id && noSubstitution[node.id];
        }
    }
    ts.transformSystemModule = transformSystemModule;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function transformECMAScriptModule(context) {
        var compilerOptions = context.getCompilerOptions();
        var previousOnEmitNode = context.onEmitNode;
        var previousOnSubstituteNode = context.onSubstituteNode;
        context.onEmitNode = onEmitNode;
        context.onSubstituteNode = onSubstituteNode;
        context.enableEmitNotification(290 /* SourceFile */);
        context.enableSubstitution(75 /* Identifier */);
        var helperNameSubstitutions;
        return ts.chainBundle(transformSourceFile);
        function transformSourceFile(node) {
            if (node.isDeclarationFile) {
                return node;
            }
            if (ts.isExternalModule(node) || compilerOptions.isolatedModules) {
                var externalHelpersImportDeclaration = ts.createExternalHelpersImportDeclarationIfNeeded(node, compilerOptions);
                if (externalHelpersImportDeclaration) {
                    var statements = [];
                    var statementOffset = ts.addPrologue(statements, node.statements);
                    ts.append(statements, externalHelpersImportDeclaration);
                    ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset));
                    return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements));
                }
                else {
                    return ts.visitEachChild(node, visitor, context);
                }
            }
            return node;
        }
        function visitor(node) {
            switch (node.kind) {
                case 253 /* ImportEqualsDeclaration */:
                    // Elide `import=` as it is not legal with --module ES6
                    return undefined;
                case 259 /* ExportAssignment */:
                    return visitExportAssignment(node);
                case 260 /* ExportDeclaration */:
                    var exportDecl = node;
                    return visitExportDeclaration(exportDecl);
            }
            return node;
        }
        function visitExportAssignment(node) {
            // Elide `export=` as it is not legal with --module ES6
            return node.isExportEquals ? undefined : node;
        }
        function visitExportDeclaration(node) {
            // `export * as ns` only needs to be transformed in ES2015
            if (compilerOptions.module !== undefined && compilerOptions.module > ts.ModuleKind.ES2015) {
                return node;
            }
            // Either ill-formed or don't need to be tranformed.
            if (!node.exportClause || !ts.isNamespaceExport(node.exportClause) || !node.moduleSpecifier) {
                return node;
            }
            var oldIdentifier = node.exportClause.name;
            var synthName = ts.getGeneratedNameForNode(oldIdentifier);
            var importDecl = ts.createImportDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(synthName)), node.moduleSpecifier);
            ts.setOriginalNode(importDecl, node.exportClause);
            var exportDecl = ts.createExportDeclaration(
            /*decorators*/ undefined, 
            /*modifiers*/ undefined, ts.createNamedExports([ts.createExportSpecifier(synthName, oldIdentifier)]));
            ts.setOriginalNode(exportDecl, node);
            return [importDecl, exportDecl];
        }
        //
        // Emit Notification
        //
        /**
         * Hook for node emit.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emit A callback used to emit the node in the printer.
         */
        function onEmitNode(hint, node, emitCallback) {
            if (ts.isSourceFile(node)) {
                if ((ts.isExternalModule(node) || compilerOptions.isolatedModules) && compilerOptions.importHelpers) {
                    helperNameSubstitutions = ts.createMap();
                }
                previousOnEmitNode(hint, node, emitCallback);
                helperNameSubstitutions = undefined;
            }
            else {
                previousOnEmitNode(hint, node, emitCallback);
            }
        }
        //
        // Substitutions
        //
        /**
         * Hooks node substitutions.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to substitute.
         */
        function onSubstituteNode(hint, node) {
            node = previousOnSubstituteNode(hint, node);
            if (helperNameSubstitutions && ts.isIdentifier(node) && ts.getEmitFlags(node) & 4096 /* HelperName */) {
                return substituteHelperName(node);
            }
            return node;
        }
        function substituteHelperName(node) {
            var name = ts.idText(node);
            var substitution = helperNameSubstitutions.get(name);
            if (!substitution) {
                helperNameSubstitutions.set(name, substitution = ts.createFileLevelUniqueName(name));
            }
            return substitution;
        }
    }
    ts.transformECMAScriptModule = transformECMAScriptModule;
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function canProduceDiagnostics(node) {
        return ts.isVariableDeclaration(node) ||
            ts.isPropertyDeclaration(node) ||
            ts.isPropertySignature(node) ||
            ts.isBindingElement(node) ||
            ts.isSetAccessor(node) ||
            ts.isGetAccessor(node) ||
            ts.isConstructSignatureDeclaration(node) ||
            ts.isCallSignatureDeclaration(node) ||
            ts.isMethodDeclaration(node) ||
            ts.isMethodSignature(node) ||
            ts.isFunctionDeclaration(node) ||
            ts.isParameter(node) ||
            ts.isTypeParameterDeclaration(node) ||
            ts.isExpressionWithTypeArguments(node) ||
            ts.isImportEqualsDeclaration(node) ||
            ts.isTypeAliasDeclaration(node) ||
            ts.isConstructorDeclaration(node) ||
            ts.isIndexSignatureDeclaration(node) ||
            ts.isPropertyAccessExpression(node);
    }
    ts.canProduceDiagnostics = canProduceDiagnostics;
    function createGetSymbolAccessibilityDiagnosticForNodeName(node) {
        if (ts.isSetAccessor(node) || ts.isGetAccessor(node)) {
            return getAccessorNameVisibilityError;
        }
        else if (ts.isMethodSignature(node) || ts.isMethodDeclaration(node)) {
            return getMethodNameVisibilityError;
        }
        else {
            return createGetSymbolAccessibilityDiagnosticForNode(node);
        }
        function getAccessorNameVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (ts.hasModifier(node, 32 /* Static */)) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else if (node.parent.kind === 245 /* ClassDeclaration */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else {
                return symbolAccessibilityResult.errorModuleName ?
                    ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
            }
        }
        function getMethodNameVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (ts.hasModifier(node, 32 /* Static */)) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else if (node.parent.kind === 245 /* ClassDeclaration */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_private_name_1;
            }
            else {
                return symbolAccessibilityResult.errorModuleName ?
                    ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_private_name_1;
            }
        }
    }
    ts.createGetSymbolAccessibilityDiagnosticForNodeName = createGetSymbolAccessibilityDiagnosticForNodeName;
    function createGetSymbolAccessibilityDiagnosticForNode(node) {
        if (ts.isVariableDeclaration(node) || ts.isPropertyDeclaration(node) || ts.isPropertySignature(node) || ts.isPropertyAccessExpression(node) || ts.isBindingElement(node) || ts.isConstructorDeclaration(node)) {
            return getVariableDeclarationTypeVisibilityError;
        }
        else if (ts.isSetAccessor(node) || ts.isGetAccessor(node)) {
            return getAccessorDeclarationTypeVisibilityError;
        }
        else if (ts.isConstructSignatureDeclaration(node) || ts.isCallSignatureDeclaration(node) || ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isFunctionDeclaration(node) || ts.isIndexSignatureDeclaration(node)) {
            return getReturnTypeVisibilityError;
        }
        else if (ts.isParameter(node)) {
            if (ts.isParameterPropertyDeclaration(node, node.parent) && ts.hasModifier(node.parent, 8 /* Private */)) {
                return getVariableDeclarationTypeVisibilityError;
            }
            return getParameterDeclarationTypeVisibilityError;
        }
        else if (ts.isTypeParameterDeclaration(node)) {
            return getTypeParameterConstraintVisibilityError;
        }
        else if (ts.isExpressionWithTypeArguments(node)) {
            return getHeritageClauseVisibilityError;
        }
        else if (ts.isImportEqualsDeclaration(node)) {
            return getImportEntityNameVisibilityError;
        }
        else if (ts.isTypeAliasDeclaration(node)) {
            return getTypeAliasDeclarationVisibilityError;
        }
        else {
            return ts.Debug.assertNever(node, "Attempted to set a declaration diagnostic context for unhandled node kind: " + ts.SyntaxKind[node.kind]);
        }
        function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            if (node.kind === 242 /* VariableDeclaration */ || node.kind === 191 /* BindingElement */) {
                return symbolAccessibilityResult.errorModuleName ?
                    symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                        ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                        ts.Diagnostics.Exported_variable_0_has_or_is_using_name_1_from_private_module_2 :
                    ts.Diagnostics.Exported_variable_0_has_or_is_using_private_name_1;
            }
            // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit
            // The only exception here is if the constructor was marked as private. we are not emitting the constructor parameters at all.
            else if (node.kind === 159 /* PropertyDeclaration */ || node.kind === 194 /* PropertyAccessExpression */ || node.kind === 158 /* PropertySignature */ ||
                (node.kind === 156 /* Parameter */ && ts.hasModifier(node.parent, 8 /* Private */))) {
                // TODO(jfreeman): Deal with computed properties in error reporting.
                if (ts.hasModifier(node, 32 /* Static */)) {
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1;
                }
                else if (node.parent.kind === 245 /* ClassDeclaration */ || node.kind === 156 /* Parameter */) {
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    // Interfaces cannot have types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1;
                }
            }
        }
        function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage;
            if (node.kind === 164 /* SetAccessor */) {
                // Getters can infer the return type from the returned expression, but setters cannot, so the
                // "_from_external_module_1_but_cannot_be_named" case cannot occur.
                if (ts.hasModifier(node, 32 /* Static */)) {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1;
                }
            }
            else {
                if (ts.hasModifier(node, 32 /* Static */)) {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1;
                }
                else {
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1;
                }
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node.name,
                typeName: node.name
            };
        }
        function getReturnTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage;
            switch (node.kind) {
                case 166 /* ConstructSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 165 /* CallSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 167 /* IndexSignature */:
                    // Interfaces cannot have return types that cannot be named
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0;
                    break;
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    if (ts.hasModifier(node, 32 /* Static */)) {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0;
                    }
                    else if (node.parent.kind === 245 /* ClassDeclaration */) {
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                                ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0;
                    }
                    else {
                        // Interfaces cannot have return types that cannot be named
                        diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1 :
                            ts.Diagnostics.Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0;
                    }
                    break;
                case 244 /* FunctionDeclaration */:
                    diagnosticMessage = symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named :
                            ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1 :
                        ts.Diagnostics.Return_type_of_exported_function_has_or_is_using_private_name_0;
                    break;
                default:
                    return ts.Debug.fail("This is unknown kind for signature: " + node.kind);
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node.name || node
            };
        }
        function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult) {
            var diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult);
            return diagnosticMessage !== undefined ? {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            } : undefined;
        }
        function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) {
            switch (node.parent.kind) {
                case 162 /* Constructor */:
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1;
                case 166 /* ConstructSignature */:
                case 171 /* ConstructorType */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 165 /* CallSignature */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 167 /* IndexSignature */:
                    // Interfaces cannot have parameter types that cannot be named
                    return symbolAccessibilityResult.errorModuleName ?
                        ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1;
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    if (ts.hasModifier(node.parent, 32 /* Static */)) {
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else if (node.parent.parent.kind === 245 /* ClassDeclaration */) {
                        return symbolAccessibilityResult.errorModuleName ?
                            symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                                ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                                ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else {
                        // Interfaces cannot have parameter types that cannot be named
                        return symbolAccessibilityResult.errorModuleName ?
                            ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2 :
                            ts.Diagnostics.Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                    }
                case 244 /* FunctionDeclaration */:
                case 170 /* FunctionType */:
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_exported_function_has_or_is_using_private_name_1;
                case 164 /* SetAccessor */:
                case 163 /* GetAccessor */:
                    return symbolAccessibilityResult.errorModuleName ?
                        symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ?
                            ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named :
                            ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_name_1_from_private_module_2 :
                        ts.Diagnostics.Parameter_0_of_accessor_has_or_is_using_private_name_1;
                default:
                    return ts.Debug.fail("Unknown parent for parameter: " + ts.SyntaxKind[node.parent.kind]);
            }
        }
        function getTypeParameterConstraintVisibilityError() {
            // Type parameter constraints are named by user so we should always be able to name it
            var diagnosticMessage;
            switch (node.parent.kind) {
                case 245 /* ClassDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1;
                    break;
                case 246 /* InterfaceDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 186 /* MappedType */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_mapped_object_type_is_using_private_name_1;
                    break;
                case 171 /* ConstructorType */:
                case 166 /* ConstructSignature */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 165 /* CallSignature */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1;
                    break;
                case 161 /* MethodDeclaration */:
                case 160 /* MethodSignature */:
                    if (ts.hasModifier(node.parent, 32 /* Static */)) {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else if (node.parent.parent.kind === 245 /* ClassDeclaration */) {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1;
                    }
                    else {
                        diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1;
                    }
                    break;
                case 170 /* FunctionType */:
                case 244 /* FunctionDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1;
                    break;
                case 247 /* TypeAliasDeclaration */:
                    diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1;
                    break;
                default:
                    return ts.Debug.fail("This is unknown parent for type parameter: " + node.parent.kind);
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: node.name
            };
        }
        function getHeritageClauseVisibilityError() {
            var diagnosticMessage;
            // Heritage clause is written by user so it can always be named
            if (node.parent.parent.kind === 245 /* ClassDeclaration */) {
                // Class or Interface implemented/extended is inaccessible
                diagnosticMessage = ts.isHeritageClause(node.parent) && node.parent.token === 113 /* ImplementsKeyword */ ?
                    ts.Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
                    ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
            }
            else {
                // interface is inaccessible
                diagnosticMessage = ts.Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
            }
            return {
                diagnosticMessage: diagnosticMessage,
                errorNode: node,
                typeName: ts.getNameOfDeclaration(node.parent.parent)
            };
        }
        function getImportEntityNameVisibilityError() {
            return {
                diagnosticMessage: ts.Diagnostics.Import_declaration_0_is_using_private_name_1,
                errorNode: node,
                typeName: node.name
            };
        }
        function getTypeAliasDeclarationVisibilityError() {
            return {
                diagnosticMessage: ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
                errorNode: node.type,
                typeName: node.name
            };
        }
    }
    ts.createGetSymbolAccessibilityDiagnosticForNode = createGetSymbolAccessibilityDiagnosticForNode;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function getDeclarationDiagnostics(host, resolver, file) {
        if (file && ts.isJsonSourceFile(file)) {
            return []; // No declaration diagnostics for json for now
        }
        var compilerOptions = host.getCompilerOptions();
        var result = ts.transformNodes(resolver, host, compilerOptions, file ? [file] : ts.filter(host.getSourceFiles(), ts.isSourceFileNotJson), [transformDeclarations], /*allowDtsFiles*/ false);
        return result.diagnostics;
    }
    ts.getDeclarationDiagnostics = getDeclarationDiagnostics;
    function hasInternalAnnotation(range, currentSourceFile) {
        var comment = currentSourceFile.text.substring(range.pos, range.end);
        return ts.stringContains(comment, "@internal");
    }
    function isInternalDeclaration(node, currentSourceFile) {
        var parseTreeNode = ts.getParseTreeNode(node);
        if (parseTreeNode && parseTreeNode.kind === 156 /* Parameter */) {
            var paramIdx = parseTreeNode.parent.parameters.indexOf(parseTreeNode);
            var previousSibling = paramIdx > 0 ? parseTreeNode.parent.parameters[paramIdx - 1] : undefined;
            var text = currentSourceFile.text;
            var commentRanges = previousSibling
                ? ts.concatenate(
                // to handle
                // ... parameters, /* @internal */
                // public param: string
                ts.getTrailingCommentRanges(text, ts.skipTrivia(text, previousSibling.end + 1, /* stopAfterLineBreak */ false, /* stopAtComments */ true)), ts.getLeadingCommentRanges(text, node.pos))
                : ts.getTrailingCommentRanges(text, ts.skipTrivia(text, node.pos, /* stopAfterLineBreak */ false, /* stopAtComments */ true));
            return commentRanges && commentRanges.length && hasInternalAnnotation(ts.last(commentRanges), currentSourceFile);
        }
        var leadingCommentRanges = parseTreeNode && ts.getLeadingCommentRangesOfNode(parseTreeNode, currentSourceFile);
        return !!ts.forEach(leadingCommentRanges, function (range) {
            return hasInternalAnnotation(range, currentSourceFile);
        });
    }
    ts.isInternalDeclaration = isInternalDeclaration;
    var declarationEmitNodeBuilderFlags = 1024 /* MultilineObjectLiterals */ |
        2048 /* WriteClassExpressionAsTypeLiteral */ |
        4096 /* UseTypeOfFunction */ |
        8 /* UseStructuralFallback */ |
        524288 /* AllowEmptyTuple */ |
        4 /* GenerateNamesForShadowedTypeParams */ |
        1 /* NoTruncation */;
    /**
     * Transforms a ts file into a .d.ts file
     * This process requires type information, which is retrieved through the emit resolver. Because of this,
     * in many places this transformer assumes it will be operating on parse tree nodes directly.
     * This means that _no transforms should be allowed to occur before this one_.
     */
    function transformDeclarations(context) {
        var throwDiagnostic = function () { return ts.Debug.fail("Diagnostic emitted without context"); };
        var getSymbolAccessibilityDiagnostic = throwDiagnostic;
        var needsDeclare = true;
        var isBundledEmit = false;
        var resultHasExternalModuleIndicator = false;
        var needsScopeFixMarker = false;
        var resultHasScopeMarker = false;
        var enclosingDeclaration;
        var necessaryTypeReferences;
        var lateMarkedStatements;
        var lateStatementReplacementMap;
        var suppressNewDiagnosticContexts;
        var exportedModulesFromDeclarationEmit;
        var host = context.getEmitHost();
        var symbolTracker = {
            trackSymbol: trackSymbol,
            reportInaccessibleThisError: reportInaccessibleThisError,
            reportInaccessibleUniqueSymbolError: reportInaccessibleUniqueSymbolError,
            reportCyclicStructureError: reportCyclicStructureError,
            reportPrivateInBaseOfClassExpression: reportPrivateInBaseOfClassExpression,
            reportLikelyUnsafeImportRequiredError: reportLikelyUnsafeImportRequiredError,
            moduleResolverHost: host,
            trackReferencedAmbientModule: trackReferencedAmbientModule,
            trackExternalModuleSymbolOfImportTypeNode: trackExternalModuleSymbolOfImportTypeNode,
            reportNonlocalAugmentation: reportNonlocalAugmentation
        };
        var errorNameNode;
        var currentSourceFile;
        var refs;
        var libs;
        var emittedImports; // must be declared in container so it can be `undefined` while transformer's first pass
        var resolver = context.getEmitResolver();
        var options = context.getCompilerOptions();
        var noResolve = options.noResolve, stripInternal = options.stripInternal;
        return transformRoot;
        function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives) {
            if (!typeReferenceDirectives) {
                return;
            }
            necessaryTypeReferences = necessaryTypeReferences || ts.createMap();
            for (var _i = 0, typeReferenceDirectives_2 = typeReferenceDirectives; _i < typeReferenceDirectives_2.length; _i++) {
                var ref = typeReferenceDirectives_2[_i];
                necessaryTypeReferences.set(ref, true);
            }
        }
        function trackReferencedAmbientModule(node, symbol) {
            // If it is visible via `// <reference types="..."/>`, then we should just use that
            var directives = resolver.getTypeReferenceDirectivesForSymbol(symbol, 67108863 /* All */);
            if (ts.length(directives)) {
                return recordTypeReferenceDirectivesIfNecessary(directives);
            }
            // Otherwise we should emit a path-based reference
            var container = ts.getSourceFileOfNode(node);
            refs.set("" + ts.getOriginalNodeId(container), container);
        }
        function handleSymbolAccessibilityError(symbolAccessibilityResult) {
            if (symbolAccessibilityResult.accessibility === 0 /* Accessible */) {
                // Add aliases back onto the possible imports list if they're not there so we can try them again with updated visibility info
                if (symbolAccessibilityResult && symbolAccessibilityResult.aliasesToMakeVisible) {
                    if (!lateMarkedStatements) {
                        lateMarkedStatements = symbolAccessibilityResult.aliasesToMakeVisible;
                    }
                    else {
                        for (var _i = 0, _a = symbolAccessibilityResult.aliasesToMakeVisible; _i < _a.length; _i++) {
                            var ref = _a[_i];
                            ts.pushIfUnique(lateMarkedStatements, ref);
                        }
                    }
                }
                // TODO: Do all these accessibility checks inside/after the first pass in the checker when declarations are enabled, if possible
            }
            else {
                // Report error
                var errorInfo = getSymbolAccessibilityDiagnostic(symbolAccessibilityResult);
                if (errorInfo) {
                    if (errorInfo.typeName) {
                        context.addDiagnostic(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNode(errorInfo.typeName), symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
                    }
                    else {
                        context.addDiagnostic(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName));
                    }
                }
            }
        }
        function trackExternalModuleSymbolOfImportTypeNode(symbol) {
            if (!isBundledEmit) {
                (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
            }
        }
        function trackSymbol(symbol, enclosingDeclaration, meaning) {
            if (symbol.flags & 262144 /* TypeParameter */)
                return;
            handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true));
            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
        }
        function reportPrivateInBaseOfClassExpression(propertyName) {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName));
            }
        }
        function reportInaccessibleUniqueSymbolError() {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), "unique symbol"));
            }
        }
        function reportCyclicStructureError() {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_a_type_with_a_cyclic_structure_which_cannot_be_trivially_serialized_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode)));
            }
        }
        function reportInaccessibleThisError() {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), "this"));
            }
        }
        function reportLikelyUnsafeImportRequiredError(specifier) {
            if (errorNameNode) {
                context.addDiagnostic(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_cannot_be_named_without_a_reference_to_1_This_is_likely_not_portable_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), specifier));
            }
        }
        function reportNonlocalAugmentation(containingFile, parentSymbol, symbol) {
            var primaryDeclaration = ts.find(parentSymbol.declarations, function (d) { return ts.getSourceFileOfNode(d) === containingFile; });
            var augmentingDeclarations = ts.filter(symbol.declarations, function (d) { return ts.getSourceFileOfNode(d) !== containingFile; });
            for (var _i = 0, augmentingDeclarations_1 = augmentingDeclarations; _i < augmentingDeclarations_1.length; _i++) {
                var augmentations = augmentingDeclarations_1[_i];
                context.addDiagnostic(ts.addRelatedInfo(ts.createDiagnosticForNode(augmentations, ts.Diagnostics.Declaration_augments_declaration_in_another_file_This_cannot_be_serialized), ts.createDiagnosticForNode(primaryDeclaration, ts.Diagnostics.This_is_the_declaration_being_augmented_Consider_moving_the_augmenting_declaration_into_the_same_file)));
            }
        }
        function transformDeclarationsForJS(sourceFile, bundled) {
            var oldDiag = getSymbolAccessibilityDiagnostic;
            getSymbolAccessibilityDiagnostic = function (s) { return ({
                diagnosticMessage: s.errorModuleName
                    ? ts.Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_from_module_1_An_explicit_type_annotation_may_unblock_declaration_emit
                    : ts.Diagnostics.Declaration_emit_for_this_file_requires_using_private_name_0_An_explicit_type_annotation_may_unblock_declaration_emit,
                errorNode: s.errorNode || sourceFile
            }); };
            var result = resolver.getDeclarationStatementsForSourceFile(sourceFile, declarationEmitNodeBuilderFlags, symbolTracker, bundled);
            getSymbolAccessibilityDiagnostic = oldDiag;
            return result;
        }
        function transformRoot(node) {
            if (node.kind === 290 /* SourceFile */ && node.isDeclarationFile) {
                return node;
            }
            if (node.kind === 291 /* Bundle */) {
                isBundledEmit = true;
                refs = ts.createMap();
                libs = ts.createMap();
                var hasNoDefaultLib_1 = false;
                var bundle = ts.createBundle(ts.map(node.sourceFiles, function (sourceFile) {
                    if (sourceFile.isDeclarationFile)
                        return undefined; // Omit declaration files from bundle results, too // TODO: GH#18217
                    hasNoDefaultLib_1 = hasNoDefaultLib_1 || sourceFile.hasNoDefaultLib;
                    currentSourceFile = sourceFile;
                    enclosingDeclaration = sourceFile;
                    lateMarkedStatements = undefined;
                    suppressNewDiagnosticContexts = false;
                    lateStatementReplacementMap = ts.createMap();
                    getSymbolAccessibilityDiagnostic = throwDiagnostic;
                    needsScopeFixMarker = false;
                    resultHasScopeMarker = false;
                    collectReferences(sourceFile, refs);
                    collectLibs(sourceFile, libs);
                    if (ts.isExternalOrCommonJsModule(sourceFile) || ts.isJsonSourceFile(sourceFile)) {
                        resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules)
                        needsDeclare = false;
                        var statements = ts.isSourceFileJS(sourceFile) ? ts.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : ts.visitNodes(sourceFile.statements, visitDeclarationStatements);
                        var newFile = ts.updateSourceFileNode(sourceFile, [ts.createModuleDeclaration([], [ts.createModifier(130 /* DeclareKeyword */)], ts.createLiteral(ts.getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), ts.createModuleBlock(ts.setTextRange(ts.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), sourceFile.statements)))], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
                        return newFile;
                    }
                    needsDeclare = true;
                    var updated = ts.isSourceFileJS(sourceFile) ? ts.createNodeArray(transformDeclarationsForJS(sourceFile)) : ts.visitNodes(sourceFile.statements, visitDeclarationStatements);
                    return ts.updateSourceFileNode(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
                }), ts.mapDefined(node.prepends, function (prepend) {
                    if (prepend.kind === 293 /* InputFiles */) {
                        var sourceFile = ts.createUnparsedSourceFile(prepend, "dts", stripInternal);
                        hasNoDefaultLib_1 = hasNoDefaultLib_1 || !!sourceFile.hasNoDefaultLib;
                        collectReferences(sourceFile, refs);
                        recordTypeReferenceDirectivesIfNecessary(sourceFile.typeReferenceDirectives);
                        collectLibs(sourceFile, libs);
                        return sourceFile;
                    }
                    return prepend;
                }));
                bundle.syntheticFileReferences = [];
                bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
                bundle.syntheticLibReferences = getLibReferences();
                bundle.hasNoDefaultLib = hasNoDefaultLib_1;
                var outputFilePath_1 = ts.getDirectoryPath(ts.normalizeSlashes(ts.getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
                var referenceVisitor_1 = mapReferencesIntoArray(bundle.syntheticFileReferences, outputFilePath_1);
                refs.forEach(referenceVisitor_1);
                return bundle;
            }
            // Single source file
            needsDeclare = true;
            needsScopeFixMarker = false;
            resultHasScopeMarker = false;
            enclosingDeclaration = node;
            currentSourceFile = node;
            getSymbolAccessibilityDiagnostic = throwDiagnostic;
            isBundledEmit = false;
            resultHasExternalModuleIndicator = false;
            suppressNewDiagnosticContexts = false;
            lateMarkedStatements = undefined;
            lateStatementReplacementMap = ts.createMap();
            necessaryTypeReferences = undefined;
            refs = collectReferences(currentSourceFile, ts.createMap());
            libs = collectLibs(currentSourceFile, ts.createMap());
            var references = [];
            var outputFilePath = ts.getDirectoryPath(ts.normalizeSlashes(ts.getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
            var referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
            var combinedStatements;
            if (ts.isSourceFileJS(currentSourceFile)) {
                combinedStatements = ts.createNodeArray(transformDeclarationsForJS(node));
                refs.forEach(referenceVisitor);
                emittedImports = ts.filter(combinedStatements, ts.isAnyImportSyntax);
            }
            else {
                var statements = ts.visitNodes(node.statements, visitDeclarationStatements);
                combinedStatements = ts.setTextRange(ts.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements);
                refs.forEach(referenceVisitor);
                emittedImports = ts.filter(combinedStatements, ts.isAnyImportSyntax);
                if (ts.isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) {
                    combinedStatements = ts.setTextRange(ts.createNodeArray(__spreadArrays(combinedStatements, [ts.createEmptyExports()])), combinedStatements);
                }
            }
            var updated = ts.updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
            updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
            return updated;
            function getLibReferences() {
                return ts.map(ts.arrayFrom(libs.keys()), function (lib) { return ({ fileName: lib, pos: -1, end: -1 }); });
            }
            function getFileReferencesForUsedTypeReferences() {
                return necessaryTypeReferences ? ts.mapDefined(ts.arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForTypeName) : [];
            }
            function getFileReferenceForTypeName(typeName) {
                // Elide type references for which we have imports
                if (emittedImports) {
                    for (var _i = 0, emittedImports_1 = emittedImports; _i < emittedImports_1.length; _i++) {
                        var importStatement = emittedImports_1[_i];
                        if (ts.isImportEqualsDeclaration(importStatement) && ts.isExternalModuleReference(importStatement.moduleReference)) {
                            var expr = importStatement.moduleReference.expression;
                            if (ts.isStringLiteralLike(expr) && expr.text === typeName) {
                                return undefined;
                            }
                        }
                        else if (ts.isImportDeclaration(importStatement) && ts.isStringLiteral(importStatement.moduleSpecifier) && importStatement.moduleSpecifier.text === typeName) {
                            return undefined;
                        }
                    }
                }
                return { fileName: typeName, pos: -1, end: -1 };
            }
            function mapReferencesIntoArray(references, outputFilePath) {
                return function (file) {
                    var declFileName;
                    if (file.isDeclarationFile) { // Neither decl files or js should have their refs changed
                        declFileName = file.fileName;
                    }
                    else {
                        if (isBundledEmit && ts.contains(node.sourceFiles, file))
                            return; // Omit references to files which are being merged
                        var paths = ts.getOutputPathsFor(file, host, /*forceDtsPaths*/ true);
                        declFileName = paths.declarationFilePath || paths.jsFilePath || file.fileName;
                    }
                    if (declFileName) {
                        var specifier = ts.moduleSpecifiers.getModuleSpecifier(__assign(__assign({}, options), { baseUrl: options.baseUrl && ts.toPath(options.baseUrl, host.getCurrentDirectory(), host.getCanonicalFileName) }), currentSourceFile, ts.toPath(outputFilePath, host.getCurrentDirectory(), host.getCanonicalFileName), ts.toPath(declFileName, host.getCurrentDirectory(), host.getCanonicalFileName), host, 
                        /*preferences*/ undefined);
                        if (!ts.pathIsRelative(specifier)) {
                            // If some compiler option/symlink/whatever allows access to the file containing the ambient module declaration
                            // via a non-relative name, emit a type reference directive to that non-relative name, rather than
                            // a relative path to the declaration file
                            recordTypeReferenceDirectivesIfNecessary([specifier]);
                            return;
                        }
                        var fileName = ts.getRelativePathToDirectoryOrUrl(outputFilePath, declFileName, host.getCurrentDirectory(), host.getCanonicalFileName, 
                        /*isAbsolutePathAnUrl*/ false);
                        if (ts.startsWith(fileName, "./") && ts.hasExtension(fileName)) {
                            fileName = fileName.substring(2);
                        }
                        // omit references to files from node_modules (npm may disambiguate module
                        // references when installing this package, making the path is unreliable).
                        if (ts.startsWith(fileName, "node_modules/") || ts.pathContainsNodeModules(fileName)) {
                            return;
                        }
                        references.push({ pos: -1, end: -1, fileName: fileName });
                    }
                };
            }
        }
        function collectReferences(sourceFile, ret) {
            if (noResolve || (!ts.isUnparsedSource(sourceFile) && ts.isSourceFileJS(sourceFile)))
                return ret;
            ts.forEach(sourceFile.referencedFiles, function (f) {
                var elem = host.getSourceFileFromReference(sourceFile, f);
                if (elem) {
                    ret.set("" + ts.getOriginalNodeId(elem), elem);
                }
            });
            return ret;
        }
        function collectLibs(sourceFile, ret) {
            ts.forEach(sourceFile.libReferenceDirectives, function (ref) {
                var lib = host.getLibFileFromReference(ref);
                if (lib) {
                    ret.set(ts.toFileNameLowerCase(ref.fileName), true);
                }
            });
            return ret;
        }
        function filterBindingPatternInitializers(name) {
            if (name.kind === 75 /* Identifier */) {
                return name;
            }
            else {
                if (name.kind === 190 /* ArrayBindingPattern */) {
                    return ts.updateArrayBindingPattern(name, ts.visitNodes(name.elements, visitBindingElement));
                }
                else {
                    return ts.updateObjectBindingPattern(name, ts.visitNodes(name.elements, visitBindingElement));
                }
            }
            function visitBindingElement(elem) {
                if (elem.kind === 215 /* OmittedExpression */) {
                    return elem;
                }
                return ts.updateBindingElement(elem, elem.dotDotDotToken, elem.propertyName, filterBindingPatternInitializers(elem.name), shouldPrintWithInitializer(elem) ? elem.initializer : undefined);
            }
        }
        function ensureParameter(p, modifierMask, type) {
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(p);
            }
            var newParam = ts.updateParameter(p, 
            /*decorators*/ undefined, maskModifiers(p, modifierMask), p.dotDotDotToken, filterBindingPatternInitializers(p.name), resolver.isOptionalParameter(p) ? (p.questionToken || ts.createToken(57 /* QuestionToken */)) : undefined, ensureType(p, type || p.type, /*ignorePrivate*/ true), // Ignore private param props, since this type is going straight back into a param
            ensureNoInitializer(p));
            if (!suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = oldDiag;
            }
            return newParam;
        }
        function shouldPrintWithInitializer(node) {
            return canHaveLiteralInitializer(node) && resolver.isLiteralConstDeclaration(ts.getParseTreeNode(node)); // TODO: Make safe
        }
        function ensureNoInitializer(node) {
            if (shouldPrintWithInitializer(node)) {
                return resolver.createLiteralConstValue(ts.getParseTreeNode(node), symbolTracker); // TODO: Make safe
            }
            return undefined;
        }
        function ensureType(node, type, ignorePrivate) {
            if (!ignorePrivate && ts.hasModifier(node, 8 /* Private */)) {
                // Private nodes emit no types (except private parameter properties, whose parameter types are actually visible)
                return;
            }
            if (shouldPrintWithInitializer(node)) {
                // Literal const declarations will have an initializer ensured rather than a type
                return;
            }
            var shouldUseResolverType = node.kind === 156 /* Parameter */ &&
                (resolver.isRequiredInitializedParameter(node) ||
                    resolver.isOptionalUninitializedParameterProperty(node));
            if (type && !shouldUseResolverType) {
                return ts.visitNode(type, visitDeclarationSubtree);
            }
            if (!ts.getParseTreeNode(node)) {
                return type ? ts.visitNode(type, visitDeclarationSubtree) : ts.createKeywordTypeNode(125 /* AnyKeyword */);
            }
            if (node.kind === 164 /* SetAccessor */) {
                // Set accessors with no associated type node (from it's param or get accessor return) are `any` since they are never contextually typed right now
                // (The inferred type here will be void, but the old declaration emitter printed `any`, so this replicates that)
                return ts.createKeywordTypeNode(125 /* AnyKeyword */);
            }
            errorNameNode = node.name;
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(node);
            }
            if (node.kind === 242 /* VariableDeclaration */ || node.kind === 191 /* BindingElement */) {
                return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            }
            if (node.kind === 156 /* Parameter */
                || node.kind === 159 /* PropertyDeclaration */
                || node.kind === 158 /* PropertySignature */) {
                if (!node.initializer)
                    return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType));
                return cleanup(resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldUseResolverType) || resolver.createTypeOfExpression(node.initializer, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            }
            return cleanup(resolver.createReturnTypeOfSignatureDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker));
            function cleanup(returnValue) {
                errorNameNode = undefined;
                if (!suppressNewDiagnosticContexts) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                return returnValue || ts.createKeywordTypeNode(125 /* AnyKeyword */);
            }
        }
        function isDeclarationAndNotVisible(node) {
            node = ts.getParseTreeNode(node);
            switch (node.kind) {
                case 244 /* FunctionDeclaration */:
                case 249 /* ModuleDeclaration */:
                case 246 /* InterfaceDeclaration */:
                case 245 /* ClassDeclaration */:
                case 247 /* TypeAliasDeclaration */:
                case 248 /* EnumDeclaration */:
                    return !resolver.isDeclarationVisible(node);
                // The following should be doing their own visibility checks based on filtering their members
                case 242 /* VariableDeclaration */:
                    return !getBindingNameVisible(node);
                case 253 /* ImportEqualsDeclaration */:
                case 254 /* ImportDeclaration */:
                case 260 /* ExportDeclaration */:
                case 259 /* ExportAssignment */:
                    return false;
            }
            return false;
        }
        function getBindingNameVisible(elem) {
            if (ts.isOmittedExpression(elem)) {
                return false;
            }
            if (ts.isBindingPattern(elem.name)) {
                // If any child binding pattern element has been marked visible (usually by collect linked aliases), then this is visible
                return ts.some(elem.name.elements, getBindingNameVisible);
            }
            else {
                return resolver.isDeclarationVisible(elem);
            }
        }
        function updateParamsList(node, params, modifierMask) {
            if (ts.hasModifier(node, 8 /* Private */)) {
                return undefined; // TODO: GH#18217
            }
            var newParams = ts.map(params, function (p) { return ensureParameter(p, modifierMask); });
            if (!newParams) {
                return undefined; // TODO: GH#18217
            }
            return ts.createNodeArray(newParams, params.hasTrailingComma);
        }
        function updateAccessorParamsList(input, isPrivate) {
            var newParams;
            if (!isPrivate) {
                var thisParameter = ts.getThisParameter(input);
                if (thisParameter) {
                    newParams = [ensureParameter(thisParameter)];
                }
            }
            if (ts.isSetAccessorDeclaration(input)) {
                var newValueParameter = void 0;
                if (!isPrivate) {
                    var valueParameter = ts.getSetAccessorValueParameter(input);
                    if (valueParameter) {
                        var accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
                        newValueParameter = ensureParameter(valueParameter, /*modifierMask*/ undefined, accessorType);
                    }
                }
                if (!newValueParameter) {
                    newValueParameter = ts.createParameter(
                    /*decorators*/ undefined, 
                    /*modifiers*/ undefined, 
                    /*dotDotDotToken*/ undefined, "value");
                }
                newParams = ts.append(newParams, newValueParameter);
            }
            return ts.createNodeArray(newParams || ts.emptyArray);
        }
        function ensureTypeParams(node, params) {
            return ts.hasModifier(node, 8 /* Private */) ? undefined : ts.visitNodes(params, visitDeclarationSubtree);
        }
        function isEnclosingDeclaration(node) {
            return ts.isSourceFile(node)
                || ts.isTypeAliasDeclaration(node)
                || ts.isModuleDeclaration(node)
                || ts.isClassDeclaration(node)
                || ts.isInterfaceDeclaration(node)
                || ts.isFunctionLike(node)
                || ts.isIndexSignatureDeclaration(node)
                || ts.isMappedTypeNode(node);
        }
        function checkEntityNameVisibility(entityName, enclosingDeclaration) {
            var visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration);
            handleSymbolAccessibilityError(visibilityResult);
            recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName));
        }
        function preserveJsDoc(updated, original) {
            if (ts.hasJSDocNodes(updated) && ts.hasJSDocNodes(original)) {
                updated.jsDoc = original.jsDoc;
            }
            return ts.setCommentRange(updated, ts.getCommentRange(original));
        }
        function rewriteModuleSpecifier(parent, input) {
            if (!input)
                return undefined; // TODO: GH#18217
            resultHasExternalModuleIndicator = resultHasExternalModuleIndicator || (parent.kind !== 249 /* ModuleDeclaration */ && parent.kind !== 188 /* ImportType */);
            if (ts.isStringLiteralLike(input)) {
                if (isBundledEmit) {
                    var newName = ts.getExternalModuleNameFromDeclaration(context.getEmitHost(), resolver, parent);
                    if (newName) {
                        return ts.createLiteral(newName);
                    }
                }
                else {
                    var symbol = resolver.getSymbolOfExternalModuleSpecifier(input);
                    if (symbol) {
                        (exportedModulesFromDeclarationEmit || (exportedModulesFromDeclarationEmit = [])).push(symbol);
                    }
                }
            }
            return input;
        }
        function transformImportEqualsDeclaration(decl) {
            if (!resolver.isDeclarationVisible(decl))
                return;
            if (decl.moduleReference.kind === 265 /* ExternalModuleReference */) {
                // Rewrite external module names if necessary
                var specifier = ts.getExternalModuleImportEqualsDeclarationExpression(decl);
                return ts.updateImportEqualsDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, decl.name, ts.updateExternalModuleReference(decl.moduleReference, rewriteModuleSpecifier(decl, specifier)));
            }
            else {
                var oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(decl);
                checkEntityNameVisibility(decl.moduleReference, enclosingDeclaration);
                getSymbolAccessibilityDiagnostic = oldDiag;
                return decl;
            }
        }
        function transformImportDeclaration(decl) {
            if (!decl.importClause) {
                // import "mod" - possibly needed for side effects? (global interface patches, module augmentations, etc)
                return ts.updateImportDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, decl.importClause, rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            // The `importClause` visibility corresponds to the default's visibility.
            var visibleDefaultBinding = decl.importClause && decl.importClause.name && resolver.isDeclarationVisible(decl.importClause) ? decl.importClause.name : undefined;
            if (!decl.importClause.namedBindings) {
                // No named bindings (either namespace or list), meaning the import is just default or should be elided
                return visibleDefaultBinding && ts.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, 
                /*namedBindings*/ undefined, decl.importClause.isTypeOnly), rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            if (decl.importClause.namedBindings.kind === 256 /* NamespaceImport */) {
                // Namespace import (optionally with visible default)
                var namedBindings = resolver.isDeclarationVisible(decl.importClause.namedBindings) ? decl.importClause.namedBindings : /*namedBindings*/ undefined;
                return visibleDefaultBinding || namedBindings ? ts.updateImportDeclaration(decl, /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, namedBindings, decl.importClause.isTypeOnly), rewriteModuleSpecifier(decl, decl.moduleSpecifier)) : undefined;
            }
            // Named imports (optionally with visible default)
            var bindingList = ts.mapDefined(decl.importClause.namedBindings.elements, function (b) { return resolver.isDeclarationVisible(b) ? b : undefined; });
            if ((bindingList && bindingList.length) || visibleDefaultBinding) {
                return ts.updateImportDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, ts.updateImportClause(decl.importClause, visibleDefaultBinding, bindingList && bindingList.length ? ts.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, decl.importClause.isTypeOnly), rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            // Augmentation of export depends on import
            if (resolver.isImportRequiredByAugmentation(decl)) {
                return ts.updateImportDeclaration(decl, 
                /*decorators*/ undefined, decl.modifiers, 
                /*importClause*/ undefined, rewriteModuleSpecifier(decl, decl.moduleSpecifier));
            }
            // Nothing visible
        }
        function transformAndReplaceLatePaintedStatements(statements) {
            // This is a `while` loop because `handleSymbolAccessibilityError` can see additional import aliases marked as visible during
            // error handling which must now be included in the output and themselves checked for errors.
            // For example:
            // ```
            // module A {
            //   export module Q {}
            //   import B = Q;
            //   import C = B;
            //   export import D = C;
            // }
            // ```
            // In such a scenario, only Q and D are initially visible, but we don't consider imports as private names - instead we say they if they are referenced they must
            // be recorded. So while checking D's visibility we mark C as visible, then we must check C which in turn marks B, completing the chain of
            // dependent imports and allowing a valid declaration file output. Today, this dependent alias marking only happens for internal import aliases.
            while (ts.length(lateMarkedStatements)) {
                var i = lateMarkedStatements.shift();
                if (!ts.isLateVisibilityPaintedStatement(i)) {
                    return ts.Debug.fail("Late replaced statement was found which is not handled by the declaration transformer!: " + (ts.SyntaxKind ? ts.SyntaxKind[i.kind] : i.kind));
                }
                var priorNeedsDeclare = needsDeclare;
                needsDeclare = i.parent && ts.isSourceFile(i.parent) && !(ts.isExternalModule(i.parent) && isBundledEmit);
                var result = transformTopLevelDeclaration(i);
                needsDeclare = priorNeedsDeclare;
                lateStatementReplacementMap.set("" + ts.getOriginalNodeId(i), result);
            }
            // And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list
            // (and remove them from the set to examine for outter declarations)
            return ts.visitNodes(statements, visitLateVisibilityMarkedStatements);
            function visitLateVisibilityMarkedStatements(statement) {
                if (ts.isLateVisibilityPaintedStatement(statement)) {
                    var key = "" + ts.getOriginalNodeId(statement);
                    if (lateStatementReplacementMap.has(key)) {
                        var result = lateStatementReplacementMap.get(key);
                        lateStatementReplacementMap.delete(key);
                        if (result) {
                            if (ts.isArray(result) ? ts.some(result, ts.needsScopeMarker) : ts.needsScopeMarker(result)) {
                                // Top-level declarations in .d.ts files are always considered exported even without a modifier unless there's an export assignment or specifier
                                needsScopeFixMarker = true;
                            }
                            if (ts.isSourceFile(statement.parent) && (ts.isArray(result) ? ts.some(result, ts.isExternalModuleIndicator) : ts.isExternalModuleIndicator(result))) {
                                resultHasExternalModuleIndicator = true;
                            }
                        }
                        return result;
                    }
                }
                return statement;
            }
        }
        function visitDeclarationSubtree(input) {
            if (shouldStripInternal(input))
                return;
            if (ts.isDeclaration(input)) {
                if (isDeclarationAndNotVisible(input))
                    return;
                if (ts.hasDynamicName(input) && !resolver.isLateBound(ts.getParseTreeNode(input))) {
                    return;
                }
            }
            // Elide implementation signatures from overload sets
            if (ts.isFunctionLike(input) && resolver.isImplementationOfOverload(input))
                return;
            // Elide semicolon class statements
            if (ts.isSemicolonClassElement(input))
                return;
            var previousEnclosingDeclaration;
            if (isEnclosingDeclaration(input)) {
                previousEnclosingDeclaration = enclosingDeclaration;
                enclosingDeclaration = input;
            }
            var oldDiag = getSymbolAccessibilityDiagnostic;
            // Setup diagnostic-related flags before first potential `cleanup` call, otherwise
            // We'd see a TDZ violation at runtime
            var canProduceDiagnostic = ts.canProduceDiagnostics(input);
            var oldWithinObjectLiteralType = suppressNewDiagnosticContexts;
            var shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === 173 /* TypeLiteral */ || input.kind === 186 /* MappedType */) && input.parent.kind !== 247 /* TypeAliasDeclaration */);
            // Emit methods which are private as properties with no type information
            if (ts.isMethodDeclaration(input) || ts.isMethodSignature(input)) {
                if (ts.hasModifier(input, 8 /* Private */)) {
                    if (input.symbol && input.symbol.declarations && input.symbol.declarations[0] !== input)
                        return; // Elide all but the first overload
                    return cleanup(ts.createProperty(/*decorators*/ undefined, ensureModifiers(input), input.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined));
                }
            }
            if (canProduceDiagnostic && !suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(input);
            }
            if (ts.isTypeQueryNode(input)) {
                checkEntityNameVisibility(input.exprName, enclosingDeclaration);
            }
            if (shouldEnterSuppressNewDiagnosticsContextContext) {
                // We stop making new diagnostic contexts within object literal types. Unless it's an object type on the RHS of a type alias declaration. Then we do.
                suppressNewDiagnosticContexts = true;
            }
            if (isProcessedComponent(input)) {
                switch (input.kind) {
                    case 216 /* ExpressionWithTypeArguments */: {
                        if ((ts.isEntityName(input.expression) || ts.isEntityNameExpression(input.expression))) {
                            checkEntityNameVisibility(input.expression, enclosingDeclaration);
                        }
                        var node = ts.visitEachChild(input, visitDeclarationSubtree, context);
                        return cleanup(ts.updateExpressionWithTypeArguments(node, ts.parenthesizeTypeParameters(node.typeArguments), node.expression));
                    }
                    case 169 /* TypeReference */: {
                        checkEntityNameVisibility(input.typeName, enclosingDeclaration);
                        var node = ts.visitEachChild(input, visitDeclarationSubtree, context);
                        return cleanup(ts.updateTypeReferenceNode(node, node.typeName, ts.parenthesizeTypeParameters(node.typeArguments)));
                    }
                    case 166 /* ConstructSignature */:
                        return cleanup(ts.updateConstructSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type)));
                    case 162 /* Constructor */: {
                        // A constructor declaration may not have a type annotation
                        var ctor = ts.createSignatureDeclaration(162 /* Constructor */, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters, 0 /* None */), 
                        /*type*/ undefined);
                        ctor.modifiers = ts.createNodeArray(ensureModifiers(input));
                        return cleanup(ctor);
                    }
                    case 161 /* MethodDeclaration */: {
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        var sig = ts.createSignatureDeclaration(160 /* MethodSignature */, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type));
                        sig.name = input.name;
                        sig.modifiers = ts.createNodeArray(ensureModifiers(input));
                        sig.questionToken = input.questionToken;
                        return cleanup(sig);
                    }
                    case 163 /* GetAccessor */: {
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        var accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
                        return cleanup(ts.updateGetAccessor(input, 
                        /*decorators*/ undefined, ensureModifiers(input), input.name, updateAccessorParamsList(input, ts.hasModifier(input, 8 /* Private */)), ensureType(input, accessorType), 
                        /*body*/ undefined));
                    }
                    case 164 /* SetAccessor */: {
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        return cleanup(ts.updateSetAccessor(input, 
                        /*decorators*/ undefined, ensureModifiers(input), input.name, updateAccessorParamsList(input, ts.hasModifier(input, 8 /* Private */)), 
                        /*body*/ undefined));
                    }
                    case 159 /* PropertyDeclaration */:
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        return cleanup(ts.updateProperty(input, 
                        /*decorators*/ undefined, ensureModifiers(input), input.name, input.questionToken, ensureType(input, input.type), ensureNoInitializer(input)));
                    case 158 /* PropertySignature */:
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        return cleanup(ts.updatePropertySignature(input, ensureModifiers(input), input.name, input.questionToken, ensureType(input, input.type), ensureNoInitializer(input)));
                    case 160 /* MethodSignature */: {
                        if (ts.isPrivateIdentifier(input.name)) {
                            return cleanup(/*returnValue*/ undefined);
                        }
                        return cleanup(ts.updateMethodSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type), input.name, input.questionToken));
                    }
                    case 165 /* CallSignature */: {
                        return cleanup(ts.updateCallSignature(input, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type)));
                    }
                    case 167 /* IndexSignature */: {
                        return cleanup(ts.updateIndexSignature(input, 
                        /*decorators*/ undefined, ensureModifiers(input), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree) || ts.createKeywordTypeNode(125 /* AnyKeyword */)));
                    }
                    case 242 /* VariableDeclaration */: {
                        if (ts.isBindingPattern(input.name)) {
                            return recreateBindingPattern(input.name);
                        }
                        shouldEnterSuppressNewDiagnosticsContextContext = true;
                        suppressNewDiagnosticContexts = true; // Variable declaration types also suppress new diagnostic contexts, provided the contexts wouldn't be made for binding pattern types
                        return cleanup(ts.updateTypeScriptVariableDeclaration(input, input.name, /*exclaimationToken*/ undefined, ensureType(input, input.type), ensureNoInitializer(input)));
                    }
                    case 155 /* TypeParameter */: {
                        if (isPrivateMethodTypeParameter(input) && (input.default || input.constraint)) {
                            return cleanup(ts.updateTypeParameterDeclaration(input, input.name, /*constraint*/ undefined, /*defaultType*/ undefined));
                        }
                        return cleanup(ts.visitEachChild(input, visitDeclarationSubtree, context));
                    }
                    case 180 /* ConditionalType */: {
                        // We have to process conditional types in a special way because for visibility purposes we need to push a new enclosingDeclaration
                        // just for the `infer` types in the true branch. It's an implicit declaration scope that only applies to _part_ of the type.
                        var checkType = ts.visitNode(input.checkType, visitDeclarationSubtree);
                        var extendsType = ts.visitNode(input.extendsType, visitDeclarationSubtree);
                        var oldEnclosingDecl = enclosingDeclaration;
                        enclosingDeclaration = input.trueType;
                        var trueType = ts.visitNode(input.trueType, visitDeclarationSubtree);
                        enclosingDeclaration = oldEnclosingDecl;
                        var falseType = ts.visitNode(input.falseType, visitDeclarationSubtree);
                        return cleanup(ts.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType));
                    }
                    case 170 /* FunctionType */: {
                        return cleanup(ts.updateFunctionTypeNode(input, ts.visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree)));
                    }
                    case 171 /* ConstructorType */: {
                        return cleanup(ts.updateConstructorTypeNode(input, ts.visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), ts.visitNode(input.type, visitDeclarationSubtree)));
                    }
                    case 188 /* ImportType */: {
                        if (!ts.isLiteralImportTypeNode(input))
                            return cleanup(input);
                        return cleanup(ts.updateImportTypeNode(input, ts.updateLiteralTypeNode(input.argument, rewriteModuleSpecifier(input, input.argument.literal)), input.qualifier, ts.visitNodes(input.typeArguments, visitDeclarationSubtree, ts.isTypeNode), input.isTypeOf));
                    }
                    default: ts.Debug.assertNever(input, "Attempted to process unhandled node kind: " + ts.SyntaxKind[input.kind]);
                }
            }
            return cleanup(ts.visitEachChild(input, visitDeclarationSubtree, context));
            function cleanup(returnValue) {
                if (returnValue && canProduceDiagnostic && ts.hasDynamicName(input)) {
                    checkName(input);
                }
                if (isEnclosingDeclaration(input)) {
                    enclosingDeclaration = previousEnclosingDeclaration;
                }
                if (canProduceDiagnostic && !suppressNewDiagnosticContexts) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                if (shouldEnterSuppressNewDiagnosticsContextContext) {
                    suppressNewDiagnosticContexts = oldWithinObjectLiteralType;
                }
                if (returnValue === input) {
                    return returnValue;
                }
                return returnValue && ts.setOriginalNode(preserveJsDoc(returnValue, input), input);
            }
        }
        function isPrivateMethodTypeParameter(node) {
            return node.parent.kind === 161 /* MethodDeclaration */ && ts.hasModifier(node.parent, 8 /* Private */);
        }
        function visitDeclarationStatements(input) {
            if (!isPreservedDeclarationStatement(input)) {
                // return undefined for unmatched kinds to omit them from the tree
                return;
            }
            if (shouldStripInternal(input))
                return;
            switch (input.kind) {
                case 260 /* ExportDeclaration */: {
                    if (ts.isSourceFile(input.parent)) {
                        resultHasExternalModuleIndicator = true;
                    }
                    resultHasScopeMarker = true;
                    // Always visible if the parent node isn't dropped for being not visible
                    // Rewrite external module names if necessary
                    return ts.updateExportDeclaration(input, 
                    /*decorators*/ undefined, input.modifiers, input.exportClause, rewriteModuleSpecifier(input, input.moduleSpecifier), input.isTypeOnly);
                }
                case 259 /* ExportAssignment */: {
                    // Always visible if the parent node isn't dropped for being not visible
                    if (ts.isSourceFile(input.parent)) {
                        resultHasExternalModuleIndicator = true;
                    }
                    resultHasScopeMarker = true;
                    if (input.expression.kind === 75 /* Identifier */) {
                        return input;
                    }
                    else {
                        var newId = ts.createOptimisticUniqueName("_default");
                        getSymbolAccessibilityDiagnostic = function () { return ({
                            diagnosticMessage: ts.Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
                            errorNode: input
                        }); };
                        var varDecl = ts.createVariableDeclaration(newId, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
                        var statement = ts.createVariableStatement(needsDeclare ? [ts.createModifier(130 /* DeclareKeyword */)] : [], ts.createVariableDeclarationList([varDecl], 2 /* Const */));
                        return [statement, ts.updateExportAssignment(input, input.decorators, input.modifiers, newId)];
                    }
                }
            }
            var result = transformTopLevelDeclaration(input);
            // Don't actually transform yet; just leave as original node - will be elided/swapped by late pass
            lateStatementReplacementMap.set("" + ts.getOriginalNodeId(input), result);
            return input;
        }
        function stripExportModifiers(statement) {
            if (ts.isImportEqualsDeclaration(statement) || ts.hasModifier(statement, 512 /* Default */)) {
                // `export import` statements should remain as-is, as imports are _not_ implicitly exported in an ambient namespace
                // Likewise, `export default` classes and the like and just be `default`, so we preserve their `export` modifiers, too
                return statement;
            }
            var clone = ts.getMutableClone(statement);
            var modifiers = ts.createModifiersFromModifierFlags(ts.getModifierFlags(statement) & (3071 /* All */ ^ 1 /* Export */));
            clone.modifiers = modifiers.length ? ts.createNodeArray(modifiers) : undefined;
            return clone;
        }
        function transformTopLevelDeclaration(input) {
            if (shouldStripInternal(input))
                return;
            switch (input.kind) {
                case 253 /* ImportEqualsDeclaration */: {
                    return transformImportEqualsDeclaration(input);
                }
                case 254 /* ImportDeclaration */: {
                    return transformImportDeclaration(input);
                }
            }
            if (ts.isDeclaration(input) && isDeclarationAndNotVisible(input))
                return;
            // Elide implementation signatures from overload sets
            if (ts.isFunctionLike(input) && resolver.isImplementationOfOverload(input))
                return;
            var previousEnclosingDeclaration;
            if (isEnclosingDeclaration(input)) {
                previousEnclosingDeclaration = enclosingDeclaration;
                enclosingDeclaration = input;
            }
            var canProdiceDiagnostic = ts.canProduceDiagnostics(input);
            var oldDiag = getSymbolAccessibilityDiagnostic;
            if (canProdiceDiagnostic) {
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(input);
            }
            var previousNeedsDeclare = needsDeclare;
            switch (input.kind) {
                case 247 /* TypeAliasDeclaration */: // Type aliases get `declare`d if need be (for legacy support), but that's all
                    return cleanup(ts.updateTypeAliasDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input), input.name, ts.visitNodes(input.typeParameters, visitDeclarationSubtree, ts.isTypeParameterDeclaration), ts.visitNode(input.type, visitDeclarationSubtree, ts.isTypeNode)));
                case 246 /* InterfaceDeclaration */: {
                    return cleanup(ts.updateInterfaceDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input), input.name, ensureTypeParams(input, input.typeParameters), transformHeritageClauses(input.heritageClauses), ts.visitNodes(input.members, visitDeclarationSubtree)));
                }
                case 244 /* FunctionDeclaration */: {
                    // Generators lose their generator-ness, excepting their return type
                    var clean = cleanup(ts.updateFunctionDeclaration(input, 
                    /*decorators*/ undefined, ensureModifiers(input), 
                    /*asteriskToken*/ undefined, input.name, ensureTypeParams(input, input.typeParameters), updateParamsList(input, input.parameters), ensureType(input, input.type), 
                    /*body*/ undefined));
                    if (clean && resolver.isExpandoFunctionDeclaration(input)) {
                        var props = resolver.getPropertiesOfContainerFunction(input);
                        var fakespace_1 = ts.createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, clean.name || ts.createIdentifier("_default"), ts.createModuleBlock([]), 16 /* Namespace */);
                        fakespace_1.flags ^= 8 /* Synthesized */; // unset synthesized so it is usable as an enclosing declaration
                        fakespace_1.parent = enclosingDeclaration;
                        fakespace_1.locals = ts.createSymbolTable(props);
                        fakespace_1.symbol = props[0].parent;
                        var declarations = ts.mapDefined(props, function (p) {
                            if (!ts.isPropertyAccessExpression(p.valueDeclaration)) {
                                return undefined; // TODO GH#33569: Handle element access expressions that created late bound names (rather than silently omitting them)
                            }
                            getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
                            var type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace_1, declarationEmitNodeBuilderFlags, symbolTracker);
                            getSymbolAccessibilityDiagnostic = oldDiag;
                            var varDecl = ts.createVariableDeclaration(ts.unescapeLeadingUnderscores(p.escapedName), type, /*initializer*/ undefined);
                            return ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([varDecl]));
                        });
                        var namespaceDecl = ts.createModuleDeclaration(/*decorators*/ undefined, ensureModifiers(input), input.name, ts.createModuleBlock(declarations), 16 /* Namespace */);
                        if (!ts.hasModifier(clean, 512 /* Default */)) {
                            return [clean, namespaceDecl];
                        }
                        var modifiers = ts.createModifiersFromModifierFlags((ts.getModifierFlags(clean) & ~513 /* ExportDefault */) | 2 /* Ambient */);
                        var cleanDeclaration = ts.updateFunctionDeclaration(clean, 
                        /*decorators*/ undefined, modifiers, 
                        /*asteriskToken*/ undefined, clean.name, clean.typeParameters, clean.parameters, clean.type, 
                        /*body*/ undefined);
                        var namespaceDeclaration = ts.updateModuleDeclaration(namespaceDecl, 
                        /*decorators*/ undefined, modifiers, namespaceDecl.name, namespaceDecl.body);
                        var exportDefaultDeclaration = ts.createExportAssignment(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, 
                        /*isExportEquals*/ false, namespaceDecl.name);
                        if (ts.isSourceFile(input.parent)) {
                            resultHasExternalModuleIndicator = true;
                        }
                        resultHasScopeMarker = true;
                        return [cleanDeclaration, namespaceDeclaration, exportDefaultDeclaration];
                    }
                    else {
                        return clean;
                    }
                }
                case 249 /* ModuleDeclaration */: {
                    needsDeclare = false;
                    var inner = input.body;
                    if (inner && inner.kind === 250 /* ModuleBlock */) {
                        var oldNeedsScopeFix = needsScopeFixMarker;
                        var oldHasScopeFix = resultHasScopeMarker;
                        resultHasScopeMarker = false;
                        needsScopeFixMarker = false;
                        var statements = ts.visitNodes(inner.statements, visitDeclarationStatements);
                        var lateStatements = transformAndReplaceLatePaintedStatements(statements);
                        if (input.flags & 8388608 /* Ambient */) {
                            needsScopeFixMarker = false; // If it was `declare`'d everything is implicitly exported already, ignore late printed "privates"
                        }
                        // With the final list of statements, there are 3 possibilities:
                        // 1. There's an export assignment or export declaration in the namespace - do nothing
                        // 2. Everything is exported and there are no export assignments or export declarations - strip all export modifiers
                        // 3. Some things are exported, some are not, and there's no marker - add an empty marker
                        if (!ts.isGlobalScopeAugmentation(input) && !hasScopeMarker(lateStatements) && !resultHasScopeMarker) {
                            if (needsScopeFixMarker) {
                                lateStatements = ts.createNodeArray(__spreadArrays(lateStatements, [ts.createEmptyExports()]));
                            }
                            else {
                                lateStatements = ts.visitNodes(lateStatements, stripExportModifiers);
                            }
                        }
                        var body = ts.updateModuleBlock(inner, lateStatements);
                        needsDeclare = previousNeedsDeclare;
                        needsScopeFixMarker = oldNeedsScopeFix;
                        resultHasScopeMarker = oldHasScopeFix;
                        var mods = ensureModifiers(input);
                        return cleanup(ts.updateModuleDeclaration(input, 
                        /*decorators*/ undefined, mods, ts.isExternalModuleAugmentation(input) ? rewriteModuleSpecifier(input, input.name) : input.name, body));
                    }
                    else {
                        needsDeclare = previousNeedsDeclare;
                        var mods = ensureModifiers(input);
                        needsDeclare = false;
                        ts.visitNode(inner, visitDeclarationStatements);
                        // eagerly transform nested namespaces (the nesting doesn't need any elision or painting done)
                        var id = "" + ts.getOriginalNodeId(inner); // TODO: GH#18217
                        var body = lateStatementReplacementMap.get(id);
                        lateStatementReplacementMap.delete(id);
                        return cleanup(ts.updateModuleDeclaration(input, 
                        /*decorators*/ undefined, mods, input.name, body));
                    }
                }
                case 245 /* ClassDeclaration */: {
                    var modifiers = ts.createNodeArray(ensureModifiers(input));
                    var typeParameters = ensureTypeParams(input, input.typeParameters);
                    var ctor = ts.getFirstConstructorWithBody(input);
                    var parameterProperties = void 0;
                    if (ctor) {
                        var oldDiag_1 = getSymbolAccessibilityDiagnostic;
                        parameterProperties = ts.compact(ts.flatMap(ctor.parameters, function (param) {
                            if (!ts.hasModifier(param, 92 /* ParameterPropertyModifier */) || shouldStripInternal(param))
                                return;
                            getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(param);
                            if (param.name.kind === 75 /* Identifier */) {
                                return preserveJsDoc(ts.createProperty(
                                /*decorators*/ undefined, ensureModifiers(param), param.name, param.questionToken, ensureType(param, param.type), ensureNoInitializer(param)), param);
                            }
                            else {
                                // Pattern - this is currently an error, but we emit declarations for it somewhat correctly
                                return walkBindingPattern(param.name);
                            }
                            function walkBindingPattern(pattern) {
                                var elems;
                                for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) {
                                    var elem = _a[_i];
                                    if (ts.isOmittedExpression(elem))
                                        continue;
                                    if (ts.isBindingPattern(elem.name)) {
                                        elems = ts.concatenate(elems, walkBindingPattern(elem.name));
                                    }
                                    elems = elems || [];
                                    elems.push(ts.createProperty(
                                    /*decorators*/ undefined, ensureModifiers(param), elem.name, 
                                    /*questionToken*/ undefined, ensureType(elem, /*type*/ undefined), 
                                    /*initializer*/ undefined));
                                }
                                return elems;
                            }
                        }));
                        getSymbolAccessibilityDiagnostic = oldDiag_1;
                    }
                    var hasPrivateIdentifier = ts.some(input.members, function (member) { return !!member.name && ts.isPrivateIdentifier(member.name); });
                    var privateIdentifier = hasPrivateIdentifier ? [
                        ts.createProperty(
                        /*decorators*/ undefined, 
                        /*modifiers*/ undefined, ts.createPrivateIdentifier("#private"), 
                        /*questionToken*/ undefined, 
                        /*type*/ undefined, 
                        /*initializer*/ undefined)
                    ] : undefined;
                    var memberNodes = ts.concatenate(ts.concatenate(privateIdentifier, parameterProperties), ts.visitNodes(input.members, visitDeclarationSubtree));
                    var members = ts.createNodeArray(memberNodes);
                    var extendsClause_1 = ts.getEffectiveBaseTypeNode(input);
                    if (extendsClause_1 && !ts.isEntityNameExpression(extendsClause_1.expression) && extendsClause_1.expression.kind !== 100 /* NullKeyword */) {
                        // We must add a temporary declaration for the extends clause expression
                        var oldId = input.name ? ts.unescapeLeadingUnderscores(input.name.escapedText) : "default";
                        var newId_1 = ts.createOptimisticUniqueName(oldId + "_base");
                        getSymbolAccessibilityDiagnostic = function () { return ({
                            diagnosticMessage: ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
                            errorNode: extendsClause_1,
                            typeName: input.name
                        }); };
                        var varDecl = ts.createVariableDeclaration(newId_1, resolver.createTypeOfExpression(extendsClause_1.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
                        var statement = ts.createVariableStatement(needsDeclare ? [ts.createModifier(130 /* DeclareKeyword */)] : [], ts.createVariableDeclarationList([varDecl], 2 /* Const */));
                        var heritageClauses = ts.createNodeArray(ts.map(input.heritageClauses, function (clause) {
                            if (clause.token === 90 /* ExtendsKeyword */) {
                                var oldDiag_2 = getSymbolAccessibilityDiagnostic;
                                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]);
                                var newClause = ts.updateHeritageClause(clause, ts.map(clause.types, function (t) { return ts.updateExpressionWithTypeArguments(t, ts.visitNodes(t.typeArguments, visitDeclarationSubtree), newId_1); }));
                                getSymbolAccessibilityDiagnostic = oldDiag_2;
                                return newClause;
                            }
                            return ts.updateHeritageClause(clause, ts.visitNodes(ts.createNodeArray(ts.filter(clause.types, function (t) { return ts.isEntityNameExpression(t.expression) || t.expression.kind === 100 /* NullKeyword */; })), visitDeclarationSubtree));
                        }));
                        return [statement, cleanup(ts.updateClassDeclaration(input, 
                            /*decorators*/ undefined, modifiers, input.name, typeParameters, heritageClauses, members))]; // TODO: GH#18217
                    }
                    else {
                        var heritageClauses = transformHeritageClauses(input.heritageClauses);
                        return cleanup(ts.updateClassDeclaration(input, 
                        /*decorators*/ undefined, modifiers, input.name, typeParameters, heritageClauses, members));
                    }
                }
                case 225 /* VariableStatement */: {
                    return cleanup(transformVariableStatement(input));
                }
                case 248 /* EnumDeclaration */: {
                    return cleanup(ts.updateEnumDeclaration(input, /*decorators*/ undefined, ts.createNodeArray(ensureModifiers(input)), input.name, ts.createNodeArray(ts.mapDefined(input.members, function (m) {
                        if (shouldStripInternal(m))
                            return;
                        // Rewrite enum values to their constants, if available
                        var constValue = resolver.getConstantValue(m);
                        return preserveJsDoc(ts.updateEnumMember(m, m.name, constValue !== undefined ? ts.createLiteral(constValue) : undefined), m);
                    }))));
                }
            }
            // Anything left unhandled is an error, so this should be unreachable
            return ts.Debug.assertNever(input, "Unhandled top-level node in declaration emit: " + ts.SyntaxKind[input.kind]);
            function cleanup(node) {
                if (isEnclosingDeclaration(input)) {
                    enclosingDeclaration = previousEnclosingDeclaration;
                }
                if (canProdiceDiagnostic) {
                    getSymbolAccessibilityDiagnostic = oldDiag;
                }
                if (input.kind === 249 /* ModuleDeclaration */) {
                    needsDeclare = previousNeedsDeclare;
                }
                if (node === input) {
                    return node;
                }
                return node && ts.setOriginalNode(preserveJsDoc(node, input), input);
            }
        }
        function transformVariableStatement(input) {
            if (!ts.forEach(input.declarationList.declarations, getBindingNameVisible))
                return;
            var nodes = ts.visitNodes(input.declarationList.declarations, visitDeclarationSubtree);
            if (!ts.length(nodes))
                return;
            return ts.updateVariableStatement(input, ts.createNodeArray(ensureModifiers(input)), ts.updateVariableDeclarationList(input.declarationList, nodes));
        }
        function recreateBindingPattern(d) {
            return ts.flatten(ts.mapDefined(d.elements, function (e) { return recreateBindingElement(e); }));
        }
        function recreateBindingElement(e) {
            if (e.kind === 215 /* OmittedExpression */) {
                return;
            }
            if (e.name) {
                if (!getBindingNameVisible(e))
                    return;
                if (ts.isBindingPattern(e.name)) {
                    return recreateBindingPattern(e.name);
                }
                else {
                    return ts.createVariableDeclaration(e.name, ensureType(e, /*type*/ undefined), /*initializer*/ undefined);
                }
            }
        }
        function checkName(node) {
            var oldDiag;
            if (!suppressNewDiagnosticContexts) {
                oldDiag = getSymbolAccessibilityDiagnostic;
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNodeName(node);
            }
            errorNameNode = node.name;
            ts.Debug.assert(resolver.isLateBound(ts.getParseTreeNode(node))); // Should only be called with dynamic names
            var decl = node;
            var entityName = decl.name.expression;
            checkEntityNameVisibility(entityName, enclosingDeclaration);
            if (!suppressNewDiagnosticContexts) {
                getSymbolAccessibilityDiagnostic = oldDiag;
            }
            errorNameNode = undefined;
        }
        function shouldStripInternal(node) {
            return !!stripInternal && !!node && isInternalDeclaration(node, currentSourceFile);
        }
        function isScopeMarker(node) {
            return ts.isExportAssignment(node) || ts.isExportDeclaration(node);
        }
        function hasScopeMarker(statements) {
            return ts.some(statements, isScopeMarker);
        }
        function ensureModifiers(node) {
            var currentFlags = ts.getModifierFlags(node);
            var newFlags = ensureModifierFlags(node);
            if (currentFlags === newFlags) {
                return node.modifiers;
            }
            return ts.createModifiersFromModifierFlags(newFlags);
        }
        function ensureModifierFlags(node) {
            var mask = 3071 /* All */ ^ (4 /* Public */ | 256 /* Async */); // No async modifiers in declaration files
            var additions = (needsDeclare && !isAlwaysType(node)) ? 2 /* Ambient */ : 0 /* None */;
            var parentIsFile = node.parent.kind === 290 /* SourceFile */;
            if (!parentIsFile || (isBundledEmit && parentIsFile && ts.isExternalModule(node.parent))) {
                mask ^= 2 /* Ambient */;
                additions = 0 /* None */;
            }
            return maskModifierFlags(node, mask, additions);
        }
        function getTypeAnnotationFromAllAccessorDeclarations(node, accessors) {
            var accessorType = getTypeAnnotationFromAccessor(node);
            if (!accessorType && node !== accessors.firstAccessor) {
                accessorType = getTypeAnnotationFromAccessor(accessors.firstAccessor);
                // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(accessors.firstAccessor);
            }
            if (!accessorType && accessors.secondAccessor && node !== accessors.secondAccessor) {
                accessorType = getTypeAnnotationFromAccessor(accessors.secondAccessor);
                // If we end up pulling the type from the second accessor, we also need to change the diagnostic context to get the expected error message
                getSymbolAccessibilityDiagnostic = ts.createGetSymbolAccessibilityDiagnosticForNode(accessors.secondAccessor);
            }
            return accessorType;
        }
        function transformHeritageClauses(nodes) {
            return ts.createNodeArray(ts.filter(ts.map(nodes, function (clause) { return ts.updateHeritageClause(clause, ts.visitNodes(ts.createNodeArray(ts.filter(clause.types, function (t) {
                return ts.isEntityNameExpression(t.expression) || (clause.token === 90 /* ExtendsKeyword */ && t.expression.kind === 100 /* NullKeyword */);
            })), visitDeclarationSubtree)); }), function (clause) { return clause.types && !!clause.types.length; }));
        }
    }
    ts.transformDeclarations = transformDeclarations;
    function isAlwaysType(node) {
        if (node.kind === 246 /* InterfaceDeclaration */) {
            return true;
        }
        return false;
    }
    // Elide "public" modifier, as it is the default
    function maskModifiers(node, modifierMask, modifierAdditions) {
        return ts.createModifiersFromModifierFlags(maskModifierFlags(node, modifierMask, modifierAdditions));
    }
    function maskModifierFlags(node, modifierMask, modifierAdditions) {
        if (modifierMask === void 0) { modifierMask = 3071 /* All */ ^ 4 /* Public */; }
        if (modifierAdditions === void 0) { modifierAdditions = 0 /* None */; }
        var flags = (ts.getModifierFlags(node) & modifierMask) | modifierAdditions;
        if (flags & 512 /* Default */ && !(flags & 1 /* Export */)) {
            // A non-exported default is a nonsequitor - we usually try to remove all export modifiers
            // from statements in ambient declarations; but a default export must retain its export modifier to be syntactically valid
            flags ^= 1 /* Export */;
        }
        if (flags & 512 /* Default */ && flags & 2 /* Ambient */) {
            flags ^= 2 /* Ambient */; // `declare` is never required alongside `default` (and would be an error if printed)
        }
        return flags;
    }
    function getTypeAnnotationFromAccessor(accessor) {
        if (accessor) {
            return accessor.kind === 163 /* GetAccessor */
                ? accessor.type // Getter - return type
                : accessor.parameters.length > 0
                    ? accessor.parameters[0].type // Setter parameter type
                    : undefined;
        }
    }
    function canHaveLiteralInitializer(node) {
        switch (node.kind) {
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
                return !ts.hasModifier(node, 8 /* Private */);
            case 156 /* Parameter */:
            case 242 /* VariableDeclaration */:
                return true;
        }
        return false;
    }
    function isPreservedDeclarationStatement(node) {
        switch (node.kind) {
            case 244 /* FunctionDeclaration */:
            case 249 /* ModuleDeclaration */:
            case 253 /* ImportEqualsDeclaration */:
            case 246 /* InterfaceDeclaration */:
            case 245 /* ClassDeclaration */:
            case 247 /* TypeAliasDeclaration */:
            case 248 /* EnumDeclaration */:
            case 225 /* VariableStatement */:
            case 254 /* ImportDeclaration */:
            case 260 /* ExportDeclaration */:
            case 259 /* ExportAssignment */:
                return true;
        }
        return false;
    }
    function isProcessedComponent(node) {
        switch (node.kind) {
            case 166 /* ConstructSignature */:
            case 162 /* Constructor */:
            case 161 /* MethodDeclaration */:
            case 163 /* GetAccessor */:
            case 164 /* SetAccessor */:
            case 159 /* PropertyDeclaration */:
            case 158 /* PropertySignature */:
            case 160 /* MethodSignature */:
            case 165 /* CallSignature */:
            case 167 /* IndexSignature */:
            case 242 /* VariableDeclaration */:
            case 155 /* TypeParameter */:
            case 216 /* ExpressionWithTypeArguments */:
            case 169 /* TypeReference */:
            case 180 /* ConditionalType */:
            case 170 /* FunctionType */:
            case 171 /* ConstructorType */:
            case 188 /* ImportType */:
                return true;
        }
        return false;
    }
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function getModuleTransformer(moduleKind) {
        switch (moduleKind) {
            case ts.ModuleKind.ESNext:
            case ts.ModuleKind.ES2020:
            case ts.ModuleKind.ES2015:
                return ts.transformECMAScriptModule;
            case ts.ModuleKind.System:
                return ts.transformSystemModule;
            default:
                return ts.transformModule;
        }
    }
    var TransformationState;
    (function (TransformationState) {
        TransformationState[TransformationState["Uninitialized"] = 0] = "Uninitialized";
        TransformationState[TransformationState["Initialized"] = 1] = "Initialized";
        TransformationState[TransformationState["Completed"] = 2] = "Completed";
        TransformationState[TransformationState["Disposed"] = 3] = "Disposed";
    })(TransformationState || (TransformationState = {}));
    var SyntaxKindFeatureFlags;
    (function (SyntaxKindFeatureFlags) {
        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["Substitution"] = 1] = "Substitution";
        SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["EmitNotifications"] = 2] = "EmitNotifications";
    })(SyntaxKindFeatureFlags || (SyntaxKindFeatureFlags = {}));
    ts.noTransformers = { scriptTransformers: ts.emptyArray, declarationTransformers: ts.emptyArray };
    function getTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles) {
        return {
            scriptTransformers: getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles),
            declarationTransformers: getDeclarationTransformers(customTransformers),
        };
    }
    ts.getTransformers = getTransformers;
    function getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles) {
        if (emitOnlyDtsFiles)
            return ts.emptyArray;
        var jsx = compilerOptions.jsx;
        var languageVersion = ts.getEmitScriptTarget(compilerOptions);
        var moduleKind = ts.getEmitModuleKind(compilerOptions);
        var transformers = [];
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.before, wrapScriptTransformerFactory));
        transformers.push(ts.transformTypeScript);
        transformers.push(ts.transformClassFields);
        if (jsx === 2 /* React */) {
            transformers.push(ts.transformJsx);
        }
        if (languageVersion < 99 /* ESNext */) {
            transformers.push(ts.transformESNext);
        }
        if (languageVersion < 7 /* ES2020 */) {
            transformers.push(ts.transformES2020);
        }
        if (languageVersion < 6 /* ES2019 */) {
            transformers.push(ts.transformES2019);
        }
        if (languageVersion < 5 /* ES2018 */) {
            transformers.push(ts.transformES2018);
        }
        if (languageVersion < 4 /* ES2017 */) {
            transformers.push(ts.transformES2017);
        }
        if (languageVersion < 3 /* ES2016 */) {
            transformers.push(ts.transformES2016);
        }
        if (languageVersion < 2 /* ES2015 */) {
            transformers.push(ts.transformES2015);
            transformers.push(ts.transformGenerators);
        }
        transformers.push(getModuleTransformer(moduleKind));
        // The ES5 transformer is last so that it can substitute expressions like `exports.default`
        // for ES3.
        if (languageVersion < 1 /* ES5 */) {
            transformers.push(ts.transformES5);
        }
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.after, wrapScriptTransformerFactory));
        return transformers;
    }
    function getDeclarationTransformers(customTransformers) {
        var transformers = [];
        transformers.push(ts.transformDeclarations);
        ts.addRange(transformers, customTransformers && ts.map(customTransformers.afterDeclarations, wrapDeclarationTransformerFactory));
        return transformers;
    }
    /**
     * Wrap a custom script or declaration transformer object in a `Transformer` callback with fallback support for transforming bundles.
     */
    function wrapCustomTransformer(transformer) {
        return function (node) { return ts.isBundle(node) ? transformer.transformBundle(node) : transformer.transformSourceFile(node); };
    }
    /**
     * Wrap a transformer factory that may return a custom script or declaration transformer object.
     */
    function wrapCustomTransformerFactory(transformer, handleDefault) {
        return function (context) {
            var customTransformer = transformer(context);
            return typeof customTransformer === "function"
                ? handleDefault(customTransformer)
                : wrapCustomTransformer(customTransformer);
        };
    }
    function wrapScriptTransformerFactory(transformer) {
        return wrapCustomTransformerFactory(transformer, ts.chainBundle);
    }
    function wrapDeclarationTransformerFactory(transformer) {
        return wrapCustomTransformerFactory(transformer, ts.identity);
    }
    function noEmitSubstitution(_hint, node) {
        return node;
    }
    ts.noEmitSubstitution = noEmitSubstitution;
    function noEmitNotification(hint, node, callback) {
        callback(hint, node);
    }
    ts.noEmitNotification = noEmitNotification;
    /**
     * Transforms an array of SourceFiles by passing them through each transformer.
     *
     * @param resolver The emit resolver provided by the checker.
     * @param host The emit host object used to interact with the file system.
     * @param options Compiler options to surface in the `TransformationContext`.
     * @param nodes An array of nodes to transform.
     * @param transforms An array of `TransformerFactory` callbacks.
     * @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
     */
    function transformNodes(resolver, host, options, nodes, transformers, allowDtsFiles) {
        var enabledSyntaxKindFeatures = new Array(331 /* Count */);
        var lexicalEnvironmentVariableDeclarations;
        var lexicalEnvironmentFunctionDeclarations;
        var lexicalEnvironmentStatements;
        var lexicalEnvironmentFlags = 0 /* None */;
        var lexicalEnvironmentVariableDeclarationsStack = [];
        var lexicalEnvironmentFunctionDeclarationsStack = [];
        var lexicalEnvironmentStatementsStack = [];
        var lexicalEnvironmentFlagsStack = [];
        var lexicalEnvironmentStackOffset = 0;
        var lexicalEnvironmentSuspended = false;
        var emitHelpers;
        var onSubstituteNode = noEmitSubstitution;
        var onEmitNode = noEmitNotification;
        var state = 0 /* Uninitialized */;
        var diagnostics = [];
        // The transformation context is provided to each transformer as part of transformer
        // initialization.
        var context = {
            getCompilerOptions: function () { return options; },
            getEmitResolver: function () { return resolver; },
            getEmitHost: function () { return host; },
            startLexicalEnvironment: startLexicalEnvironment,
            suspendLexicalEnvironment: suspendLexicalEnvironment,
            resumeLexicalEnvironment: resumeLexicalEnvironment,
            endLexicalEnvironment: endLexicalEnvironment,
            setLexicalEnvironmentFlags: setLexicalEnvironmentFlags,
            getLexicalEnvironmentFlags: getLexicalEnvironmentFlags,
            hoistVariableDeclaration: hoistVariableDeclaration,
            hoistFunctionDeclaration: hoistFunctionDeclaration,
            addInitializationStatement: addInitializationStatement,
            requestEmitHelper: requestEmitHelper,
            readEmitHelpers: readEmitHelpers,
            enableSubstitution: enableSubstitution,
            enableEmitNotification: enableEmitNotification,
            isSubstitutionEnabled: isSubstitutionEnabled,
            isEmitNotificationEnabled: isEmitNotificationEnabled,
            get onSubstituteNode() { return onSubstituteNode; },
            set onSubstituteNode(value) {
                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
                onSubstituteNode = value;
            },
            get onEmitNode() { return onEmitNode; },
            set onEmitNode(value) {
                ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed.");
                ts.Debug.assert(value !== undefined, "Value must not be 'undefined'");
                onEmitNode = value;
            },
            addDiagnostic: function (diag) {
                diagnostics.push(diag);
            }
        };
        // Ensure the parse tree is clean before applying transformations
        for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) {
            var node = nodes_4[_i];
            ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
        }
        ts.performance.mark("beforeTransform");
        // Chain together and initialize each transformer.
        var transformersWithContext = transformers.map(function (t) { return t(context); });
        var transformation = function (node) {
            for (var _i = 0, transformersWithContext_1 = transformersWithContext; _i < transformersWithContext_1.length; _i++) {
                var transform = transformersWithContext_1[_i];
                node = transform(node);
            }
            return node;
        };
        // prevent modification of transformation hooks.
        state = 1 /* Initialized */;
        // Transform each node.
        var transformed = ts.map(nodes, allowDtsFiles ? transformation : transformRoot);
        // prevent modification of the lexical environment.
        state = 2 /* Completed */;
        ts.performance.mark("afterTransform");
        ts.performance.measure("transformTime", "beforeTransform", "afterTransform");
        return {
            transformed: transformed,
            substituteNode: substituteNode,
            emitNodeWithNotification: emitNodeWithNotification,
            isEmitNotificationEnabled: isEmitNotificationEnabled,
            dispose: dispose,
            diagnostics: diagnostics
        };
        function transformRoot(node) {
            return node && (!ts.isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node;
        }
        /**
         * Enables expression substitutions in the pretty printer for the provided SyntaxKind.
         */
        function enableSubstitution(kind) {
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            enabledSyntaxKindFeatures[kind] |= 1 /* Substitution */;
        }
        /**
         * Determines whether expression substitutions are enabled for the provided node.
         */
        function isSubstitutionEnabled(node) {
            return (enabledSyntaxKindFeatures[node.kind] & 1 /* Substitution */) !== 0
                && (ts.getEmitFlags(node) & 4 /* NoSubstitution */) === 0;
        }
        /**
         * Emits a node with possible substitution.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node or its substitute.
         */
        function substituteNode(hint, node) {
            ts.Debug.assert(state < 3 /* Disposed */, "Cannot substitute a node after the result is disposed.");
            return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
        }
        /**
         * Enables before/after emit notifications in the pretty printer for the provided SyntaxKind.
         */
        function enableEmitNotification(kind) {
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            enabledSyntaxKindFeatures[kind] |= 2 /* EmitNotifications */;
        }
        /**
         * Determines whether before/after emit notifications should be raised in the pretty
         * printer when it emits a node.
         */
        function isEmitNotificationEnabled(node) {
            return (enabledSyntaxKindFeatures[node.kind] & 2 /* EmitNotifications */) !== 0
                || (ts.getEmitFlags(node) & 2 /* AdviseOnEmitNode */) !== 0;
        }
        /**
         * Emits a node with possible emit notification.
         *
         * @param hint A hint as to the intended usage of the node.
         * @param node The node to emit.
         * @param emitCallback The callback used to emit the node.
         */
        function emitNodeWithNotification(hint, node, emitCallback) {
            ts.Debug.assert(state < 3 /* Disposed */, "Cannot invoke TransformationResult callbacks after the result is disposed.");
            if (node) {
                // TODO: Remove check and unconditionally use onEmitNode when API is breakingly changed
                // (see https://github.com/microsoft/TypeScript/pull/36248/files/5062623f39120171b98870c71344b3242eb03d23#r369766739)
                if (isEmitNotificationEnabled(node)) {
                    onEmitNode(hint, node, emitCallback);
                }
                else {
                    emitCallback(hint, node);
                }
            }
        }
        /**
         * Records a hoisted variable declaration for the provided name within a lexical environment.
         */
        function hoistVariableDeclaration(name) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            var decl = ts.setEmitFlags(ts.createVariableDeclaration(name), 64 /* NoNestedSourceMaps */);
            if (!lexicalEnvironmentVariableDeclarations) {
                lexicalEnvironmentVariableDeclarations = [decl];
            }
            else {
                lexicalEnvironmentVariableDeclarations.push(decl);
            }
            if (lexicalEnvironmentFlags & 1 /* InParameters */) {
                lexicalEnvironmentFlags |= 2 /* VariablesHoistedInParameters */;
            }
        }
        /**
         * Records a hoisted function declaration within a lexical environment.
         */
        function hoistFunctionDeclaration(func) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.setEmitFlags(func, 1048576 /* CustomPrologue */);
            if (!lexicalEnvironmentFunctionDeclarations) {
                lexicalEnvironmentFunctionDeclarations = [func];
            }
            else {
                lexicalEnvironmentFunctionDeclarations.push(func);
            }
        }
        /**
         * Adds an initialization statement to the top of the lexical environment.
         */
        function addInitializationStatement(node) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.setEmitFlags(node, 1048576 /* CustomPrologue */);
            if (!lexicalEnvironmentStatements) {
                lexicalEnvironmentStatements = [node];
            }
            else {
                lexicalEnvironmentStatements.push(node);
            }
        }
        /**
         * Starts a new lexical environment. Any existing hoisted variable or function declarations
         * are pushed onto a stack, and the related storage variables are reset.
         */
        function startLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
            // Save the current lexical environment. Rather than resizing the array we adjust the
            // stack size variable. This allows us to reuse existing array slots we've
            // already allocated between transformations to avoid allocation and GC overhead during
            // transformation.
            lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations;
            lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations;
            lexicalEnvironmentStatementsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentStatements;
            lexicalEnvironmentFlagsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFlags;
            lexicalEnvironmentStackOffset++;
            lexicalEnvironmentVariableDeclarations = undefined;
            lexicalEnvironmentFunctionDeclarations = undefined;
            lexicalEnvironmentStatements = undefined;
            lexicalEnvironmentFlags = 0 /* None */;
        }
        /** Suspends the current lexical environment, usually after visiting a parameter list. */
        function suspendLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
            lexicalEnvironmentSuspended = true;
        }
        /** Resumes a suspended lexical environment, usually before visiting a function body. */
        function resumeLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
            lexicalEnvironmentSuspended = false;
        }
        /**
         * Ends a lexical environment. The previous set of hoisted declarations are restored and
         * any hoisted declarations added in this environment are returned.
         */
        function endLexicalEnvironment() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed.");
            ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
            var statements;
            if (lexicalEnvironmentVariableDeclarations ||
                lexicalEnvironmentFunctionDeclarations ||
                lexicalEnvironmentStatements) {
                if (lexicalEnvironmentFunctionDeclarations) {
                    statements = __spreadArrays(lexicalEnvironmentFunctionDeclarations);
                }
                if (lexicalEnvironmentVariableDeclarations) {
                    var statement = ts.createVariableStatement(
                    /*modifiers*/ undefined, ts.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations));
                    ts.setEmitFlags(statement, 1048576 /* CustomPrologue */);
                    if (!statements) {
                        statements = [statement];
                    }
                    else {
                        statements.push(statement);
                    }
                }
                if (lexicalEnvironmentStatements) {
                    if (!statements) {
                        statements = __spreadArrays(lexicalEnvironmentStatements);
                    }
                    else {
                        statements = __spreadArrays(statements, lexicalEnvironmentStatements);
                    }
                }
            }
            // Restore the previous lexical environment.
            lexicalEnvironmentStackOffset--;
            lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset];
            lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset];
            lexicalEnvironmentStatements = lexicalEnvironmentStatementsStack[lexicalEnvironmentStackOffset];
            lexicalEnvironmentFlags = lexicalEnvironmentFlagsStack[lexicalEnvironmentStackOffset];
            if (lexicalEnvironmentStackOffset === 0) {
                lexicalEnvironmentVariableDeclarationsStack = [];
                lexicalEnvironmentFunctionDeclarationsStack = [];
                lexicalEnvironmentStatementsStack = [];
                lexicalEnvironmentFlagsStack = [];
            }
            return statements;
        }
        function setLexicalEnvironmentFlags(flags, value) {
            lexicalEnvironmentFlags = value ?
                lexicalEnvironmentFlags | flags :
                lexicalEnvironmentFlags & ~flags;
        }
        function getLexicalEnvironmentFlags() {
            return lexicalEnvironmentFlags;
        }
        function requestEmitHelper(helper) {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            ts.Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
            if (helper.dependencies) {
                for (var _i = 0, _a = helper.dependencies; _i < _a.length; _i++) {
                    var h = _a[_i];
                    requestEmitHelper(h);
                }
            }
            emitHelpers = ts.append(emitHelpers, helper);
        }
        function readEmitHelpers() {
            ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization.");
            ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed.");
            var helpers = emitHelpers;
            emitHelpers = undefined;
            return helpers;
        }
        function dispose() {
            if (state < 3 /* Disposed */) {
                // Clean up emit nodes on parse tree
                for (var _i = 0, nodes_5 = nodes; _i < nodes_5.length; _i++) {
                    var node = nodes_5[_i];
                    ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node)));
                }
                // Release references to external entries for GC purposes.
                lexicalEnvironmentVariableDeclarations = undefined;
                lexicalEnvironmentVariableDeclarationsStack = undefined;
                lexicalEnvironmentFunctionDeclarations = undefined;
                lexicalEnvironmentFunctionDeclarationsStack = undefined;
                onSubstituteNode = undefined;
                onEmitNode = undefined;
                emitHelpers = undefined;
                // Prevent further use of the transformation result.
                state = 3 /* Disposed */;
            }
        }
    }
    ts.transformNodes = transformNodes;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var brackets = createBracketsMap();
    var syntheticParent = { pos: -1, end: -1 };
    /*@internal*/
    function isBuildInfoFile(file) {
        return ts.fileExtensionIs(file, ".tsbuildinfo" /* TsBuildInfo */);
    }
    ts.isBuildInfoFile = isBuildInfoFile;
    /*@internal*/
    /**
     * Iterates over the source files that are expected to have an emit output.
     *
     * @param host An EmitHost.
     * @param action The action to execute.
     * @param sourceFilesOrTargetSourceFile
     *   If an array, the full list of source files to emit.
     *   Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
     */
    function forEachEmittedFile(host, action, sourceFilesOrTargetSourceFile, forceDtsEmit, onlyBuildInfo, includeBuildInfo) {
        if (forceDtsEmit === void 0) { forceDtsEmit = false; }
        var sourceFiles = ts.isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : ts.getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile, forceDtsEmit);
        var options = host.getCompilerOptions();
        if (options.outFile || options.out) {
            var prepends = host.getPrependNodes();
            if (sourceFiles.length || prepends.length) {
                var bundle = ts.createBundle(sourceFiles, prepends);
                var result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle);
                if (result) {
                    return result;
                }
            }
        }
        else {
            if (!onlyBuildInfo) {
                for (var _a = 0, sourceFiles_1 = sourceFiles; _a < sourceFiles_1.length; _a++) {
                    var sourceFile = sourceFiles_1[_a];
                    var result = action(getOutputPathsFor(sourceFile, host, forceDtsEmit), sourceFile);
                    if (result) {
                        return result;
                    }
                }
            }
            if (includeBuildInfo) {
                var buildInfoPath = getTsBuildInfoEmitOutputFilePath(host.getCompilerOptions());
                if (buildInfoPath)
                    return action({ buildInfoPath: buildInfoPath }, /*sourceFileOrBundle*/ undefined);
            }
        }
    }
    ts.forEachEmittedFile = forEachEmittedFile;
    function getTsBuildInfoEmitOutputFilePath(options) {
        var configFile = options.configFilePath;
        if (!ts.isIncrementalCompilation(options))
            return undefined;
        if (options.tsBuildInfoFile)
            return options.tsBuildInfoFile;
        var outPath = options.outFile || options.out;
        var buildInfoExtensionLess;
        if (outPath) {
            buildInfoExtensionLess = ts.removeFileExtension(outPath);
        }
        else {
            if (!configFile)
                return undefined;
            var configFileExtensionLess = ts.removeFileExtension(configFile);
            buildInfoExtensionLess = options.outDir ?
                options.rootDir ?
                    ts.resolvePath(options.outDir, ts.getRelativePathFromDirectory(options.rootDir, configFileExtensionLess, /*ignoreCase*/ true)) :
                    ts.combinePaths(options.outDir, ts.getBaseFileName(configFileExtensionLess)) :
                configFileExtensionLess;
        }
        return buildInfoExtensionLess + ".tsbuildinfo" /* TsBuildInfo */;
    }
    ts.getTsBuildInfoEmitOutputFilePath = getTsBuildInfoEmitOutputFilePath;
    /*@internal*/
    function getOutputPathsForBundle(options, forceDtsPaths) {
        var outPath = options.outFile || options.out;
        var jsFilePath = options.emitDeclarationOnly ? undefined : outPath;
        var sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options);
        var declarationFilePath = (forceDtsPaths || ts.getEmitDeclarations(options)) ? ts.removeFileExtension(outPath) + ".d.ts" /* Dts */ : undefined;
        var declarationMapPath = declarationFilePath && ts.getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
        var buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
        return { jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath, declarationMapPath: declarationMapPath, buildInfoPath: buildInfoPath };
    }
    ts.getOutputPathsForBundle = getOutputPathsForBundle;
    /*@internal*/
    function getOutputPathsFor(sourceFile, host, forceDtsPaths) {
        var options = host.getCompilerOptions();
        if (sourceFile.kind === 291 /* Bundle */) {
            return getOutputPathsForBundle(options, forceDtsPaths);
        }
        else {
            var ownOutputFilePath = ts.getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile, options));
            var isJsonFile = ts.isJsonSourceFile(sourceFile);
            // If json file emits to the same location skip writing it, if emitDeclarationOnly skip writing it
            var isJsonEmittedToSameLocation = isJsonFile &&
                ts.comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
            var jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? undefined : ownOutputFilePath;
            var sourceMapFilePath = !jsFilePath || ts.isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
            var declarationFilePath = (forceDtsPaths || (ts.getEmitDeclarations(options) && !isJsonFile)) ? ts.getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined;
            var declarationMapPath = declarationFilePath && ts.getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
            return { jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath, declarationMapPath: declarationMapPath, buildInfoPath: undefined };
        }
    }
    ts.getOutputPathsFor = getOutputPathsFor;
    function getSourceMapFilePath(jsFilePath, options) {
        return (options.sourceMap && !options.inlineSourceMap) ? jsFilePath + ".map" : undefined;
    }
    // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
    // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
    // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
    /* @internal */
    function getOutputExtension(sourceFile, options) {
        if (ts.isJsonSourceFile(sourceFile)) {
            return ".json" /* Json */;
        }
        if (options.jsx === 1 /* Preserve */) {
            if (ts.isSourceFileJS(sourceFile)) {
                if (ts.fileExtensionIs(sourceFile.fileName, ".jsx" /* Jsx */)) {
                    return ".jsx" /* Jsx */;
                }
            }
            else if (sourceFile.languageVariant === 1 /* JSX */) {
                // TypeScript source file preserving JSX syntax
                return ".jsx" /* Jsx */;
            }
        }
        return ".js" /* Js */;
    }
    ts.getOutputExtension = getOutputExtension;
    function rootDirOfOptions(configFile) {
        return configFile.options.rootDir || ts.getDirectoryPath(ts.Debug.checkDefined(configFile.options.configFilePath));
    }
    function getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, outputDir) {
        return outputDir ?
            ts.resolvePath(outputDir, ts.getRelativePathFromDirectory(rootDirOfOptions(configFile), inputFileName, ignoreCase)) :
            inputFileName;
    }
    /* @internal */
    function getOutputDeclarationFileName(inputFileName, configFile, ignoreCase) {
        ts.Debug.assert(!ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */) && !ts.fileExtensionIs(inputFileName, ".json" /* Json */));
        return ts.changeExtension(getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.declarationDir || configFile.options.outDir), ".d.ts" /* Dts */);
    }
    ts.getOutputDeclarationFileName = getOutputDeclarationFileName;
    function getOutputJSFileName(inputFileName, configFile, ignoreCase) {
        if (configFile.options.emitDeclarationOnly)
            return undefined;
        var isJsonFile = ts.fileExtensionIs(inputFileName, ".json" /* Json */);
        var outputFileName = ts.changeExtension(getOutputPathWithoutChangingExt(inputFileName, configFile, ignoreCase, configFile.options.outDir), isJsonFile ?
            ".json" /* Json */ :
            ts.fileExtensionIs(inputFileName, ".tsx" /* Tsx */) && configFile.options.jsx === 1 /* Preserve */ ?
                ".jsx" /* Jsx */ :
                ".js" /* Js */);
        return !isJsonFile || ts.comparePaths(inputFileName, outputFileName, ts.Debug.checkDefined(configFile.options.configFilePath), ignoreCase) !== 0 /* EqualTo */ ?
            outputFileName :
            undefined;
    }
    function createAddOutput() {
        var outputs;
        return { addOutput: addOutput, getOutputs: getOutputs };
        function addOutput(path) {
            if (path) {
                (outputs || (outputs = [])).push(path);
            }
        }
        function getOutputs() {
            return outputs || ts.emptyArray;
        }
    }
    function getSingleOutputFileNames(configFile, addOutput) {
        var _a = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false), jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
        addOutput(jsFilePath);
        addOutput(sourceMapFilePath);
        addOutput(declarationFilePath);
        addOutput(declarationMapPath);
        addOutput(buildInfoPath);
    }
    function getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput) {
        if (ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */))
            return;
        var js = getOutputJSFileName(inputFileName, configFile, ignoreCase);
        addOutput(js);
        if (ts.fileExtensionIs(inputFileName, ".json" /* Json */))
            return;
        if (js && configFile.options.sourceMap) {
            addOutput(js + ".map");
        }
        if (ts.getEmitDeclarations(configFile.options)) {
            var dts = getOutputDeclarationFileName(inputFileName, configFile, ignoreCase);
            addOutput(dts);
            if (configFile.options.declarationMap) {
                addOutput(dts + ".map");
            }
        }
    }
    /*@internal*/
    function getAllProjectOutputs(configFile, ignoreCase) {
        var _a = createAddOutput(), addOutput = _a.addOutput, getOutputs = _a.getOutputs;
        if (configFile.options.outFile || configFile.options.out) {
            getSingleOutputFileNames(configFile, addOutput);
        }
        else {
            for (var _b = 0, _c = configFile.fileNames; _b < _c.length; _b++) {
                var inputFileName = _c[_b];
                getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput);
            }
            addOutput(getTsBuildInfoEmitOutputFilePath(configFile.options));
        }
        return getOutputs();
    }
    ts.getAllProjectOutputs = getAllProjectOutputs;
    function getOutputFileNames(commandLine, inputFileName, ignoreCase) {
        inputFileName = ts.normalizePath(inputFileName);
        ts.Debug.assert(ts.contains(commandLine.fileNames, inputFileName), "Expected fileName to be present in command line");
        var _a = createAddOutput(), addOutput = _a.addOutput, getOutputs = _a.getOutputs;
        if (commandLine.options.outFile || commandLine.options.out) {
            getSingleOutputFileNames(commandLine, addOutput);
        }
        else {
            getOwnOutputFileNames(commandLine, inputFileName, ignoreCase, addOutput);
        }
        return getOutputs();
    }
    ts.getOutputFileNames = getOutputFileNames;
    /*@internal*/
    function getFirstProjectOutput(configFile, ignoreCase) {
        if (configFile.options.outFile || configFile.options.out) {
            var jsFilePath = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false).jsFilePath;
            return ts.Debug.checkDefined(jsFilePath, "project " + configFile.options.configFilePath + " expected to have at least one output");
        }
        for (var _a = 0, _b = configFile.fileNames; _a < _b.length; _a++) {
            var inputFileName = _b[_a];
            if (ts.fileExtensionIs(inputFileName, ".d.ts" /* Dts */))
                continue;
            var jsFilePath = getOutputJSFileName(inputFileName, configFile, ignoreCase);
            if (jsFilePath)
                return jsFilePath;
            if (ts.fileExtensionIs(inputFileName, ".json" /* Json */))
                continue;
            if (ts.getEmitDeclarations(configFile.options)) {
                return getOutputDeclarationFileName(inputFileName, configFile, ignoreCase);
            }
        }
        var buildInfoPath = getTsBuildInfoEmitOutputFilePath(configFile.options);
        if (buildInfoPath)
            return buildInfoPath;
        return ts.Debug.fail("project " + configFile.options.configFilePath + " expected to have at least one output");
    }
    ts.getFirstProjectOutput = getFirstProjectOutput;
    /*@internal*/
    // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
    function emitFiles(resolver, host, targetSourceFile, _a, emitOnlyDtsFiles, onlyBuildInfo, forceDtsEmit) {
        var scriptTransformers = _a.scriptTransformers, declarationTransformers = _a.declarationTransformers;
        var compilerOptions = host.getCompilerOptions();
        var sourceMapDataList = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || ts.getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
        var emittedFilesList = compilerOptions.listEmittedFiles ? [] : undefined;
        var emitterDiagnostics = ts.createDiagnosticCollection();
        var newLine = ts.getNewLineCharacter(compilerOptions, function () { return host.getNewLine(); });
        var writer = ts.createTextWriter(newLine);
        var _b = ts.performance.createTimer("printTime", "beforePrint", "afterPrint"), enter = _b.enter, exit = _b.exit;
        var bundleBuildInfo;
        var emitSkipped = false;
        var exportedModulesFromDeclarationEmit;
        // Emit each output file
        enter();
        forEachEmittedFile(host, emitSourceFileOrBundle, ts.getSourceFilesToEmit(host, targetSourceFile, forceDtsEmit), forceDtsEmit, onlyBuildInfo, !targetSourceFile);
        exit();
        return {
            emitSkipped: emitSkipped,
            diagnostics: emitterDiagnostics.getDiagnostics(),
            emittedFiles: emittedFilesList,
            sourceMaps: sourceMapDataList,
            exportedModulesFromDeclarationEmit: exportedModulesFromDeclarationEmit
        };
        function emitSourceFileOrBundle(_a, sourceFileOrBundle) {
            var jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
            var buildInfoDirectory;
            if (buildInfoPath && sourceFileOrBundle && ts.isBundle(sourceFileOrBundle)) {
                buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
                bundleBuildInfo = {
                    commonSourceDirectory: relativeToBuildInfo(host.getCommonSourceDirectory()),
                    sourceFiles: sourceFileOrBundle.sourceFiles.map(function (file) { return relativeToBuildInfo(ts.getNormalizedAbsolutePath(file.fileName, host.getCurrentDirectory())); })
                };
            }
            emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath, relativeToBuildInfo);
            emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath, relativeToBuildInfo);
            emitBuildInfo(bundleBuildInfo, buildInfoPath);
            if (!emitSkipped && emittedFilesList) {
                if (!emitOnlyDtsFiles) {
                    if (jsFilePath) {
                        emittedFilesList.push(jsFilePath);
                    }
                    if (sourceMapFilePath) {
                        emittedFilesList.push(sourceMapFilePath);
                    }
                    if (buildInfoPath) {
                        emittedFilesList.push(buildInfoPath);
                    }
                }
                if (declarationFilePath) {
                    emittedFilesList.push(declarationFilePath);
                }
                if (declarationMapPath) {
                    emittedFilesList.push(declarationMapPath);
                }
            }
            function relativeToBuildInfo(path) {
                return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(buildInfoDirectory, path, host.getCanonicalFileName));
            }
        }
        function emitBuildInfo(bundle, buildInfoPath) {
            // Write build information if applicable
            if (!buildInfoPath || targetSourceFile || emitSkipped)
                return;
            var program = host.getProgramBuildInfo();
            if (host.isEmitBlocked(buildInfoPath) || compilerOptions.noEmit) {
                emitSkipped = true;
                return;
            }
            var version = ts.version; // Extracted into a const so the form is stable between namespace and module
            ts.writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText({ bundle: bundle, program: program, version: version }), /*writeByteOrderMark*/ false);
        }
        function emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath, relativeToBuildInfo) {
            if (!sourceFileOrBundle || emitOnlyDtsFiles || !jsFilePath) {
                return;
            }
            // Make sure not to write js file and source map file if any of them cannot be written
            if ((jsFilePath && host.isEmitBlocked(jsFilePath)) || compilerOptions.noEmit) {
                emitSkipped = true;
                return;
            }
            // Transform the source files
            var transform = ts.transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
            var printerOptions = {
                removeComments: compilerOptions.removeComments,
                newLine: compilerOptions.newLine,
                noEmitHelpers: compilerOptions.noEmitHelpers,
                module: compilerOptions.module,
                target: compilerOptions.target,
                sourceMap: compilerOptions.sourceMap,
                inlineSourceMap: compilerOptions.inlineSourceMap,
                inlineSources: compilerOptions.inlineSources,
                extendedDiagnostics: compilerOptions.extendedDiagnostics,
                writeBundleFileInfo: !!bundleBuildInfo,
                relativeToBuildInfo: relativeToBuildInfo
            };
            // Create a printer to print the nodes
            var printer = createPrinter(printerOptions, {
                // resolver hooks
                hasGlobalName: resolver.hasGlobalName,
                // transform hooks
                onEmitNode: transform.emitNodeWithNotification,
                isEmitNotificationEnabled: transform.isEmitNotificationEnabled,
                substituteNode: transform.substituteNode,
            });
            ts.Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform");
            printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform.transformed[0], printer, compilerOptions);
            // Clean up emit nodes on parse tree
            transform.dispose();
            if (bundleBuildInfo)
                bundleBuildInfo.js = printer.bundleFileInfo;
        }
        function emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath, relativeToBuildInfo) {
            if (!sourceFileOrBundle)
                return;
            if (!declarationFilePath) {
                if (emitOnlyDtsFiles || compilerOptions.emitDeclarationOnly)
                    emitSkipped = true;
                return;
            }
            var sourceFiles = ts.isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
            var filesForEmit = forceDtsEmit ? sourceFiles : ts.filter(sourceFiles, ts.isSourceFileNotJson);
            // Setup and perform the transformation to retrieve declarations from the input files
            var inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [ts.createBundle(filesForEmit, !ts.isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : filesForEmit;
            if (emitOnlyDtsFiles && !ts.getEmitDeclarations(compilerOptions)) {
                // Checker wont collect the linked aliases since thats only done when declaration is enabled.
                // Do that here when emitting only dts files
                filesForEmit.forEach(collectLinkedAliases);
            }
            var declarationTransform = ts.transformNodes(resolver, host, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
            if (ts.length(declarationTransform.diagnostics)) {
                for (var _a = 0, _b = declarationTransform.diagnostics; _a < _b.length; _a++) {
                    var diagnostic = _b[_a];
                    emitterDiagnostics.add(diagnostic);
                }
            }
            var printerOptions = {
                removeComments: compilerOptions.removeComments,
                newLine: compilerOptions.newLine,
                noEmitHelpers: true,
                module: compilerOptions.module,
                target: compilerOptions.target,
                sourceMap: compilerOptions.sourceMap,
                inlineSourceMap: compilerOptions.inlineSourceMap,
                extendedDiagnostics: compilerOptions.extendedDiagnostics,
                onlyPrintJsDocStyle: true,
                writeBundleFileInfo: !!bundleBuildInfo,
                recordInternalSection: !!bundleBuildInfo,
                relativeToBuildInfo: relativeToBuildInfo
            };
            var declarationPrinter = createPrinter(printerOptions, {
                // resolver hooks
                hasGlobalName: resolver.hasGlobalName,
                // transform hooks
                onEmitNode: declarationTransform.emitNodeWithNotification,
                isEmitNotificationEnabled: declarationTransform.isEmitNotificationEnabled,
                substituteNode: declarationTransform.substituteNode,
            });
            var declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit;
            emitSkipped = emitSkipped || declBlocked;
            if (!declBlocked || forceDtsEmit) {
                ts.Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform");
                printSourceFileOrBundle(declarationFilePath, declarationMapPath, declarationTransform.transformed[0], declarationPrinter, {
                    sourceMap: compilerOptions.declarationMap,
                    sourceRoot: compilerOptions.sourceRoot,
                    mapRoot: compilerOptions.mapRoot,
                    extendedDiagnostics: compilerOptions.extendedDiagnostics,
                });
                if (forceDtsEmit && declarationTransform.transformed[0].kind === 290 /* SourceFile */) {
                    var sourceFile = declarationTransform.transformed[0];
                    exportedModulesFromDeclarationEmit = sourceFile.exportedModulesFromDeclarationEmit;
                }
            }
            declarationTransform.dispose();
            if (bundleBuildInfo)
                bundleBuildInfo.dts = declarationPrinter.bundleFileInfo;
        }
        function collectLinkedAliases(node) {
            if (ts.isExportAssignment(node)) {
                if (node.expression.kind === 75 /* Identifier */) {
                    resolver.collectLinkedAliases(node.expression, /*setVisibility*/ true);
                }
                return;
            }
            else if (ts.isExportSpecifier(node)) {
                resolver.collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true);
                return;
            }
            ts.forEachChild(node, collectLinkedAliases);
        }
        function printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle, printer, mapOptions) {
            var bundle = sourceFileOrBundle.kind === 291 /* Bundle */ ? sourceFileOrBundle : undefined;
            var sourceFile = sourceFileOrBundle.kind === 290 /* SourceFile */ ? sourceFileOrBundle : undefined;
            var sourceFiles = bundle ? bundle.sourceFiles : [sourceFile];
            var sourceMapGenerator;
            if (shouldEmitSourceMaps(mapOptions, sourceFileOrBundle)) {
                sourceMapGenerator = ts.createSourceMapGenerator(host, ts.getBaseFileName(ts.normalizeSlashes(jsFilePath)), getSourceRoot(mapOptions), getSourceMapDirectory(mapOptions, jsFilePath, sourceFile), mapOptions);
            }
            if (bundle) {
                printer.writeBundle(bundle, writer, sourceMapGenerator);
            }
            else {
                printer.writeFile(sourceFile, writer, sourceMapGenerator);
            }
            if (sourceMapGenerator) {
                if (sourceMapDataList) {
                    sourceMapDataList.push({
                        inputSourceFileNames: sourceMapGenerator.getSources(),
                        sourceMap: sourceMapGenerator.toJSON()
                    });
                }
                var sourceMappingURL = getSourceMappingURL(mapOptions, sourceMapGenerator, jsFilePath, sourceMapFilePath, sourceFile);
                if (sourceMappingURL) {
                    if (!writer.isAtStartOfLine())
                        writer.rawWrite(newLine);
                    writer.writeComment("//# " + "sourceMappingURL" + "=" + sourceMappingURL); // Tools can sometimes see this line as a source mapping url comment
                }
                // Write the source map
                if (sourceMapFilePath) {
                    var sourceMap = sourceMapGenerator.toString();
                    ts.writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap, /*writeByteOrderMark*/ false, sourceFiles);
                }
            }
            else {
                writer.writeLine();
            }
            // Write the output file
            ts.writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), !!compilerOptions.emitBOM, sourceFiles);
            // Reset state
            writer.clear();
        }
        function shouldEmitSourceMaps(mapOptions, sourceFileOrBundle) {
            return (mapOptions.sourceMap || mapOptions.inlineSourceMap)
                && (sourceFileOrBundle.kind !== 290 /* SourceFile */ || !ts.fileExtensionIs(sourceFileOrBundle.fileName, ".json" /* Json */));
        }
        function getSourceRoot(mapOptions) {
            // Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the
            // relative paths of the sources list in the sourcemap
            var sourceRoot = ts.normalizeSlashes(mapOptions.sourceRoot || "");
            return sourceRoot ? ts.ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot;
        }
        function getSourceMapDirectory(mapOptions, filePath, sourceFile) {
            if (mapOptions.sourceRoot)
                return host.getCommonSourceDirectory();
            if (mapOptions.mapRoot) {
                var sourceMapDir = ts.normalizeSlashes(mapOptions.mapRoot);
                if (sourceFile) {
                    // For modules or multiple emit files the mapRoot will have directory structure like the sources
                    // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
                    sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
                }
                if (ts.getRootLength(sourceMapDir) === 0) {
                    // The relative paths are relative to the common directory
                    sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
                }
                return sourceMapDir;
            }
            return ts.getDirectoryPath(ts.normalizePath(filePath));
        }
        function getSourceMappingURL(mapOptions, sourceMapGenerator, filePath, sourceMapFilePath, sourceFile) {
            if (mapOptions.inlineSourceMap) {
                // Encode the sourceMap into the sourceMap url
                var sourceMapText = sourceMapGenerator.toString();
                var base64SourceMapText = ts.base64encode(ts.sys, sourceMapText);
                return "data:application/json;base64," + base64SourceMapText;
            }
            var sourceMapFile = ts.getBaseFileName(ts.normalizeSlashes(ts.Debug.checkDefined(sourceMapFilePath)));
            if (mapOptions.mapRoot) {
                var sourceMapDir = ts.normalizeSlashes(mapOptions.mapRoot);
                if (sourceFile) {
                    // For modules or multiple emit files the mapRoot will have directory structure like the sources
                    // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
                    sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
                }
                if (ts.getRootLength(sourceMapDir) === 0) {
                    // The relative paths are relative to the common directory
                    sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
                    return ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
                    ts.combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
                    host.getCurrentDirectory(), host.getCanonicalFileName, 
                    /*isAbsolutePathAnUrl*/ true);
                }
                else {
                    return ts.combinePaths(sourceMapDir, sourceMapFile);
                }
            }
            return sourceMapFile;
        }
    }
    ts.emitFiles = emitFiles;
    /*@internal*/
    function getBuildInfoText(buildInfo) {
        return JSON.stringify(buildInfo, undefined, 2);
    }
    ts.getBuildInfoText = getBuildInfoText;
    /*@internal*/
    function getBuildInfo(buildInfoText) {
        return JSON.parse(buildInfoText);
    }
    ts.getBuildInfo = getBuildInfo;
    /*@internal*/
    ts.notImplementedResolver = {
        hasGlobalName: ts.notImplemented,
        getReferencedExportContainer: ts.notImplemented,
        getReferencedImportDeclaration: ts.notImplemented,
        getReferencedDeclarationWithCollidingName: ts.notImplemented,
        isDeclarationWithCollidingName: ts.notImplemented,
        isValueAliasDeclaration: ts.notImplemented,
        isReferencedAliasDeclaration: ts.notImplemented,
        isTopLevelValueImportEqualsWithEntityName: ts.notImplemented,
        getNodeCheckFlags: ts.notImplemented,
        isDeclarationVisible: ts.notImplemented,
        isLateBound: function (_node) { return false; },
        collectLinkedAliases: ts.notImplemented,
        isImplementationOfOverload: ts.notImplemented,
        isRequiredInitializedParameter: ts.notImplemented,
        isOptionalUninitializedParameterProperty: ts.notImplemented,
        isExpandoFunctionDeclaration: ts.notImplemented,
        getPropertiesOfContainerFunction: ts.notImplemented,
        createTypeOfDeclaration: ts.notImplemented,
        createReturnTypeOfSignatureDeclaration: ts.notImplemented,
        createTypeOfExpression: ts.notImplemented,
        createLiteralConstValue: ts.notImplemented,
        isSymbolAccessible: ts.notImplemented,
        isEntityNameVisible: ts.notImplemented,
        // Returns the constant value this property access resolves to: notImplemented, or 'undefined' for a non-constant
        getConstantValue: ts.notImplemented,
        getReferencedValueDeclaration: ts.notImplemented,
        getTypeReferenceSerializationKind: ts.notImplemented,
        isOptionalParameter: ts.notImplemented,
        moduleExportsSomeValue: ts.notImplemented,
        isArgumentsLocalBinding: ts.notImplemented,
        getExternalModuleFileFromDeclaration: ts.notImplemented,
        getTypeReferenceDirectivesForEntityName: ts.notImplemented,
        getTypeReferenceDirectivesForSymbol: ts.notImplemented,
        isLiteralConstDeclaration: ts.notImplemented,
        getJsxFactoryEntity: ts.notImplemented,
        getAllAccessorDeclarations: ts.notImplemented,
        getSymbolOfExternalModuleSpecifier: ts.notImplemented,
        isBindingCapturedByNode: ts.notImplemented,
        getDeclarationStatementsForSourceFile: ts.notImplemented,
        isImportRequiredByAugmentation: ts.notImplemented,
    };
    function createSourceFilesFromBundleBuildInfo(bundle, buildInfoDirectory, host) {
        var sourceFiles = bundle.sourceFiles.map(function (fileName) {
            var sourceFile = ts.createNode(290 /* SourceFile */, 0, 0);
            sourceFile.fileName = ts.getRelativePathFromDirectory(host.getCurrentDirectory(), ts.getNormalizedAbsolutePath(fileName, buildInfoDirectory), !host.useCaseSensitiveFileNames());
            sourceFile.text = "";
            sourceFile.statements = ts.createNodeArray();
            return sourceFile;
        });
        var jsBundle = ts.Debug.checkDefined(bundle.js);
        ts.forEach(jsBundle.sources && jsBundle.sources.prologues, function (prologueInfo) {
            var sourceFile = sourceFiles[prologueInfo.file];
            sourceFile.text = prologueInfo.text;
            sourceFile.end = prologueInfo.text.length;
            sourceFile.statements = ts.createNodeArray(prologueInfo.directives.map(function (directive) {
                var statement = ts.createNode(226 /* ExpressionStatement */, directive.pos, directive.end);
                statement.expression = ts.createNode(10 /* StringLiteral */, directive.expression.pos, directive.expression.end);
                statement.expression.text = directive.expression.text;
                return statement;
            }));
        });
        return sourceFiles;
    }
    /*@internal*/
    function emitUsingBuildInfo(config, host, getCommandLine, customTransformers) {
        var _a = getOutputPathsForBundle(config.options, /*forceDtsPaths*/ false), buildInfoPath = _a.buildInfoPath, jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath;
        var buildInfoText = host.readFile(ts.Debug.checkDefined(buildInfoPath));
        if (!buildInfoText)
            return buildInfoPath;
        var jsFileText = host.readFile(ts.Debug.checkDefined(jsFilePath));
        if (!jsFileText)
            return jsFilePath;
        var sourceMapText = sourceMapFilePath && host.readFile(sourceMapFilePath);
        // error if no source map or for now if inline sourcemap
        if ((sourceMapFilePath && !sourceMapText) || config.options.inlineSourceMap)
            return sourceMapFilePath || "inline sourcemap decoding";
        // read declaration text
        var declarationText = declarationFilePath && host.readFile(declarationFilePath);
        if (declarationFilePath && !declarationText)
            return declarationFilePath;
        var declarationMapText = declarationMapPath && host.readFile(declarationMapPath);
        // error if no source map or for now if inline sourcemap
        if ((declarationMapPath && !declarationMapText) || config.options.inlineSourceMap)
            return declarationMapPath || "inline sourcemap decoding";
        var buildInfo = getBuildInfo(buildInfoText);
        if (!buildInfo.bundle || !buildInfo.bundle.js || (declarationText && !buildInfo.bundle.dts))
            return buildInfoPath;
        var buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
        var ownPrependInput = ts.createInputFiles(jsFileText, declarationText, sourceMapFilePath, sourceMapText, declarationMapPath, declarationMapText, jsFilePath, declarationFilePath, buildInfoPath, buildInfo, 
        /*onlyOwnText*/ true);
        var outputFiles = [];
        var prependNodes = ts.createPrependNodes(config.projectReferences, getCommandLine, function (f) { return host.readFile(f); });
        var sourceFilesForJsEmit = createSourceFilesFromBundleBuildInfo(buildInfo.bundle, buildInfoDirectory, host);
        var emitHost = {
            getPrependNodes: ts.memoize(function () { return __spreadArrays(prependNodes, [ownPrependInput]); }),
            getCanonicalFileName: host.getCanonicalFileName,
            getCommonSourceDirectory: function () { return ts.getNormalizedAbsolutePath(buildInfo.bundle.commonSourceDirectory, buildInfoDirectory); },
            getCompilerOptions: function () { return config.options; },
            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
            getNewLine: function () { return host.getNewLine(); },
            getSourceFile: ts.returnUndefined,
            getSourceFileByPath: ts.returnUndefined,
            getSourceFiles: function () { return sourceFilesForJsEmit; },
            getLibFileFromReference: ts.notImplemented,
            isSourceFileFromExternalLibrary: ts.returnFalse,
            getResolvedProjectReferenceToRedirect: ts.returnUndefined,
            getProjectReferenceRedirect: ts.returnUndefined,
            isSourceOfProjectReferenceRedirect: ts.returnFalse,
            writeFile: function (name, text, writeByteOrderMark) {
                switch (name) {
                    case jsFilePath:
                        if (jsFileText === text)
                            return;
                        break;
                    case sourceMapFilePath:
                        if (sourceMapText === text)
                            return;
                        break;
                    case buildInfoPath:
                        var newBuildInfo = getBuildInfo(text);
                        newBuildInfo.program = buildInfo.program;
                        // Update sourceFileInfo
                        var _a = buildInfo.bundle, js = _a.js, dts = _a.dts, sourceFiles = _a.sourceFiles;
                        newBuildInfo.bundle.js.sources = js.sources;
                        if (dts) {
                            newBuildInfo.bundle.dts.sources = dts.sources;
                        }
                        newBuildInfo.bundle.sourceFiles = sourceFiles;
                        outputFiles.push({ name: name, text: getBuildInfoText(newBuildInfo), writeByteOrderMark: writeByteOrderMark });
                        return;
                    case declarationFilePath:
                        if (declarationText === text)
                            return;
                        break;
                    case declarationMapPath:
                        if (declarationMapText === text)
                            return;
                        break;
                    default:
                        ts.Debug.fail("Unexpected path: " + name);
                }
                outputFiles.push({ name: name, text: text, writeByteOrderMark: writeByteOrderMark });
            },
            isEmitBlocked: ts.returnFalse,
            readFile: function (f) { return host.readFile(f); },
            fileExists: function (f) { return host.fileExists(f); },
            useCaseSensitiveFileNames: function () { return host.useCaseSensitiveFileNames(); },
            getProgramBuildInfo: ts.returnUndefined,
            getSourceFileFromReference: ts.returnUndefined,
            redirectTargetsMap: ts.createMultiMap()
        };
        emitFiles(ts.notImplementedResolver, emitHost, 
        /*targetSourceFile*/ undefined, ts.getTransformers(config.options, customTransformers));
        return outputFiles;
    }
    ts.emitUsingBuildInfo = emitUsingBuildInfo;
    var PipelinePhase;
    (function (PipelinePhase) {
        PipelinePhase[PipelinePhase["Notification"] = 0] = "Notification";
        PipelinePhase[PipelinePhase["Substitution"] = 1] = "Substitution";
        PipelinePhase[PipelinePhase["Comments"] = 2] = "Comments";
        PipelinePhase[PipelinePhase["SourceMaps"] = 3] = "SourceMaps";
        PipelinePhase[PipelinePhase["Emit"] = 4] = "Emit";
    })(PipelinePhase || (PipelinePhase = {}));
    function createPrinter(printerOptions, handlers) {
        if (printerOptions === void 0) { printerOptions = {}; }
        if (handlers === void 0) { handlers = {}; }
        var hasGlobalName = handlers.hasGlobalName, _a = handlers.onEmitNode, onEmitNode = _a === void 0 ? ts.noEmitNotification : _a, isEmitNotificationEnabled = handlers.isEmitNotificationEnabled, _b = handlers.substituteNode, substituteNode = _b === void 0 ? ts.noEmitSubstitution : _b, onBeforeEmitNodeArray = handlers.onBeforeEmitNodeArray, onAfterEmitNodeArray = handlers.onAfterEmitNodeArray, onBeforeEmitToken = handlers.onBeforeEmitToken, onAfterEmitToken = handlers.onAfterEmitToken;
        var extendedDiagnostics = !!printerOptions.extendedDiagnostics;
        var newLine = ts.getNewLineCharacter(printerOptions);
        var moduleKind = ts.getEmitModuleKind(printerOptions);
        var bundledHelpers = ts.createMap();
        var currentSourceFile;
        var nodeIdToGeneratedName; // Map of generated names for specific nodes.
        var autoGeneratedIdToGeneratedName; // Map of generated names for temp and loop variables.
        var generatedNames; // Set of names generated by the NameGenerator.
        var tempFlagsStack; // Stack of enclosing name generation scopes.
        var tempFlags; // TempFlags for the current name generation scope.
        var reservedNamesStack; // Stack of TempFlags reserved in enclosing name generation scopes.
        var reservedNames; // TempFlags to reserve in nested name generation scopes.
        var preserveSourceNewlines = printerOptions.preserveSourceNewlines; // Can be overridden inside nodes with the `IgnoreSourceNewlines` emit flag.
        var writer;
        var ownWriter; // Reusable `EmitTextWriter` for basic printing.
        var write = writeBase;
        var isOwnFileEmit;
        var bundleFileInfo = printerOptions.writeBundleFileInfo ? { sections: [] } : undefined;
        var relativeToBuildInfo = bundleFileInfo ? ts.Debug.checkDefined(printerOptions.relativeToBuildInfo) : undefined;
        var recordInternalSection = printerOptions.recordInternalSection;
        var sourceFileTextPos = 0;
        var sourceFileTextKind = "text" /* Text */;
        // Source Maps
        var sourceMapsDisabled = true;
        var sourceMapGenerator;
        var sourceMapSource;
        var sourceMapSourceIndex = -1;
        // Comments
        var containerPos = -1;
        var containerEnd = -1;
        var declarationListContainerEnd = -1;
        var currentLineMap;
        var detachedCommentsInfo;
        var hasWrittenComment = false;
        var commentsDisabled = !!printerOptions.removeComments;
        var lastNode;
        var lastSubstitution;
        var _c = ts.performance.createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment"), enterComment = _c.enter, exitComment = _c.exit;
        reset();
        return {
            // public API
            printNode: printNode,
            printList: printList,
            printFile: printFile,
            printBundle: printBundle,
            // internal API
            writeNode: writeNode,
            writeList: writeList,
            writeFile: writeFile,
            writeBundle: writeBundle,
            bundleFileInfo: bundleFileInfo
        };
        function printNode(hint, node, sourceFile) {
            switch (hint) {
                case 0 /* SourceFile */:
                    ts.Debug.assert(ts.isSourceFile(node), "Expected a SourceFile node.");
                    break;
                case 2 /* IdentifierName */:
                    ts.Debug.assert(ts.isIdentifier(node), "Expected an Identifier node.");
                    break;
                case 1 /* Expression */:
                    ts.Debug.assert(ts.isExpression(node), "Expected an Expression node.");
                    break;
            }
            switch (node.kind) {
                case 290 /* SourceFile */: return printFile(node);
                case 291 /* Bundle */: return printBundle(node);
                case 292 /* UnparsedSource */: return printUnparsedSource(node);
            }
            writeNode(hint, node, sourceFile, beginPrint());
            return endPrint();
        }
        function printList(format, nodes, sourceFile) {
            writeList(format, nodes, sourceFile, beginPrint());
            return endPrint();
        }
        function printBundle(bundle) {
            writeBundle(bundle, beginPrint(), /*sourceMapEmitter*/ undefined);
            return endPrint();
        }
        function printFile(sourceFile) {
            writeFile(sourceFile, beginPrint(), /*sourceMapEmitter*/ undefined);
            return endPrint();
        }
        function printUnparsedSource(unparsed) {
            writeUnparsedSource(unparsed, beginPrint());
            return endPrint();
        }
        function writeNode(hint, node, sourceFile, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            print(hint, node, sourceFile);
            reset();
            writer = previousWriter;
        }
        function writeList(format, nodes, sourceFile, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            if (sourceFile) {
                setSourceFile(sourceFile);
            }
            emitList(syntheticParent, nodes, format);
            reset();
            writer = previousWriter;
        }
        function getTextPosWithWriteLine() {
            return writer.getTextPosWithWriteLine ? writer.getTextPosWithWriteLine() : writer.getTextPos();
        }
        function updateOrPushBundleFileTextLike(pos, end, kind) {
            var last = ts.lastOrUndefined(bundleFileInfo.sections);
            if (last && last.kind === kind) {
                last.end = end;
            }
            else {
                bundleFileInfo.sections.push({ pos: pos, end: end, kind: kind });
            }
        }
        function recordBundleFileInternalSectionStart(node) {
            if (recordInternalSection &&
                bundleFileInfo &&
                currentSourceFile &&
                (ts.isDeclaration(node) || ts.isVariableStatement(node)) &&
                ts.isInternalDeclaration(node, currentSourceFile) &&
                sourceFileTextKind !== "internal" /* Internal */) {
                var prevSourceFileTextKind = sourceFileTextKind;
                recordBundleFileTextLikeSection(writer.getTextPos());
                sourceFileTextPos = getTextPosWithWriteLine();
                sourceFileTextKind = "internal" /* Internal */;
                return prevSourceFileTextKind;
            }
            return undefined;
        }
        function recordBundleFileInternalSectionEnd(prevSourceFileTextKind) {
            if (prevSourceFileTextKind) {
                recordBundleFileTextLikeSection(writer.getTextPos());
                sourceFileTextPos = getTextPosWithWriteLine();
                sourceFileTextKind = prevSourceFileTextKind;
            }
        }
        function recordBundleFileTextLikeSection(end) {
            if (sourceFileTextPos < end) {
                updateOrPushBundleFileTextLike(sourceFileTextPos, end, sourceFileTextKind);
                return true;
            }
            return false;
        }
        function writeBundle(bundle, output, sourceMapGenerator) {
            var _a;
            isOwnFileEmit = false;
            var previousWriter = writer;
            setWriter(output, sourceMapGenerator);
            emitShebangIfNeeded(bundle);
            emitPrologueDirectivesIfNeeded(bundle);
            emitHelpers(bundle);
            emitSyntheticTripleSlashReferencesIfNeeded(bundle);
            for (var _b = 0, _c = bundle.prepends; _b < _c.length; _b++) {
                var prepend = _c[_b];
                writeLine();
                var pos = writer.getTextPos();
                var savedSections = bundleFileInfo && bundleFileInfo.sections;
                if (savedSections)
                    bundleFileInfo.sections = [];
                print(4 /* Unspecified */, prepend, /*sourceFile*/ undefined);
                if (bundleFileInfo) {
                    var newSections = bundleFileInfo.sections;
                    bundleFileInfo.sections = savedSections;
                    if (prepend.oldFileOfCurrentEmit)
                        (_a = bundleFileInfo.sections).push.apply(_a, newSections);
                    else {
                        newSections.forEach(function (section) { return ts.Debug.assert(ts.isBundleFileTextLike(section)); });
                        bundleFileInfo.sections.push({
                            pos: pos,
                            end: writer.getTextPos(),
                            kind: "prepend" /* Prepend */,
                            data: relativeToBuildInfo(prepend.fileName),
                            texts: newSections
                        });
                    }
                }
            }
            sourceFileTextPos = getTextPosWithWriteLine();
            for (var _d = 0, _e = bundle.sourceFiles; _d < _e.length; _d++) {
                var sourceFile = _e[_d];
                print(0 /* SourceFile */, sourceFile, sourceFile);
            }
            if (bundleFileInfo && bundle.sourceFiles.length) {
                var end = writer.getTextPos();
                if (recordBundleFileTextLikeSection(end)) {
                    // Store prologues
                    var prologues = getPrologueDirectivesFromBundledSourceFiles(bundle);
                    if (prologues) {
                        if (!bundleFileInfo.sources)
                            bundleFileInfo.sources = {};
                        bundleFileInfo.sources.prologues = prologues;
                    }
                    // Store helpes
                    var helpers = getHelpersFromBundledSourceFiles(bundle);
                    if (helpers) {
                        if (!bundleFileInfo.sources)
                            bundleFileInfo.sources = {};
                        bundleFileInfo.sources.helpers = helpers;
                    }
                }
            }
            reset();
            writer = previousWriter;
        }
        function writeUnparsedSource(unparsed, output) {
            var previousWriter = writer;
            setWriter(output, /*_sourceMapGenerator*/ undefined);
            print(4 /* Unspecified */, unparsed, /*sourceFile*/ undefined);
            reset();
            writer = previousWriter;
        }
        function writeFile(sourceFile, output, sourceMapGenerator) {
            isOwnFileEmit = true;
            var previousWriter = writer;
            setWriter(output, sourceMapGenerator);
            emitShebangIfNeeded(sourceFile);
            emitPrologueDirectivesIfNeeded(sourceFile);
            print(0 /* SourceFile */, sourceFile, sourceFile);
            reset();
            writer = previousWriter;
        }
        function beginPrint() {
            return ownWriter || (ownWriter = ts.createTextWriter(newLine));
        }
        function endPrint() {
            var text = ownWriter.getText();
            ownWriter.clear();
            return text;
        }
        function print(hint, node, sourceFile) {
            if (sourceFile) {
                setSourceFile(sourceFile);
            }
            pipelineEmit(hint, node);
        }
        function setSourceFile(sourceFile) {
            currentSourceFile = sourceFile;
            currentLineMap = undefined;
            detachedCommentsInfo = undefined;
            if (sourceFile) {
                setSourceMapSource(sourceFile);
            }
        }
        function setWriter(_writer, _sourceMapGenerator) {
            if (_writer && printerOptions.omitTrailingSemicolon) {
                _writer = ts.getTrailingSemicolonDeferringWriter(_writer);
            }
            writer = _writer; // TODO: GH#18217
            sourceMapGenerator = _sourceMapGenerator;
            sourceMapsDisabled = !writer || !sourceMapGenerator;
        }
        function reset() {
            nodeIdToGeneratedName = [];
            autoGeneratedIdToGeneratedName = [];
            generatedNames = ts.createMap();
            tempFlagsStack = [];
            tempFlags = 0 /* Auto */;
            reservedNamesStack = [];
            currentSourceFile = undefined;
            currentLineMap = undefined;
            detachedCommentsInfo = undefined;
            lastNode = undefined;
            lastSubstitution = undefined;
            setWriter(/*output*/ undefined, /*_sourceMapGenerator*/ undefined);
        }
        function getCurrentLineMap() {
            return currentLineMap || (currentLineMap = ts.getLineStarts(currentSourceFile));
        }
        function emit(node) {
            if (node === undefined)
                return;
            var prevSourceFileTextKind = recordBundleFileInternalSectionStart(node);
            var substitute = pipelineEmit(4 /* Unspecified */, node);
            recordBundleFileInternalSectionEnd(prevSourceFileTextKind);
            return substitute;
        }
        function emitIdentifierName(node) {
            if (node === undefined)
                return;
            return pipelineEmit(2 /* IdentifierName */, node);
        }
        function emitExpression(node) {
            if (node === undefined)
                return;
            return pipelineEmit(1 /* Expression */, node);
        }
        function emitJsxAttributeValue(node) {
            return pipelineEmit(ts.isStringLiteral(node) ? 6 /* JsxAttributeValue */ : 4 /* Unspecified */, node);
        }
        function pipelineEmit(emitHint, node) {
            var savedLastNode = lastNode;
            var savedLastSubstitution = lastSubstitution;
            var savedPreserveSourceNewlines = preserveSourceNewlines;
            lastNode = node;
            lastSubstitution = undefined;
            if (preserveSourceNewlines && !!(ts.getEmitFlags(node) & 134217728 /* IgnoreSourceNewlines */)) {
                preserveSourceNewlines = false;
            }
            var pipelinePhase = getPipelinePhase(0 /* Notification */, emitHint, node);
            pipelinePhase(emitHint, node);
            ts.Debug.assert(lastNode === node);
            var substitute = lastSubstitution;
            lastNode = savedLastNode;
            lastSubstitution = savedLastSubstitution;
            preserveSourceNewlines = savedPreserveSourceNewlines;
            return substitute || node;
        }
        function getPipelinePhase(phase, emitHint, node) {
            switch (phase) {
                case 0 /* Notification */:
                    if (onEmitNode !== ts.noEmitNotification && (!isEmitNotificationEnabled || isEmitNotificationEnabled(node))) {
                        return pipelineEmitWithNotification;
                    }
                // falls through
                case 1 /* Substitution */:
                    if (substituteNode !== ts.noEmitSubstitution && (lastSubstitution = substituteNode(emitHint, node)) !== node) {
                        return pipelineEmitWithSubstitution;
                    }
                // falls through
                case 2 /* Comments */:
                    if (!commentsDisabled && node.kind !== 290 /* SourceFile */) {
                        return pipelineEmitWithComments;
                    }
                // falls through
                case 3 /* SourceMaps */:
                    if (!sourceMapsDisabled && node.kind !== 290 /* SourceFile */ && !ts.isInJsonFile(node)) {
                        return pipelineEmitWithSourceMap;
                    }
                // falls through
                case 4 /* Emit */:
                    return pipelineEmitWithHint;
                default:
                    return ts.Debug.assertNever(phase);
            }
        }
        function getNextPipelinePhase(currentPhase, emitHint, node) {
            return getPipelinePhase(currentPhase + 1, emitHint, node);
        }
        function pipelineEmitWithNotification(hint, node) {
            ts.Debug.assert(lastNode === node);
            var pipelinePhase = getNextPipelinePhase(0 /* Notification */, hint, node);
            onEmitNode(hint, node, pipelinePhase);
            ts.Debug.assert(lastNode === node);
        }
        function pipelineEmitWithHint(hint, node) {
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
            if (hint === 0 /* SourceFile */)
                return emitSourceFile(ts.cast(node, ts.isSourceFile));
            if (hint === 2 /* IdentifierName */)
                return emitIdentifier(ts.cast(node, ts.isIdentifier));
            if (hint === 6 /* JsxAttributeValue */)
                return emitLiteral(ts.cast(node, ts.isStringLiteral), /*jsxAttributeEscape*/ true);
            if (hint === 3 /* MappedTypeParameter */)
                return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration));
            if (hint === 5 /* EmbeddedStatement */) {
                ts.Debug.assertNode(node, ts.isEmptyStatement);
                return emitEmptyStatement(/*isEmbeddedStatement*/ true);
            }
            if (hint === 4 /* Unspecified */) {
                if (ts.isKeyword(node.kind))
                    return writeTokenNode(node, writeKeyword);
                switch (node.kind) {
                    // Pseudo-literals
                    case 15 /* TemplateHead */:
                    case 16 /* TemplateMiddle */:
                    case 17 /* TemplateTail */:
                        return emitLiteral(node, /*jsxAttributeEscape*/ false);
                    case 292 /* UnparsedSource */:
                    case 286 /* UnparsedPrepend */:
                        return emitUnparsedSourceOrPrepend(node);
                    case 285 /* UnparsedPrologue */:
                        return writeUnparsedNode(node);
                    case 287 /* UnparsedText */:
                    case 288 /* UnparsedInternalText */:
                        return emitUnparsedTextLike(node);
                    case 289 /* UnparsedSyntheticReference */:
                        return emitUnparsedSyntheticReference(node);
                    // Identifiers
                    case 75 /* Identifier */:
                        return emitIdentifier(node);
                    // PrivateIdentifiers
                    case 76 /* PrivateIdentifier */:
                        return emitPrivateIdentifier(node);
                    // Parse tree nodes
                    // Names
                    case 153 /* QualifiedName */:
                        return emitQualifiedName(node);
                    case 154 /* ComputedPropertyName */:
                        return emitComputedPropertyName(node);
                    // Signature elements
                    case 155 /* TypeParameter */:
                        return emitTypeParameter(node);
                    case 156 /* Parameter */:
                        return emitParameter(node);
                    case 157 /* Decorator */:
                        return emitDecorator(node);
                    // Type members
                    case 158 /* PropertySignature */:
                        return emitPropertySignature(node);
                    case 159 /* PropertyDeclaration */:
                        return emitPropertyDeclaration(node);
                    case 160 /* MethodSignature */:
                        return emitMethodSignature(node);
                    case 161 /* MethodDeclaration */:
                        return emitMethodDeclaration(node);
                    case 162 /* Constructor */:
                        return emitConstructor(node);
                    case 163 /* GetAccessor */:
                    case 164 /* SetAccessor */:
                        return emitAccessorDeclaration(node);
                    case 165 /* CallSignature */:
                        return emitCallSignature(node);
                    case 166 /* ConstructSignature */:
                        return emitConstructSignature(node);
                    case 167 /* IndexSignature */:
                        return emitIndexSignature(node);
                    // Types
                    case 168 /* TypePredicate */:
                        return emitTypePredicate(node);
                    case 169 /* TypeReference */:
                        return emitTypeReference(node);
                    case 170 /* FunctionType */:
                        return emitFunctionType(node);
                    case 300 /* JSDocFunctionType */:
                        return emitJSDocFunctionType(node);
                    case 171 /* ConstructorType */:
                        return emitConstructorType(node);
                    case 172 /* TypeQuery */:
                        return emitTypeQuery(node);
                    case 173 /* TypeLiteral */:
                        return emitTypeLiteral(node);
                    case 174 /* ArrayType */:
                        return emitArrayType(node);
                    case 175 /* TupleType */:
                        return emitTupleType(node);
                    case 176 /* OptionalType */:
                        return emitOptionalType(node);
                    case 178 /* UnionType */:
                        return emitUnionType(node);
                    case 179 /* IntersectionType */:
                        return emitIntersectionType(node);
                    case 180 /* ConditionalType */:
                        return emitConditionalType(node);
                    case 181 /* InferType */:
                        return emitInferType(node);
                    case 182 /* ParenthesizedType */:
                        return emitParenthesizedType(node);
                    case 216 /* ExpressionWithTypeArguments */:
                        return emitExpressionWithTypeArguments(node);
                    case 183 /* ThisType */:
                        return emitThisType();
                    case 184 /* TypeOperator */:
                        return emitTypeOperator(node);
                    case 185 /* IndexedAccessType */:
                        return emitIndexedAccessType(node);
                    case 186 /* MappedType */:
                        return emitMappedType(node);
                    case 187 /* LiteralType */:
                        return emitLiteralType(node);
                    case 188 /* ImportType */:
                        return emitImportTypeNode(node);
                    case 295 /* JSDocAllType */:
                        writePunctuation("*");
                        return;
                    case 296 /* JSDocUnknownType */:
                        writePunctuation("?");
                        return;
                    case 297 /* JSDocNullableType */:
                        return emitJSDocNullableType(node);
                    case 298 /* JSDocNonNullableType */:
                        return emitJSDocNonNullableType(node);
                    case 299 /* JSDocOptionalType */:
                        return emitJSDocOptionalType(node);
                    case 177 /* RestType */:
                    case 301 /* JSDocVariadicType */:
                        return emitRestOrJSDocVariadicType(node);
                    // Binding patterns
                    case 189 /* ObjectBindingPattern */:
                        return emitObjectBindingPattern(node);
                    case 190 /* ArrayBindingPattern */:
                        return emitArrayBindingPattern(node);
                    case 191 /* BindingElement */:
                        return emitBindingElement(node);
                    // Misc
                    case 221 /* TemplateSpan */:
                        return emitTemplateSpan(node);
                    case 222 /* SemicolonClassElement */:
                        return emitSemicolonClassElement();
                    // Statements
                    case 223 /* Block */:
                        return emitBlock(node);
                    case 225 /* VariableStatement */:
                        return emitVariableStatement(node);
                    case 224 /* EmptyStatement */:
                        return emitEmptyStatement(/*isEmbeddedStatement*/ false);
                    case 226 /* ExpressionStatement */:
                        return emitExpressionStatement(node);
                    case 227 /* IfStatement */:
                        return emitIfStatement(node);
                    case 228 /* DoStatement */:
                        return emitDoStatement(node);
                    case 229 /* WhileStatement */:
                        return emitWhileStatement(node);
                    case 230 /* ForStatement */:
                        return emitForStatement(node);
                    case 231 /* ForInStatement */:
                        return emitForInStatement(node);
                    case 232 /* ForOfStatement */:
                        return emitForOfStatement(node);
                    case 233 /* ContinueStatement */:
                        return emitContinueStatement(node);
                    case 234 /* BreakStatement */:
                        return emitBreakStatement(node);
                    case 235 /* ReturnStatement */:
                        return emitReturnStatement(node);
                    case 236 /* WithStatement */:
                        return emitWithStatement(node);
                    case 237 /* SwitchStatement */:
                        return emitSwitchStatement(node);
                    case 238 /* LabeledStatement */:
                        return emitLabeledStatement(node);
                    case 239 /* ThrowStatement */:
                        return emitThrowStatement(node);
                    case 240 /* TryStatement */:
                        return emitTryStatement(node);
                    case 241 /* DebuggerStatement */:
                        return emitDebuggerStatement(node);
                    // Declarations
                    case 242 /* VariableDeclaration */:
                        return emitVariableDeclaration(node);
                    case 243 /* VariableDeclarationList */:
                        return emitVariableDeclarationList(node);
                    case 244 /* FunctionDeclaration */:
                        return emitFunctionDeclaration(node);
                    case 245 /* ClassDeclaration */:
                        return emitClassDeclaration(node);
                    case 246 /* InterfaceDeclaration */:
                        return emitInterfaceDeclaration(node);
                    case 247 /* TypeAliasDeclaration */:
                        return emitTypeAliasDeclaration(node);
                    case 248 /* EnumDeclaration */:
                        return emitEnumDeclaration(node);
                    case 249 /* ModuleDeclaration */:
                        return emitModuleDeclaration(node);
                    case 250 /* ModuleBlock */:
                        return emitModuleBlock(node);
                    case 251 /* CaseBlock */:
                        return emitCaseBlock(node);
                    case 252 /* NamespaceExportDeclaration */:
                        return emitNamespaceExportDeclaration(node);
                    case 253 /* ImportEqualsDeclaration */:
                        return emitImportEqualsDeclaration(node);
                    case 254 /* ImportDeclaration */:
                        return emitImportDeclaration(node);
                    case 255 /* ImportClause */:
                        return emitImportClause(node);
                    case 256 /* NamespaceImport */:
                        return emitNamespaceImport(node);
                    case 262 /* NamespaceExport */:
                        return emitNamespaceExport(node);
                    case 257 /* NamedImports */:
                        return emitNamedImports(node);
                    case 258 /* ImportSpecifier */:
                        return emitImportSpecifier(node);
                    case 259 /* ExportAssignment */:
                        return emitExportAssignment(node);
                    case 260 /* ExportDeclaration */:
                        return emitExportDeclaration(node);
                    case 261 /* NamedExports */:
                        return emitNamedExports(node);
                    case 263 /* ExportSpecifier */:
                        return emitExportSpecifier(node);
                    case 264 /* MissingDeclaration */:
                        return;
                    // Module references
                    case 265 /* ExternalModuleReference */:
                        return emitExternalModuleReference(node);
                    // JSX (non-expression)
                    case 11 /* JsxText */:
                        return emitJsxText(node);
                    case 268 /* JsxOpeningElement */:
                    case 271 /* JsxOpeningFragment */:
                        return emitJsxOpeningElementOrFragment(node);
                    case 269 /* JsxClosingElement */:
                    case 272 /* JsxClosingFragment */:
                        return emitJsxClosingElementOrFragment(node);
                    case 273 /* JsxAttribute */:
                        return emitJsxAttribute(node);
                    case 274 /* JsxAttributes */:
                        return emitJsxAttributes(node);
                    case 275 /* JsxSpreadAttribute */:
                        return emitJsxSpreadAttribute(node);
                    case 276 /* JsxExpression */:
                        return emitJsxExpression(node);
                    // Clauses
                    case 277 /* CaseClause */:
                        return emitCaseClause(node);
                    case 278 /* DefaultClause */:
                        return emitDefaultClause(node);
                    case 279 /* HeritageClause */:
                        return emitHeritageClause(node);
                    case 280 /* CatchClause */:
                        return emitCatchClause(node);
                    // Property assignments
                    case 281 /* PropertyAssignment */:
                        return emitPropertyAssignment(node);
                    case 282 /* ShorthandPropertyAssignment */:
                        return emitShorthandPropertyAssignment(node);
                    case 283 /* SpreadAssignment */:
                        return emitSpreadAssignment(node);
                    // Enum
                    case 284 /* EnumMember */:
                        return emitEnumMember(node);
                    // JSDoc nodes (only used in codefixes currently)
                    case 317 /* JSDocParameterTag */:
                    case 323 /* JSDocPropertyTag */:
                        return emitJSDocPropertyLikeTag(node);
                    case 318 /* JSDocReturnTag */:
                    case 320 /* JSDocTypeTag */:
                    case 319 /* JSDocThisTag */:
                    case 316 /* JSDocEnumTag */:
                        return emitJSDocSimpleTypedTag(node);
                    case 308 /* JSDocImplementsTag */:
                    case 307 /* JSDocAugmentsTag */:
                        return emitJSDocHeritageTag(node);
                    case 321 /* JSDocTemplateTag */:
                        return emitJSDocTemplateTag(node);
                    case 322 /* JSDocTypedefTag */:
                        return emitJSDocTypedefTag(node);
                    case 315 /* JSDocCallbackTag */:
                        return emitJSDocCallbackTag(node);
                    case 305 /* JSDocSignature */:
                        return emitJSDocSignature(node);
                    case 304 /* JSDocTypeLiteral */:
                        return emitJSDocTypeLiteral(node);
                    case 310 /* JSDocClassTag */:
                    case 306 /* JSDocTag */:
                        return emitJSDocSimpleTag(node);
                    case 303 /* JSDocComment */:
                        return emitJSDoc(node);
                    // Transformation nodes (ignored)
                }
                if (ts.isExpression(node)) {
                    hint = 1 /* Expression */;
                    if (substituteNode !== ts.noEmitSubstitution) {
                        lastSubstitution = node = substituteNode(hint, node);
                    }
                }
                else if (ts.isToken(node)) {
                    return writeTokenNode(node, writePunctuation);
                }
            }
            if (hint === 1 /* Expression */) {
                switch (node.kind) {
                    // Literals
                    case 8 /* NumericLiteral */:
                    case 9 /* BigIntLiteral */:
                        return emitNumericOrBigIntLiteral(node);
                    case 10 /* StringLiteral */:
                    case 13 /* RegularExpressionLiteral */:
                    case 14 /* NoSubstitutionTemplateLiteral */:
                        return emitLiteral(node, /*jsxAttributeEscape*/ false);
                    // Identifiers
                    case 75 /* Identifier */:
                        return emitIdentifier(node);
                    // Reserved words
                    case 91 /* FalseKeyword */:
                    case 100 /* NullKeyword */:
                    case 102 /* SuperKeyword */:
                    case 106 /* TrueKeyword */:
                    case 104 /* ThisKeyword */:
                    case 96 /* ImportKeyword */:
                        writeTokenNode(node, writeKeyword);
                        return;
                    // Expressions
                    case 192 /* ArrayLiteralExpression */:
                        return emitArrayLiteralExpression(node);
                    case 193 /* ObjectLiteralExpression */:
                        return emitObjectLiteralExpression(node);
                    case 194 /* PropertyAccessExpression */:
                        return emitPropertyAccessExpression(node);
                    case 195 /* ElementAccessExpression */:
                        return emitElementAccessExpression(node);
                    case 196 /* CallExpression */:
                        return emitCallExpression(node);
                    case 197 /* NewExpression */:
                        return emitNewExpression(node);
                    case 198 /* TaggedTemplateExpression */:
                        return emitTaggedTemplateExpression(node);
                    case 199 /* TypeAssertionExpression */:
                        return emitTypeAssertionExpression(node);
                    case 200 /* ParenthesizedExpression */:
                        return emitParenthesizedExpression(node);
                    case 201 /* FunctionExpression */:
                        return emitFunctionExpression(node);
                    case 202 /* ArrowFunction */:
                        return emitArrowFunction(node);
                    case 203 /* DeleteExpression */:
                        return emitDeleteExpression(node);
                    case 204 /* TypeOfExpression */:
                        return emitTypeOfExpression(node);
                    case 205 /* VoidExpression */:
                        return emitVoidExpression(node);
                    case 206 /* AwaitExpression */:
                        return emitAwaitExpression(node);
                    case 207 /* PrefixUnaryExpression */:
                        return emitPrefixUnaryExpression(node);
                    case 208 /* PostfixUnaryExpression */:
                        return emitPostfixUnaryExpression(node);
                    case 209 /* BinaryExpression */:
                        return emitBinaryExpression(node);
                    case 210 /* ConditionalExpression */:
                        return emitConditionalExpression(node);
                    case 211 /* TemplateExpression */:
                        return emitTemplateExpression(node);
                    case 212 /* YieldExpression */:
                        return emitYieldExpression(node);
                    case 213 /* SpreadElement */:
                        return emitSpreadExpression(node);
                    case 214 /* ClassExpression */:
                        return emitClassExpression(node);
                    case 215 /* OmittedExpression */:
                        return;
                    case 217 /* AsExpression */:
                        return emitAsExpression(node);
                    case 218 /* NonNullExpression */:
                        return emitNonNullExpression(node);
                    case 219 /* MetaProperty */:
                        return emitMetaProperty(node);
                    // JSX
                    case 266 /* JsxElement */:
                        return emitJsxElement(node);
                    case 267 /* JsxSelfClosingElement */:
                        return emitJsxSelfClosingElement(node);
                    case 270 /* JsxFragment */:
                        return emitJsxFragment(node);
                    // Transformation nodes
                    case 326 /* PartiallyEmittedExpression */:
                        return emitPartiallyEmittedExpression(node);
                    case 327 /* CommaListExpression */:
                        return emitCommaList(node);
                }
            }
        }
        function emitMappedTypeParameter(node) {
            emit(node.name);
            writeSpace();
            writeKeyword("in");
            writeSpace();
            emit(node.constraint);
        }
        function pipelineEmitWithSubstitution(hint, node) {
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
            var pipelinePhase = getNextPipelinePhase(1 /* Substitution */, hint, node);
            pipelinePhase(hint, lastSubstitution);
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
        }
        function getHelpersFromBundledSourceFiles(bundle) {
            var result;
            if (moduleKind === ts.ModuleKind.None || printerOptions.noEmitHelpers) {
                return undefined;
            }
            var bundledHelpers = ts.createMap();
            for (var _a = 0, _b = bundle.sourceFiles; _a < _b.length; _a++) {
                var sourceFile = _b[_a];
                var shouldSkip = ts.getExternalHelpersModuleName(sourceFile) !== undefined;
                var helpers = getSortedEmitHelpers(sourceFile);
                if (!helpers)
                    continue;
                for (var _c = 0, helpers_4 = helpers; _c < helpers_4.length; _c++) {
                    var helper = helpers_4[_c];
                    if (!helper.scoped && !shouldSkip && !bundledHelpers.get(helper.name)) {
                        bundledHelpers.set(helper.name, true);
                        (result || (result = [])).push(helper.name);
                    }
                }
            }
            return result;
        }
        function emitHelpers(node) {
            var helpersEmitted = false;
            var bundle = node.kind === 291 /* Bundle */ ? node : undefined;
            if (bundle && moduleKind === ts.ModuleKind.None) {
                return;
            }
            var numPrepends = bundle ? bundle.prepends.length : 0;
            var numNodes = bundle ? bundle.sourceFiles.length + numPrepends : 1;
            for (var i = 0; i < numNodes; i++) {
                var currentNode = bundle ? i < numPrepends ? bundle.prepends[i] : bundle.sourceFiles[i - numPrepends] : node;
                var sourceFile = ts.isSourceFile(currentNode) ? currentNode : ts.isUnparsedSource(currentNode) ? undefined : currentSourceFile;
                var shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && ts.hasRecordedExternalHelpers(sourceFile));
                var shouldBundle = (ts.isSourceFile(currentNode) || ts.isUnparsedSource(currentNode)) && !isOwnFileEmit;
                var helpers = ts.isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode);
                if (helpers) {
                    for (var _a = 0, helpers_5 = helpers; _a < helpers_5.length; _a++) {
                        var helper = helpers_5[_a];
                        if (!helper.scoped) {
                            // Skip the helper if it can be skipped and the noEmitHelpers compiler
                            // option is set, or if it can be imported and the importHelpers compiler
                            // option is set.
                            if (shouldSkip)
                                continue;
                            // Skip the helper if it can be bundled but hasn't already been emitted and we
                            // are emitting a bundled module.
                            if (shouldBundle) {
                                if (bundledHelpers.get(helper.name)) {
                                    continue;
                                }
                                bundledHelpers.set(helper.name, true);
                            }
                        }
                        else if (bundle) {
                            // Skip the helper if it is scoped and we are emitting bundled helpers
                            continue;
                        }
                        var pos = getTextPosWithWriteLine();
                        if (typeof helper.text === "string") {
                            writeLines(helper.text);
                        }
                        else {
                            writeLines(helper.text(makeFileLevelOptimisticUniqueName));
                        }
                        if (bundleFileInfo)
                            bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "emitHelpers" /* EmitHelpers */, data: helper.name });
                        helpersEmitted = true;
                    }
                }
            }
            return helpersEmitted;
        }
        function getSortedEmitHelpers(node) {
            var helpers = ts.getEmitHelpers(node);
            return helpers && ts.stableSort(helpers, ts.compareEmitHelpers);
        }
        //
        // Literals/Pseudo-literals
        //
        // SyntaxKind.NumericLiteral
        // SyntaxKind.BigIntLiteral
        function emitNumericOrBigIntLiteral(node) {
            emitLiteral(node, /*jsxAttributeEscape*/ false);
        }
        // SyntaxKind.StringLiteral
        // SyntaxKind.RegularExpressionLiteral
        // SyntaxKind.NoSubstitutionTemplateLiteral
        // SyntaxKind.TemplateHead
        // SyntaxKind.TemplateMiddle
        // SyntaxKind.TemplateTail
        function emitLiteral(node, jsxAttributeEscape) {
            var text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape, jsxAttributeEscape);
            if ((printerOptions.sourceMap || printerOptions.inlineSourceMap)
                && (node.kind === 10 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) {
                writeLiteral(text);
            }
            else {
                // Quick info expects all literals to be called with writeStringLiteral, as there's no specific type for numberLiterals
                writeStringLiteral(text);
            }
        }
        // SyntaxKind.UnparsedSource
        // SyntaxKind.UnparsedPrepend
        function emitUnparsedSourceOrPrepend(unparsed) {
            for (var _a = 0, _b = unparsed.texts; _a < _b.length; _a++) {
                var text = _b[_a];
                writeLine();
                emit(text);
            }
        }
        // SyntaxKind.UnparsedPrologue
        // SyntaxKind.UnparsedText
        // SyntaxKind.UnparsedInternal
        // SyntaxKind.UnparsedSyntheticReference
        function writeUnparsedNode(unparsed) {
            writer.rawWrite(unparsed.parent.text.substring(unparsed.pos, unparsed.end));
        }
        // SyntaxKind.UnparsedText
        // SyntaxKind.UnparsedInternal
        function emitUnparsedTextLike(unparsed) {
            var pos = getTextPosWithWriteLine();
            writeUnparsedNode(unparsed);
            if (bundleFileInfo) {
                updateOrPushBundleFileTextLike(pos, writer.getTextPos(), unparsed.kind === 287 /* UnparsedText */ ?
                    "text" /* Text */ :
                    "internal" /* Internal */);
            }
        }
        // SyntaxKind.UnparsedSyntheticReference
        function emitUnparsedSyntheticReference(unparsed) {
            var pos = getTextPosWithWriteLine();
            writeUnparsedNode(unparsed);
            if (bundleFileInfo) {
                var section = ts.clone(unparsed.section);
                section.pos = pos;
                section.end = writer.getTextPos();
                bundleFileInfo.sections.push(section);
            }
        }
        //
        // Identifiers
        //
        function emitIdentifier(node) {
            var writeText = node.symbol ? writeSymbol : write;
            writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol);
            emitList(node, node.typeArguments, 53776 /* TypeParameters */); // Call emitList directly since it could be an array of TypeParameterDeclarations _or_ type arguments
        }
        //
        // Names
        //
        function emitPrivateIdentifier(node) {
            var writeText = node.symbol ? writeSymbol : write;
            writeText(getTextOfNode(node, /*includeTrivia*/ false), node.symbol);
        }
        function emitQualifiedName(node) {
            emitEntityName(node.left);
            writePunctuation(".");
            emit(node.right);
        }
        function emitEntityName(node) {
            if (node.kind === 75 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        function emitComputedPropertyName(node) {
            writePunctuation("[");
            emitExpression(node.expression);
            writePunctuation("]");
        }
        //
        // Signature elements
        //
        function emitTypeParameter(node) {
            emit(node.name);
            if (node.constraint) {
                writeSpace();
                writeKeyword("extends");
                writeSpace();
                emit(node.constraint);
            }
            if (node.default) {
                writeSpace();
                writeOperator("=");
                writeSpace();
                emit(node.default);
            }
        }
        function emitParameter(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.dotDotDotToken);
            emitNodeWithWriter(node.name, writeParameter);
            emit(node.questionToken);
            if (node.parent && node.parent.kind === 300 /* JSDocFunctionType */ && !node.name) {
                emit(node.type);
            }
            else {
                emitTypeAnnotation(node.type);
            }
            // The comment position has to fallback to any present node within the parameterdeclaration because as it turns out, the parser can make parameter declarations with _just_ an initializer.
            emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name ? node.name.end : node.modifiers ? node.modifiers.end : node.decorators ? node.decorators.end : node.pos, node);
        }
        function emitDecorator(decorator) {
            writePunctuation("@");
            emitExpression(decorator.expression);
        }
        //
        // Type members
        //
        function emitPropertySignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitNodeWithWriter(node.name, writeProperty);
            emit(node.questionToken);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
        }
        function emitPropertyDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emit(node.questionToken);
            emit(node.exclamationToken);
            emitTypeAnnotation(node.type);
            emitInitializer(node.initializer, node.type ? node.type.end : node.questionToken ? node.questionToken.end : node.name.end, node);
            writeTrailingSemicolon();
        }
        function emitMethodSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.name);
            emit(node.questionToken);
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitMethodDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emit(node.asteriskToken);
            emit(node.name);
            emit(node.questionToken);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitConstructor(node) {
            emitModifiers(node, node.modifiers);
            writeKeyword("constructor");
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitAccessorDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword(node.kind === 163 /* GetAccessor */ ? "get" : "set");
            writeSpace();
            emit(node.name);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitCallSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitConstructSignature(node) {
            pushNameGenerationScope(node);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("new");
            writeSpace();
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
            popNameGenerationScope(node);
        }
        function emitIndexSignature(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitParametersForIndexSignature(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeTrailingSemicolon();
        }
        function emitSemicolonClassElement() {
            writeTrailingSemicolon();
        }
        //
        // Types
        //
        function emitTypePredicate(node) {
            if (node.assertsModifier) {
                emit(node.assertsModifier);
                writeSpace();
            }
            emit(node.parameterName);
            if (node.type) {
                writeSpace();
                writeKeyword("is");
                writeSpace();
                emit(node.type);
            }
        }
        function emitTypeReference(node) {
            emit(node.typeName);
            emitTypeArguments(node, node.typeArguments);
        }
        function emitFunctionType(node) {
            pushNameGenerationScope(node);
            emitTypeParameters(node, node.typeParameters);
            emitParametersForArrow(node, node.parameters);
            writeSpace();
            writePunctuation("=>");
            writeSpace();
            emit(node.type);
            popNameGenerationScope(node);
        }
        function emitJSDocFunctionType(node) {
            writeKeyword("function");
            emitParameters(node, node.parameters);
            writePunctuation(":");
            emit(node.type);
        }
        function emitJSDocNullableType(node) {
            writePunctuation("?");
            emit(node.type);
        }
        function emitJSDocNonNullableType(node) {
            writePunctuation("!");
            emit(node.type);
        }
        function emitJSDocOptionalType(node) {
            emit(node.type);
            writePunctuation("=");
        }
        function emitConstructorType(node) {
            pushNameGenerationScope(node);
            writeKeyword("new");
            writeSpace();
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            writeSpace();
            writePunctuation("=>");
            writeSpace();
            emit(node.type);
            popNameGenerationScope(node);
        }
        function emitTypeQuery(node) {
            writeKeyword("typeof");
            writeSpace();
            emit(node.exprName);
        }
        function emitTypeLiteral(node) {
            writePunctuation("{");
            var flags = ts.getEmitFlags(node) & 1 /* SingleLine */ ? 768 /* SingleLineTypeLiteralMembers */ : 32897 /* MultiLineTypeLiteralMembers */;
            emitList(node, node.members, flags | 524288 /* NoSpaceIfEmpty */);
            writePunctuation("}");
        }
        function emitArrayType(node) {
            emit(node.elementType);
            writePunctuation("[");
            writePunctuation("]");
        }
        function emitRestOrJSDocVariadicType(node) {
            writePunctuation("...");
            emit(node.type);
        }
        function emitTupleType(node) {
            writePunctuation("[");
            emitList(node, node.elementTypes, 528 /* TupleTypeElements */);
            writePunctuation("]");
        }
        function emitOptionalType(node) {
            emit(node.type);
            writePunctuation("?");
        }
        function emitUnionType(node) {
            emitList(node, node.types, 516 /* UnionTypeConstituents */);
        }
        function emitIntersectionType(node) {
            emitList(node, node.types, 520 /* IntersectionTypeConstituents */);
        }
        function emitConditionalType(node) {
            emit(node.checkType);
            writeSpace();
            writeKeyword("extends");
            writeSpace();
            emit(node.extendsType);
            writeSpace();
            writePunctuation("?");
            writeSpace();
            emit(node.trueType);
            writeSpace();
            writePunctuation(":");
            writeSpace();
            emit(node.falseType);
        }
        function emitInferType(node) {
            writeKeyword("infer");
            writeSpace();
            emit(node.typeParameter);
        }
        function emitParenthesizedType(node) {
            writePunctuation("(");
            emit(node.type);
            writePunctuation(")");
        }
        function emitThisType() {
            writeKeyword("this");
        }
        function emitTypeOperator(node) {
            writeTokenText(node.operator, writeKeyword);
            writeSpace();
            emit(node.type);
        }
        function emitIndexedAccessType(node) {
            emit(node.objectType);
            writePunctuation("[");
            emit(node.indexType);
            writePunctuation("]");
        }
        function emitMappedType(node) {
            var emitFlags = ts.getEmitFlags(node);
            writePunctuation("{");
            if (emitFlags & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
                increaseIndent();
            }
            if (node.readonlyToken) {
                emit(node.readonlyToken);
                if (node.readonlyToken.kind !== 138 /* ReadonlyKeyword */) {
                    writeKeyword("readonly");
                }
                writeSpace();
            }
            writePunctuation("[");
            pipelineEmit(3 /* MappedTypeParameter */, node.typeParameter);
            writePunctuation("]");
            if (node.questionToken) {
                emit(node.questionToken);
                if (node.questionToken.kind !== 57 /* QuestionToken */) {
                    writePunctuation("?");
                }
            }
            writePunctuation(":");
            writeSpace();
            emit(node.type);
            writeTrailingSemicolon();
            if (emitFlags & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
                decreaseIndent();
            }
            writePunctuation("}");
        }
        function emitLiteralType(node) {
            emitExpression(node.literal);
        }
        function emitImportTypeNode(node) {
            if (node.isTypeOf) {
                writeKeyword("typeof");
                writeSpace();
            }
            writeKeyword("import");
            writePunctuation("(");
            emit(node.argument);
            writePunctuation(")");
            if (node.qualifier) {
                writePunctuation(".");
                emit(node.qualifier);
            }
            emitTypeArguments(node, node.typeArguments);
        }
        //
        // Binding patterns
        //
        function emitObjectBindingPattern(node) {
            writePunctuation("{");
            emitList(node, node.elements, 525136 /* ObjectBindingPatternElements */);
            writePunctuation("}");
        }
        function emitArrayBindingPattern(node) {
            writePunctuation("[");
            emitList(node, node.elements, 524880 /* ArrayBindingPatternElements */);
            writePunctuation("]");
        }
        function emitBindingElement(node) {
            emit(node.dotDotDotToken);
            if (node.propertyName) {
                emit(node.propertyName);
                writePunctuation(":");
                writeSpace();
            }
            emit(node.name);
            emitInitializer(node.initializer, node.name.end, node);
        }
        //
        // Expressions
        //
        function emitArrayLiteralExpression(node) {
            var elements = node.elements;
            var preferNewLine = node.multiLine ? 65536 /* PreferNewLine */ : 0 /* None */;
            emitExpressionList(node, elements, 8914 /* ArrayLiteralExpressionElements */ | preferNewLine);
        }
        function emitObjectLiteralExpression(node) {
            ts.forEach(node.properties, generateMemberNames);
            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
            if (indentedFlag) {
                increaseIndent();
            }
            var preferNewLine = node.multiLine ? 65536 /* PreferNewLine */ : 0 /* None */;
            var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ && !ts.isJsonSourceFile(currentSourceFile) ? 64 /* AllowTrailingComma */ : 0 /* None */;
            emitList(node, node.properties, 526226 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine);
            if (indentedFlag) {
                decreaseIndent();
            }
        }
        function emitPropertyAccessExpression(node) {
            var expression = ts.cast(emitExpression(node.expression), ts.isExpression);
            var token = node.questionDotToken || ts.createNode(24 /* DotToken */, node.expression.end, node.name.pos);
            var linesBeforeDot = getLinesBetweenNodes(node, node.expression, token);
            var linesAfterDot = getLinesBetweenNodes(node, token, node.name);
            writeLinesAndIndent(linesBeforeDot, /*writeSpaceIfNotIndenting*/ false);
            var shouldEmitDotDot = token.kind !== 28 /* QuestionDotToken */ &&
                mayNeedDotDotForPropertyAccess(expression) &&
                !writer.hasTrailingComment() &&
                !writer.hasTrailingWhitespace();
            if (shouldEmitDotDot) {
                writePunctuation(".");
            }
            if (node.questionDotToken) {
                emit(token);
            }
            else {
                emitTokenWithComment(token.kind, node.expression.end, writePunctuation, node);
            }
            writeLinesAndIndent(linesAfterDot, /*writeSpaceIfNotIndenting*/ false);
            emit(node.name);
            decreaseIndentIf(linesBeforeDot, linesAfterDot);
        }
        // 1..toString is a valid property access, emit a dot after the literal
        // Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal
        function mayNeedDotDotForPropertyAccess(expression) {
            expression = ts.skipPartiallyEmittedExpressions(expression);
            if (ts.isNumericLiteral(expression)) {
                // check if numeric literal is a decimal literal that was originally written with a dot
                var text = getLiteralTextOfNode(expression, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false);
                // If he number will be printed verbatim and it doesn't already contain a dot, add one
                // if the expression doesn't have any comments that will be emitted.
                return !expression.numericLiteralFlags && !ts.stringContains(text, ts.tokenToString(24 /* DotToken */));
            }
            else if (ts.isAccessExpression(expression)) {
                // check if constant enum value is integer
                var constantValue = ts.getConstantValue(expression);
                // isFinite handles cases when constantValue is undefined
                return typeof constantValue === "number" && isFinite(constantValue)
                    && Math.floor(constantValue) === constantValue;
            }
        }
        function emitElementAccessExpression(node) {
            emitExpression(node.expression);
            emit(node.questionDotToken);
            emitTokenWithComment(22 /* OpenBracketToken */, node.expression.end, writePunctuation, node);
            emitExpression(node.argumentExpression);
            emitTokenWithComment(23 /* CloseBracketToken */, node.argumentExpression.end, writePunctuation, node);
        }
        function emitCallExpression(node) {
            emitExpression(node.expression);
            emit(node.questionDotToken);
            emitTypeArguments(node, node.typeArguments);
            emitExpressionList(node, node.arguments, 2576 /* CallExpressionArguments */);
        }
        function emitNewExpression(node) {
            emitTokenWithComment(99 /* NewKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
            emitExpressionList(node, node.arguments, 18960 /* NewExpressionArguments */);
        }
        function emitTaggedTemplateExpression(node) {
            emitExpression(node.tag);
            emitTypeArguments(node, node.typeArguments);
            writeSpace();
            emitExpression(node.template);
        }
        function emitTypeAssertionExpression(node) {
            writePunctuation("<");
            emit(node.type);
            writePunctuation(">");
            emitExpression(node.expression);
        }
        function emitParenthesizedExpression(node) {
            var openParenPos = emitTokenWithComment(20 /* OpenParenToken */, node.pos, writePunctuation, node);
            var indented = writeLineSeparatorsAndIndentBefore(node.expression, node);
            emitExpression(node.expression);
            writeLineSeparatorsAfter(node.expression, node);
            decreaseIndentIf(indented);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression ? node.expression.end : openParenPos, writePunctuation, node);
        }
        function emitFunctionExpression(node) {
            generateNameIfNeeded(node.name);
            emitFunctionDeclarationOrExpression(node);
        }
        function emitArrowFunction(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            emitSignatureAndBody(node, emitArrowFunctionHead);
        }
        function emitArrowFunctionHead(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParametersForArrow(node, node.parameters);
            emitTypeAnnotation(node.type);
            writeSpace();
            emit(node.equalsGreaterThanToken);
        }
        function emitDeleteExpression(node) {
            emitTokenWithComment(85 /* DeleteKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitTypeOfExpression(node) {
            emitTokenWithComment(108 /* TypeOfKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitVoidExpression(node) {
            emitTokenWithComment(110 /* VoidKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitAwaitExpression(node) {
            emitTokenWithComment(127 /* AwaitKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
        }
        function emitPrefixUnaryExpression(node) {
            writeTokenText(node.operator, writeOperator);
            if (shouldEmitWhitespaceBeforeOperand(node)) {
                writeSpace();
            }
            emitExpression(node.operand);
        }
        function shouldEmitWhitespaceBeforeOperand(node) {
            // In some cases, we need to emit a space between the operator and the operand. One obvious case
            // is when the operator is an identifier, like delete or typeof. We also need to do this for plus
            // and minus expressions in certain cases. Specifically, consider the following two cases (parens
            // are just for clarity of exposition, and not part of the source code):
            //
            //  (+(+1))
            //  (+(++1))
            //
            // We need to emit a space in both cases. In the first case, the absence of a space will make
            // the resulting expression a prefix increment operation. And in the second, it will make the resulting
            // expression a prefix increment whose operand is a plus expression - (++(+x))
            // The same is true of minus of course.
            var operand = node.operand;
            return operand.kind === 207 /* PrefixUnaryExpression */
                && ((node.operator === 39 /* PlusToken */ && (operand.operator === 39 /* PlusToken */ || operand.operator === 45 /* PlusPlusToken */))
                    || (node.operator === 40 /* MinusToken */ && (operand.operator === 40 /* MinusToken */ || operand.operator === 46 /* MinusMinusToken */)));
        }
        function emitPostfixUnaryExpression(node) {
            emitExpression(node.operand);
            writeTokenText(node.operator, writeOperator);
        }
        var EmitBinaryExpressionState;
        (function (EmitBinaryExpressionState) {
            EmitBinaryExpressionState[EmitBinaryExpressionState["EmitLeft"] = 0] = "EmitLeft";
            EmitBinaryExpressionState[EmitBinaryExpressionState["EmitRight"] = 1] = "EmitRight";
            EmitBinaryExpressionState[EmitBinaryExpressionState["FinishEmit"] = 2] = "FinishEmit";
        })(EmitBinaryExpressionState || (EmitBinaryExpressionState = {}));
        /**
         * emitBinaryExpression includes an embedded work stack to attempt to handle as many nested binary expressions
         * as possible without creating any additional stack frames. This can only be done when the emit pipeline does
         * not require notification/substitution/comment/sourcemap decorations.
         */
        function emitBinaryExpression(node) {
            var nodeStack = [node];
            var stateStack = [0 /* EmitLeft */];
            var stackIndex = 0;
            while (stackIndex >= 0) {
                node = nodeStack[stackIndex];
                switch (stateStack[stackIndex]) {
                    case 0 /* EmitLeft */: {
                        maybePipelineEmitExpression(node.left);
                        break;
                    }
                    case 1 /* EmitRight */: {
                        var isCommaOperator = node.operatorToken.kind !== 27 /* CommaToken */;
                        var linesBeforeOperator = getLinesBetweenNodes(node, node.left, node.operatorToken);
                        var linesAfterOperator = getLinesBetweenNodes(node, node.operatorToken, node.right);
                        writeLinesAndIndent(linesBeforeOperator, isCommaOperator);
                        emitLeadingCommentsOfPosition(node.operatorToken.pos);
                        writeTokenNode(node.operatorToken, node.operatorToken.kind === 97 /* InKeyword */ ? writeKeyword : writeOperator);
                        emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts
                        writeLinesAndIndent(linesAfterOperator, /*writeSpaceIfNotIndenting*/ true);
                        maybePipelineEmitExpression(node.right);
                        break;
                    }
                    case 2 /* FinishEmit */: {
                        var linesBeforeOperator = getLinesBetweenNodes(node, node.left, node.operatorToken);
                        var linesAfterOperator = getLinesBetweenNodes(node, node.operatorToken, node.right);
                        decreaseIndentIf(linesBeforeOperator, linesAfterOperator);
                        stackIndex--;
                        break;
                    }
                    default: return ts.Debug.fail("Invalid state " + stateStack[stackIndex] + " for emitBinaryExpressionWorker");
                }
            }
            function maybePipelineEmitExpression(next) {
                // Advance the state of this unit of work,
                stateStack[stackIndex]++;
                // Then actually do the work of emitting the node `next` returned by the prior state
                // The following section should be identical to `pipelineEmit` save it assumes EmitHint.Expression and offloads
                // binary expression handling, where possible, to the contained work queue
                // #region trampolinePipelineEmit
                var savedLastNode = lastNode;
                var savedLastSubstitution = lastSubstitution;
                lastNode = next;
                lastSubstitution = undefined;
                var pipelinePhase = getPipelinePhase(0 /* Notification */, 1 /* Expression */, next);
                if (pipelinePhase === pipelineEmitWithHint && ts.isBinaryExpression(next)) {
                    // If the target pipeline phase is emit directly, and the next node's also a binary expression,
                    // skip all the intermediate indirection and push the expression directly onto the work stack
                    stackIndex++;
                    stateStack[stackIndex] = 0 /* EmitLeft */;
                    nodeStack[stackIndex] = next;
                }
                else {
                    pipelinePhase(1 /* Expression */, next);
                }
                ts.Debug.assert(lastNode === next);
                lastNode = savedLastNode;
                lastSubstitution = savedLastSubstitution;
                // #endregion trampolinePipelineEmit
            }
        }
        function emitConditionalExpression(node) {
            var linesBeforeQuestion = getLinesBetweenNodes(node, node.condition, node.questionToken);
            var linesAfterQuestion = getLinesBetweenNodes(node, node.questionToken, node.whenTrue);
            var linesBeforeColon = getLinesBetweenNodes(node, node.whenTrue, node.colonToken);
            var linesAfterColon = getLinesBetweenNodes(node, node.colonToken, node.whenFalse);
            emitExpression(node.condition);
            writeLinesAndIndent(linesBeforeQuestion, /*writeSpaceIfNotIndenting*/ true);
            emit(node.questionToken);
            writeLinesAndIndent(linesAfterQuestion, /*writeSpaceIfNotIndenting*/ true);
            emitExpression(node.whenTrue);
            decreaseIndentIf(linesBeforeQuestion, linesAfterQuestion);
            writeLinesAndIndent(linesBeforeColon, /*writeSpaceIfNotIndenting*/ true);
            emit(node.colonToken);
            writeLinesAndIndent(linesAfterColon, /*writeSpaceIfNotIndenting*/ true);
            emitExpression(node.whenFalse);
            decreaseIndentIf(linesBeforeColon, linesAfterColon);
        }
        function emitTemplateExpression(node) {
            emit(node.head);
            emitList(node, node.templateSpans, 262144 /* TemplateExpressionSpans */);
        }
        function emitYieldExpression(node) {
            emitTokenWithComment(121 /* YieldKeyword */, node.pos, writeKeyword, node);
            emit(node.asteriskToken);
            emitExpressionWithLeadingSpace(node.expression);
        }
        function emitSpreadExpression(node) {
            emitTokenWithComment(25 /* DotDotDotToken */, node.pos, writePunctuation, node);
            emitExpression(node.expression);
        }
        function emitClassExpression(node) {
            generateNameIfNeeded(node.name);
            emitClassDeclarationOrExpression(node);
        }
        function emitExpressionWithTypeArguments(node) {
            emitExpression(node.expression);
            emitTypeArguments(node, node.typeArguments);
        }
        function emitAsExpression(node) {
            emitExpression(node.expression);
            if (node.type) {
                writeSpace();
                writeKeyword("as");
                writeSpace();
                emit(node.type);
            }
        }
        function emitNonNullExpression(node) {
            emitExpression(node.expression);
            writeOperator("!");
        }
        function emitMetaProperty(node) {
            writeToken(node.keywordToken, node.pos, writePunctuation);
            writePunctuation(".");
            emit(node.name);
        }
        //
        // Misc
        //
        function emitTemplateSpan(node) {
            emitExpression(node.expression);
            emit(node.literal);
        }
        //
        // Statements
        //
        function emitBlock(node) {
            emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node));
        }
        function emitBlockStatements(node, forceSingleLine) {
            emitTokenWithComment(18 /* OpenBraceToken */, node.pos, writePunctuation, /*contextNode*/ node);
            var format = forceSingleLine || ts.getEmitFlags(node) & 1 /* SingleLine */ ? 768 /* SingleLineBlockStatements */ : 129 /* MultiLineBlockStatements */;
            emitList(node, node.statements, format);
            emitTokenWithComment(19 /* CloseBraceToken */, node.statements.end, writePunctuation, /*contextNode*/ node, /*indentLeading*/ !!(format & 1 /* MultiLine */));
        }
        function emitVariableStatement(node) {
            emitModifiers(node, node.modifiers);
            emit(node.declarationList);
            writeTrailingSemicolon();
        }
        function emitEmptyStatement(isEmbeddedStatement) {
            // While most trailing semicolons are possibly insignificant, an embedded "empty"
            // statement is significant and cannot be elided by a trailing-semicolon-omitting writer.
            if (isEmbeddedStatement) {
                writePunctuation(";");
            }
            else {
                writeTrailingSemicolon();
            }
        }
        function emitExpressionStatement(node) {
            emitExpression(node.expression);
            // Emit semicolon in non json files
            // or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation)
            if (!ts.isJsonSourceFile(currentSourceFile) || ts.nodeIsSynthesized(node.expression)) {
                writeTrailingSemicolon();
            }
        }
        function emitIfStatement(node) {
            var openParenPos = emitTokenWithComment(95 /* IfKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.thenStatement);
            if (node.elseStatement) {
                writeLineOrSpace(node);
                emitTokenWithComment(87 /* ElseKeyword */, node.thenStatement.end, writeKeyword, node);
                if (node.elseStatement.kind === 227 /* IfStatement */) {
                    writeSpace();
                    emit(node.elseStatement);
                }
                else {
                    emitEmbeddedStatement(node, node.elseStatement);
                }
            }
        }
        function emitWhileClause(node, startPos) {
            var openParenPos = emitTokenWithComment(111 /* WhileKeyword */, startPos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
        }
        function emitDoStatement(node) {
            emitTokenWithComment(86 /* DoKeyword */, node.pos, writeKeyword, node);
            emitEmbeddedStatement(node, node.statement);
            if (ts.isBlock(node.statement)) {
                writeSpace();
            }
            else {
                writeLineOrSpace(node);
            }
            emitWhileClause(node, node.statement.end);
            writeTrailingSemicolon();
        }
        function emitWhileStatement(node) {
            emitWhileClause(node, node.pos);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForStatement(node) {
            var openParenPos = emitTokenWithComment(93 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            var pos = emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, /*contextNode*/ node);
            emitForBinding(node.initializer);
            pos = emitTokenWithComment(26 /* SemicolonToken */, node.initializer ? node.initializer.end : pos, writePunctuation, node);
            emitExpressionWithLeadingSpace(node.condition);
            pos = emitTokenWithComment(26 /* SemicolonToken */, node.condition ? node.condition.end : pos, writePunctuation, node);
            emitExpressionWithLeadingSpace(node.incrementor);
            emitTokenWithComment(21 /* CloseParenToken */, node.incrementor ? node.incrementor.end : pos, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForInStatement(node) {
            var openParenPos = emitTokenWithComment(93 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitForBinding(node.initializer);
            writeSpace();
            emitTokenWithComment(97 /* InKeyword */, node.initializer.end, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForOfStatement(node) {
            var openParenPos = emitTokenWithComment(93 /* ForKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitWithTrailingSpace(node.awaitModifier);
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitForBinding(node.initializer);
            writeSpace();
            emitTokenWithComment(152 /* OfKeyword */, node.initializer.end, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitForBinding(node) {
            if (node !== undefined) {
                if (node.kind === 243 /* VariableDeclarationList */) {
                    emit(node);
                }
                else {
                    emitExpression(node);
                }
            }
        }
        function emitContinueStatement(node) {
            emitTokenWithComment(82 /* ContinueKeyword */, node.pos, writeKeyword, node);
            emitWithLeadingSpace(node.label);
            writeTrailingSemicolon();
        }
        function emitBreakStatement(node) {
            emitTokenWithComment(77 /* BreakKeyword */, node.pos, writeKeyword, node);
            emitWithLeadingSpace(node.label);
            writeTrailingSemicolon();
        }
        function emitTokenWithComment(token, pos, writer, contextNode, indentLeading) {
            var node = ts.getParseTreeNode(contextNode);
            var isSimilarNode = node && node.kind === contextNode.kind;
            var startPos = pos;
            if (isSimilarNode && currentSourceFile) {
                pos = ts.skipTrivia(currentSourceFile.text, pos);
            }
            if (emitLeadingCommentsOfPosition && isSimilarNode && contextNode.pos !== startPos) {
                var needsIndent = indentLeading && currentSourceFile && !ts.positionsAreOnSameLine(startPos, pos, currentSourceFile);
                if (needsIndent) {
                    increaseIndent();
                }
                emitLeadingCommentsOfPosition(startPos);
                if (needsIndent) {
                    decreaseIndent();
                }
            }
            pos = writeTokenText(token, writer, pos);
            if (emitTrailingCommentsOfPosition && isSimilarNode && contextNode.end !== pos) {
                emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true);
            }
            return pos;
        }
        function emitReturnStatement(node) {
            emitTokenWithComment(101 /* ReturnKeyword */, node.pos, writeKeyword, /*contextNode*/ node);
            emitExpressionWithLeadingSpace(node.expression);
            writeTrailingSemicolon();
        }
        function emitWithStatement(node) {
            var openParenPos = emitTokenWithComment(112 /* WithKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            emitEmbeddedStatement(node, node.statement);
        }
        function emitSwitchStatement(node) {
            var openParenPos = emitTokenWithComment(103 /* SwitchKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
            emitExpression(node.expression);
            emitTokenWithComment(21 /* CloseParenToken */, node.expression.end, writePunctuation, node);
            writeSpace();
            emit(node.caseBlock);
        }
        function emitLabeledStatement(node) {
            emit(node.label);
            emitTokenWithComment(58 /* ColonToken */, node.label.end, writePunctuation, node);
            writeSpace();
            emit(node.statement);
        }
        function emitThrowStatement(node) {
            emitTokenWithComment(105 /* ThrowKeyword */, node.pos, writeKeyword, node);
            emitExpressionWithLeadingSpace(node.expression);
            writeTrailingSemicolon();
        }
        function emitTryStatement(node) {
            emitTokenWithComment(107 /* TryKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emit(node.tryBlock);
            if (node.catchClause) {
                writeLineOrSpace(node);
                emit(node.catchClause);
            }
            if (node.finallyBlock) {
                writeLineOrSpace(node);
                emitTokenWithComment(92 /* FinallyKeyword */, (node.catchClause || node.tryBlock).end, writeKeyword, node);
                writeSpace();
                emit(node.finallyBlock);
            }
        }
        function emitDebuggerStatement(node) {
            writeToken(83 /* DebuggerKeyword */, node.pos, writeKeyword);
            writeTrailingSemicolon();
        }
        //
        // Declarations
        //
        function emitVariableDeclaration(node) {
            emit(node.name);
            emit(node.exclamationToken);
            emitTypeAnnotation(node.type);
            emitInitializer(node.initializer, node.type ? node.type.end : node.name.end, node);
        }
        function emitVariableDeclarationList(node) {
            writeKeyword(ts.isLet(node) ? "let" : ts.isVarConst(node) ? "const" : "var");
            writeSpace();
            emitList(node, node.declarations, 528 /* VariableDeclarationList */);
        }
        function emitFunctionDeclaration(node) {
            emitFunctionDeclarationOrExpression(node);
        }
        function emitFunctionDeclarationOrExpression(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("function");
            emit(node.asteriskToken);
            writeSpace();
            emitIdentifierName(node.name);
            emitSignatureAndBody(node, emitSignatureHead);
        }
        function emitBlockCallback(_hint, body) {
            emitBlockFunctionBody(body);
        }
        function emitSignatureAndBody(node, emitSignatureHead) {
            var body = node.body;
            if (body) {
                if (ts.isBlock(body)) {
                    var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
                    if (indentedFlag) {
                        increaseIndent();
                    }
                    pushNameGenerationScope(node);
                    ts.forEach(node.parameters, generateNames);
                    generateNames(node.body);
                    emitSignatureHead(node);
                    if (onEmitNode) {
                        onEmitNode(4 /* Unspecified */, body, emitBlockCallback);
                    }
                    else {
                        emitBlockFunctionBody(body);
                    }
                    popNameGenerationScope(node);
                    if (indentedFlag) {
                        decreaseIndent();
                    }
                }
                else {
                    emitSignatureHead(node);
                    writeSpace();
                    emitExpression(body);
                }
            }
            else {
                emitSignatureHead(node);
                writeTrailingSemicolon();
            }
        }
        function emitSignatureHead(node) {
            emitTypeParameters(node, node.typeParameters);
            emitParameters(node, node.parameters);
            emitTypeAnnotation(node.type);
        }
        function shouldEmitBlockFunctionBodyOnSingleLine(body) {
            // We must emit a function body as a single-line body in the following case:
            // * The body has NodeEmitFlags.SingleLine specified.
            // We must emit a function body as a multi-line body in the following cases:
            // * The body is explicitly marked as multi-line.
            // * A non-synthesized body's start and end position are on different lines.
            // * Any statement in the body starts on a new line.
            if (ts.getEmitFlags(body) & 1 /* SingleLine */) {
                return true;
            }
            if (body.multiLine) {
                return false;
            }
            if (!ts.nodeIsSynthesized(body) && !ts.rangeIsOnSingleLine(body, currentSourceFile)) {
                return false;
            }
            if (getLeadingLineTerminatorCount(body, body.statements, 2 /* PreserveLines */)
                || getClosingLineTerminatorCount(body, body.statements, 2 /* PreserveLines */)) {
                return false;
            }
            var previousStatement;
            for (var _a = 0, _b = body.statements; _a < _b.length; _a++) {
                var statement = _b[_a];
                if (getSeparatingLineTerminatorCount(previousStatement, statement, 2 /* PreserveLines */) > 0) {
                    return false;
                }
                previousStatement = statement;
            }
            return true;
        }
        function emitBlockFunctionBody(body) {
            writeSpace();
            writePunctuation("{");
            increaseIndent();
            var emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body)
                ? emitBlockFunctionBodyOnSingleLine
                : emitBlockFunctionBodyWorker;
            if (emitBodyWithDetachedComments) {
                emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
            }
            else {
                emitBlockFunctionBody(body);
            }
            decreaseIndent();
            writeToken(19 /* CloseBraceToken */, body.statements.end, writePunctuation, body);
        }
        function emitBlockFunctionBodyOnSingleLine(body) {
            emitBlockFunctionBodyWorker(body, /*emitBlockFunctionBodyOnSingleLine*/ true);
        }
        function emitBlockFunctionBodyWorker(body, emitBlockFunctionBodyOnSingleLine) {
            // Emit all the prologue directives (like "use strict").
            var statementOffset = emitPrologueDirectives(body.statements);
            var pos = writer.getTextPos();
            emitHelpers(body);
            if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) {
                decreaseIndent();
                emitList(body, body.statements, 768 /* SingleLineFunctionBodyStatements */);
                increaseIndent();
            }
            else {
                emitList(body, body.statements, 1 /* MultiLineFunctionBodyStatements */, statementOffset);
            }
        }
        function emitClassDeclaration(node) {
            emitClassDeclarationOrExpression(node);
        }
        function emitClassDeclarationOrExpression(node) {
            ts.forEach(node.members, generateMemberNames);
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("class");
            if (node.name) {
                writeSpace();
                emitIdentifierName(node.name);
            }
            var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */;
            if (indentedFlag) {
                increaseIndent();
            }
            emitTypeParameters(node, node.typeParameters);
            emitList(node, node.heritageClauses, 0 /* ClassHeritageClauses */);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 129 /* ClassMembers */);
            writePunctuation("}");
            if (indentedFlag) {
                decreaseIndent();
            }
        }
        function emitInterfaceDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("interface");
            writeSpace();
            emit(node.name);
            emitTypeParameters(node, node.typeParameters);
            emitList(node, node.heritageClauses, 512 /* HeritageClauses */);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 129 /* InterfaceMembers */);
            writePunctuation("}");
        }
        function emitTypeAliasDeclaration(node) {
            emitDecorators(node, node.decorators);
            emitModifiers(node, node.modifiers);
            writeKeyword("type");
            writeSpace();
            emit(node.name);
            emitTypeParameters(node, node.typeParameters);
            writeSpace();
            writePunctuation("=");
            writeSpace();
            emit(node.type);
            writeTrailingSemicolon();
        }
        function emitEnumDeclaration(node) {
            emitModifiers(node, node.modifiers);
            writeKeyword("enum");
            writeSpace();
            emit(node.name);
            writeSpace();
            writePunctuation("{");
            emitList(node, node.members, 145 /* EnumMembers */);
            writePunctuation("}");
        }
        function emitModuleDeclaration(node) {
            emitModifiers(node, node.modifiers);
            if (~node.flags & 1024 /* GlobalAugmentation */) {
                writeKeyword(node.flags & 16 /* Namespace */ ? "namespace" : "module");
                writeSpace();
            }
            emit(node.name);
            var body = node.body;
            if (!body)
                return writeTrailingSemicolon();
            while (body.kind === 249 /* ModuleDeclaration */) {
                writePunctuation(".");
                emit(body.name);
                body = body.body;
            }
            writeSpace();
            emit(body);
        }
        function emitModuleBlock(node) {
            pushNameGenerationScope(node);
            ts.forEach(node.statements, generateNames);
            emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node));
            popNameGenerationScope(node);
        }
        function emitCaseBlock(node) {
            emitTokenWithComment(18 /* OpenBraceToken */, node.pos, writePunctuation, node);
            emitList(node, node.clauses, 129 /* CaseBlockClauses */);
            emitTokenWithComment(19 /* CloseBraceToken */, node.clauses.end, writePunctuation, node, /*indentLeading*/ true);
        }
        function emitImportEqualsDeclaration(node) {
            emitModifiers(node, node.modifiers);
            emitTokenWithComment(96 /* ImportKeyword */, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
            writeSpace();
            emit(node.name);
            writeSpace();
            emitTokenWithComment(62 /* EqualsToken */, node.name.end, writePunctuation, node);
            writeSpace();
            emitModuleReference(node.moduleReference);
            writeTrailingSemicolon();
        }
        function emitModuleReference(node) {
            if (node.kind === 75 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        function emitImportDeclaration(node) {
            emitModifiers(node, node.modifiers);
            emitTokenWithComment(96 /* ImportKeyword */, node.modifiers ? node.modifiers.end : node.pos, writeKeyword, node);
            writeSpace();
            if (node.importClause) {
                emit(node.importClause);
                writeSpace();
                emitTokenWithComment(149 /* FromKeyword */, node.importClause.end, writeKeyword, node);
                writeSpace();
            }
            emitExpression(node.moduleSpecifier);
            writeTrailingSemicolon();
        }
        function emitImportClause(node) {
            if (node.isTypeOnly) {
                emitTokenWithComment(145 /* TypeKeyword */, node.pos, writeKeyword, node);
                writeSpace();
            }
            emit(node.name);
            if (node.name && node.namedBindings) {
                emitTokenWithComment(27 /* CommaToken */, node.name.end, writePunctuation, node);
                writeSpace();
            }
            emit(node.namedBindings);
        }
        function emitNamespaceImport(node) {
            var asPos = emitTokenWithComment(41 /* AsteriskToken */, node.pos, writePunctuation, node);
            writeSpace();
            emitTokenWithComment(123 /* AsKeyword */, asPos, writeKeyword, node);
            writeSpace();
            emit(node.name);
        }
        function emitNamedImports(node) {
            emitNamedImportsOrExports(node);
        }
        function emitImportSpecifier(node) {
            emitImportOrExportSpecifier(node);
        }
        function emitExportAssignment(node) {
            var nextPos = emitTokenWithComment(89 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.isExportEquals) {
                emitTokenWithComment(62 /* EqualsToken */, nextPos, writeOperator, node);
            }
            else {
                emitTokenWithComment(84 /* DefaultKeyword */, nextPos, writeKeyword, node);
            }
            writeSpace();
            emitExpression(node.expression);
            writeTrailingSemicolon();
        }
        function emitExportDeclaration(node) {
            var nextPos = emitTokenWithComment(89 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.isTypeOnly) {
                nextPos = emitTokenWithComment(145 /* TypeKeyword */, nextPos, writeKeyword, node);
                writeSpace();
            }
            if (node.exportClause) {
                emit(node.exportClause);
            }
            else {
                nextPos = emitTokenWithComment(41 /* AsteriskToken */, nextPos, writePunctuation, node);
            }
            if (node.moduleSpecifier) {
                writeSpace();
                var fromPos = node.exportClause ? node.exportClause.end : nextPos;
                emitTokenWithComment(149 /* FromKeyword */, fromPos, writeKeyword, node);
                writeSpace();
                emitExpression(node.moduleSpecifier);
            }
            writeTrailingSemicolon();
        }
        function emitNamespaceExportDeclaration(node) {
            var nextPos = emitTokenWithComment(89 /* ExportKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            nextPos = emitTokenWithComment(123 /* AsKeyword */, nextPos, writeKeyword, node);
            writeSpace();
            nextPos = emitTokenWithComment(136 /* NamespaceKeyword */, nextPos, writeKeyword, node);
            writeSpace();
            emit(node.name);
            writeTrailingSemicolon();
        }
        function emitNamespaceExport(node) {
            var asPos = emitTokenWithComment(41 /* AsteriskToken */, node.pos, writePunctuation, node);
            writeSpace();
            emitTokenWithComment(123 /* AsKeyword */, asPos, writeKeyword, node);
            writeSpace();
            emit(node.name);
        }
        function emitNamedExports(node) {
            emitNamedImportsOrExports(node);
        }
        function emitExportSpecifier(node) {
            emitImportOrExportSpecifier(node);
        }
        function emitNamedImportsOrExports(node) {
            writePunctuation("{");
            emitList(node, node.elements, 525136 /* NamedImportsOrExportsElements */);
            writePunctuation("}");
        }
        function emitImportOrExportSpecifier(node) {
            if (node.propertyName) {
                emit(node.propertyName);
                writeSpace();
                emitTokenWithComment(123 /* AsKeyword */, node.propertyName.end, writeKeyword, node);
                writeSpace();
            }
            emit(node.name);
        }
        //
        // Module references
        //
        function emitExternalModuleReference(node) {
            writeKeyword("require");
            writePunctuation("(");
            emitExpression(node.expression);
            writePunctuation(")");
        }
        //
        // JSX
        //
        function emitJsxElement(node) {
            emit(node.openingElement);
            emitList(node, node.children, 262144 /* JsxElementOrFragmentChildren */);
            emit(node.closingElement);
        }
        function emitJsxSelfClosingElement(node) {
            writePunctuation("<");
            emitJsxTagName(node.tagName);
            emitTypeArguments(node, node.typeArguments);
            writeSpace();
            emit(node.attributes);
            writePunctuation("/>");
        }
        function emitJsxFragment(node) {
            emit(node.openingFragment);
            emitList(node, node.children, 262144 /* JsxElementOrFragmentChildren */);
            emit(node.closingFragment);
        }
        function emitJsxOpeningElementOrFragment(node) {
            writePunctuation("<");
            if (ts.isJsxOpeningElement(node)) {
                var indented = writeLineSeparatorsAndIndentBefore(node.tagName, node);
                emitJsxTagName(node.tagName);
                emitTypeArguments(node, node.typeArguments);
                if (node.attributes.properties && node.attributes.properties.length > 0) {
                    writeSpace();
                }
                emit(node.attributes);
                writeLineSeparatorsAfter(node.attributes, node);
                decreaseIndentIf(indented);
            }
            writePunctuation(">");
        }
        function emitJsxText(node) {
            writer.writeLiteral(node.text);
        }
        function emitJsxClosingElementOrFragment(node) {
            writePunctuation("</");
            if (ts.isJsxClosingElement(node)) {
                emitJsxTagName(node.tagName);
            }
            writePunctuation(">");
        }
        function emitJsxAttributes(node) {
            emitList(node, node.properties, 262656 /* JsxElementAttributes */);
        }
        function emitJsxAttribute(node) {
            emit(node.name);
            emitNodeWithPrefix("=", writePunctuation, node.initializer, emitJsxAttributeValue);
        }
        function emitJsxSpreadAttribute(node) {
            writePunctuation("{...");
            emitExpression(node.expression);
            writePunctuation("}");
        }
        function emitJsxExpression(node) {
            if (node.expression) {
                writePunctuation("{");
                emit(node.dotDotDotToken);
                emitExpression(node.expression);
                writePunctuation("}");
            }
        }
        function emitJsxTagName(node) {
            if (node.kind === 75 /* Identifier */) {
                emitExpression(node);
            }
            else {
                emit(node);
            }
        }
        //
        // Clauses
        //
        function emitCaseClause(node) {
            emitTokenWithComment(78 /* CaseKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            emitExpression(node.expression);
            emitCaseOrDefaultClauseRest(node, node.statements, node.expression.end);
        }
        function emitDefaultClause(node) {
            var pos = emitTokenWithComment(84 /* DefaultKeyword */, node.pos, writeKeyword, node);
            emitCaseOrDefaultClauseRest(node, node.statements, pos);
        }
        function emitCaseOrDefaultClauseRest(parentNode, statements, colonPos) {
            var emitAsSingleStatement = statements.length === 1 &&
                (
                // treat synthesized nodes as located on the same line for emit purposes
                ts.nodeIsSynthesized(parentNode) ||
                    ts.nodeIsSynthesized(statements[0]) ||
                    ts.rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile));
            var format = 163969 /* CaseOrDefaultClauseStatements */;
            if (emitAsSingleStatement) {
                writeToken(58 /* ColonToken */, colonPos, writePunctuation, parentNode);
                writeSpace();
                format &= ~(1 /* MultiLine */ | 128 /* Indented */);
            }
            else {
                emitTokenWithComment(58 /* ColonToken */, colonPos, writePunctuation, parentNode);
            }
            emitList(parentNode, statements, format);
        }
        function emitHeritageClause(node) {
            writeSpace();
            writeTokenText(node.token, writeKeyword);
            writeSpace();
            emitList(node, node.types, 528 /* HeritageClauseTypes */);
        }
        function emitCatchClause(node) {
            var openParenPos = emitTokenWithComment(79 /* CatchKeyword */, node.pos, writeKeyword, node);
            writeSpace();
            if (node.variableDeclaration) {
                emitTokenWithComment(20 /* OpenParenToken */, openParenPos, writePunctuation, node);
                emit(node.variableDeclaration);
                emitTokenWithComment(21 /* CloseParenToken */, node.variableDeclaration.end, writePunctuation, node);
                writeSpace();
            }
            emit(node.block);
        }
        //
        // Property assignments
        //
        function emitPropertyAssignment(node) {
            emit(node.name);
            writePunctuation(":");
            writeSpace();
            // This is to ensure that we emit comment in the following case:
            //      For example:
            //          obj = {
            //              id: /*comment1*/ ()=>void
            //          }
            // "comment1" is not considered to be leading comment for node.initializer
            // but rather a trailing comment on the previous node.
            var initializer = node.initializer;
            if (emitTrailingCommentsOfPosition && (ts.getEmitFlags(initializer) & 512 /* NoLeadingComments */) === 0) {
                var commentRange = ts.getCommentRange(initializer);
                emitTrailingCommentsOfPosition(commentRange.pos);
            }
            emitExpression(initializer);
        }
        function emitShorthandPropertyAssignment(node) {
            emit(node.name);
            if (node.objectAssignmentInitializer) {
                writeSpace();
                writePunctuation("=");
                writeSpace();
                emitExpression(node.objectAssignmentInitializer);
            }
        }
        function emitSpreadAssignment(node) {
            if (node.expression) {
                emitTokenWithComment(25 /* DotDotDotToken */, node.pos, writePunctuation, node);
                emitExpression(node.expression);
            }
        }
        //
        // Enum
        //
        function emitEnumMember(node) {
            emit(node.name);
            emitInitializer(node.initializer, node.name.end, node);
        }
        //
        // JSDoc
        //
        function emitJSDoc(node) {
            write("/**");
            if (node.comment) {
                var lines = node.comment.split(/\r\n?|\n/g);
                for (var _a = 0, lines_2 = lines; _a < lines_2.length; _a++) {
                    var line = lines_2[_a];
                    writeLine();
                    writeSpace();
                    writePunctuation("*");
                    writeSpace();
                    write(line);
                }
            }
            if (node.tags) {
                if (node.tags.length === 1 && node.tags[0].kind === 320 /* JSDocTypeTag */ && !node.comment) {
                    writeSpace();
                    emit(node.tags[0]);
                }
                else {
                    emitList(node, node.tags, 33 /* JSDocComment */);
                }
            }
            writeSpace();
            write("*/");
        }
        function emitJSDocSimpleTypedTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocTypeExpression(tag.typeExpression);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocHeritageTag(tag) {
            emitJSDocTagName(tag.tagName);
            writeSpace();
            writePunctuation("{");
            emit(tag.class);
            writePunctuation("}");
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTemplateTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocTypeExpression(tag.constraint);
            writeSpace();
            emitList(tag, tag.typeParameters, 528 /* CommaListElements */);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTypedefTag(tag) {
            emitJSDocTagName(tag.tagName);
            if (tag.typeExpression) {
                if (tag.typeExpression.kind === 294 /* JSDocTypeExpression */) {
                    emitJSDocTypeExpression(tag.typeExpression);
                }
                else {
                    writeSpace();
                    writePunctuation("{");
                    write("Object");
                    if (tag.typeExpression.isArrayType) {
                        writePunctuation("[");
                        writePunctuation("]");
                    }
                    writePunctuation("}");
                }
            }
            if (tag.fullName) {
                writeSpace();
                emit(tag.fullName);
            }
            emitJSDocComment(tag.comment);
            if (tag.typeExpression && tag.typeExpression.kind === 304 /* JSDocTypeLiteral */) {
                emitJSDocTypeLiteral(tag.typeExpression);
            }
        }
        function emitJSDocCallbackTag(tag) {
            emitJSDocTagName(tag.tagName);
            if (tag.name) {
                writeSpace();
                emit(tag.name);
            }
            emitJSDocComment(tag.comment);
            emitJSDocSignature(tag.typeExpression);
        }
        function emitJSDocSimpleTag(tag) {
            emitJSDocTagName(tag.tagName);
            emitJSDocComment(tag.comment);
        }
        function emitJSDocTypeLiteral(lit) {
            emitList(lit, ts.createNodeArray(lit.jsDocPropertyTags), 33 /* JSDocComment */);
        }
        function emitJSDocSignature(sig) {
            if (sig.typeParameters) {
                emitList(sig, ts.createNodeArray(sig.typeParameters), 33 /* JSDocComment */);
            }
            if (sig.parameters) {
                emitList(sig, ts.createNodeArray(sig.parameters), 33 /* JSDocComment */);
            }
            if (sig.type) {
                writeLine();
                writeSpace();
                writePunctuation("*");
                writeSpace();
                emit(sig.type);
            }
        }
        function emitJSDocPropertyLikeTag(param) {
            emitJSDocTagName(param.tagName);
            emitJSDocTypeExpression(param.typeExpression);
            writeSpace();
            if (param.isBracketed) {
                writePunctuation("[");
            }
            emit(param.name);
            if (param.isBracketed) {
                writePunctuation("]");
            }
            emitJSDocComment(param.comment);
        }
        function emitJSDocTagName(tagName) {
            writePunctuation("@");
            emit(tagName);
        }
        function emitJSDocComment(comment) {
            if (comment) {
                writeSpace();
                write(comment);
            }
        }
        function emitJSDocTypeExpression(typeExpression) {
            if (typeExpression) {
                writeSpace();
                writePunctuation("{");
                emit(typeExpression.type);
                writePunctuation("}");
            }
        }
        //
        // Top-level nodes
        //
        function emitSourceFile(node) {
            writeLine();
            var statements = node.statements;
            if (emitBodyWithDetachedComments) {
                // Emit detached comment if there are no prologue directives or if the first node is synthesized.
                // The synthesized node will have no leading comment so some comments may be missed.
                var shouldEmitDetachedComment = statements.length === 0 ||
                    !ts.isPrologueDirective(statements[0]) ||
                    ts.nodeIsSynthesized(statements[0]);
                if (shouldEmitDetachedComment) {
                    emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
                    return;
                }
            }
            emitSourceFileWorker(node);
        }
        function emitSyntheticTripleSlashReferencesIfNeeded(node) {
            emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || [], node.syntheticLibReferences || []);
            for (var _a = 0, _b = node.prepends; _a < _b.length; _a++) {
                var prepend = _b[_a];
                if (ts.isUnparsedSource(prepend) && prepend.syntheticReferences) {
                    for (var _c = 0, _d = prepend.syntheticReferences; _c < _d.length; _c++) {
                        var ref = _d[_c];
                        emit(ref);
                        writeLine();
                    }
                }
            }
        }
        function emitTripleSlashDirectivesIfNeeded(node) {
            if (node.isDeclarationFile)
                emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives);
        }
        function emitTripleSlashDirectives(hasNoDefaultLib, files, types, libs) {
            if (hasNoDefaultLib) {
                var pos = writer.getTextPos();
                writeComment("/// <reference no-default-lib=\"true\"/>");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "no-default-lib" /* NoDefaultLib */ });
                writeLine();
            }
            if (currentSourceFile && currentSourceFile.moduleName) {
                writeComment("/// <amd-module name=\"" + currentSourceFile.moduleName + "\" />");
                writeLine();
            }
            if (currentSourceFile && currentSourceFile.amdDependencies) {
                for (var _a = 0, _b = currentSourceFile.amdDependencies; _a < _b.length; _a++) {
                    var dep = _b[_a];
                    if (dep.name) {
                        writeComment("/// <amd-dependency name=\"" + dep.name + "\" path=\"" + dep.path + "\" />");
                    }
                    else {
                        writeComment("/// <amd-dependency path=\"" + dep.path + "\" />");
                    }
                    writeLine();
                }
            }
            for (var _c = 0, files_1 = files; _c < files_1.length; _c++) {
                var directive = files_1[_c];
                var pos = writer.getTextPos();
                writeComment("/// <reference path=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "reference" /* Reference */, data: directive.fileName });
                writeLine();
            }
            for (var _d = 0, types_22 = types; _d < types_22.length; _d++) {
                var directive = types_22[_d];
                var pos = writer.getTextPos();
                writeComment("/// <reference types=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "type" /* Type */, data: directive.fileName });
                writeLine();
            }
            for (var _e = 0, libs_1 = libs; _e < libs_1.length; _e++) {
                var directive = libs_1[_e];
                var pos = writer.getTextPos();
                writeComment("/// <reference lib=\"" + directive.fileName + "\" />");
                if (bundleFileInfo)
                    bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "lib" /* Lib */, data: directive.fileName });
                writeLine();
            }
        }
        function emitSourceFileWorker(node) {
            var statements = node.statements;
            pushNameGenerationScope(node);
            ts.forEach(node.statements, generateNames);
            emitHelpers(node);
            var index = ts.findIndex(statements, function (statement) { return !ts.isPrologueDirective(statement); });
            emitTripleSlashDirectivesIfNeeded(node);
            emitList(node, statements, 1 /* MultiLine */, index === -1 ? statements.length : index);
            popNameGenerationScope(node);
        }
        // Transformation nodes
        function emitPartiallyEmittedExpression(node) {
            emitExpression(node.expression);
        }
        function emitCommaList(node) {
            emitExpressionList(node, node.elements, 528 /* CommaListElements */);
        }
        /**
         * Emits any prologue directives at the start of a Statement list, returning the
         * number of prologue directives written to the output.
         */
        function emitPrologueDirectives(statements, sourceFile, seenPrologueDirectives, recordBundleFileSection) {
            var needsToSetSourceFile = !!sourceFile;
            for (var i = 0; i < statements.length; i++) {
                var statement = statements[i];
                if (ts.isPrologueDirective(statement)) {
                    var shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true;
                    if (shouldEmitPrologueDirective) {
                        if (needsToSetSourceFile) {
                            needsToSetSourceFile = false;
                            setSourceFile(sourceFile);
                        }
                        writeLine();
                        var pos = writer.getTextPos();
                        emit(statement);
                        if (recordBundleFileSection && bundleFileInfo)
                            bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "prologue" /* Prologue */, data: statement.expression.text });
                        if (seenPrologueDirectives) {
                            seenPrologueDirectives.set(statement.expression.text, true);
                        }
                    }
                }
                else {
                    // return index of the first non prologue directive
                    return i;
                }
            }
            return statements.length;
        }
        function emitUnparsedPrologues(prologues, seenPrologueDirectives) {
            for (var _a = 0, prologues_1 = prologues; _a < prologues_1.length; _a++) {
                var prologue = prologues_1[_a];
                if (!seenPrologueDirectives.has(prologue.data)) {
                    writeLine();
                    var pos = writer.getTextPos();
                    emit(prologue);
                    if (bundleFileInfo)
                        bundleFileInfo.sections.push({ pos: pos, end: writer.getTextPos(), kind: "prologue" /* Prologue */, data: prologue.data });
                    if (seenPrologueDirectives) {
                        seenPrologueDirectives.set(prologue.data, true);
                    }
                }
            }
        }
        function emitPrologueDirectivesIfNeeded(sourceFileOrBundle) {
            if (ts.isSourceFile(sourceFileOrBundle)) {
                emitPrologueDirectives(sourceFileOrBundle.statements, sourceFileOrBundle);
            }
            else {
                var seenPrologueDirectives = ts.createMap();
                for (var _a = 0, _b = sourceFileOrBundle.prepends; _a < _b.length; _a++) {
                    var prepend = _b[_a];
                    emitUnparsedPrologues(prepend.prologues, seenPrologueDirectives);
                }
                for (var _c = 0, _d = sourceFileOrBundle.sourceFiles; _c < _d.length; _c++) {
                    var sourceFile = _d[_c];
                    emitPrologueDirectives(sourceFile.statements, sourceFile, seenPrologueDirectives, /*recordBundleFileSection*/ true);
                }
                setSourceFile(undefined);
            }
        }
        function getPrologueDirectivesFromBundledSourceFiles(bundle) {
            var seenPrologueDirectives = ts.createMap();
            var prologues;
            for (var index = 0; index < bundle.sourceFiles.length; index++) {
                var sourceFile = bundle.sourceFiles[index];
                var directives = void 0;
                var end = 0;
                for (var _a = 0, _b = sourceFile.statements; _a < _b.length; _a++) {
                    var statement = _b[_a];
                    if (!ts.isPrologueDirective(statement))
                        break;
                    if (seenPrologueDirectives.has(statement.expression.text))
                        continue;
                    seenPrologueDirectives.set(statement.expression.text, true);
                    (directives || (directives = [])).push({
                        pos: statement.pos,
                        end: statement.end,
                        expression: {
                            pos: statement.expression.pos,
                            end: statement.expression.end,
                            text: statement.expression.text
                        }
                    });
                    end = end < statement.end ? statement.end : end;
                }
                if (directives)
                    (prologues || (prologues = [])).push({ file: index, text: sourceFile.text.substring(0, end), directives: directives });
            }
            return prologues;
        }
        function emitShebangIfNeeded(sourceFileOrBundle) {
            if (ts.isSourceFile(sourceFileOrBundle) || ts.isUnparsedSource(sourceFileOrBundle)) {
                var shebang = ts.getShebang(sourceFileOrBundle.text);
                if (shebang) {
                    writeComment(shebang);
                    writeLine();
                    return true;
                }
            }
            else {
                for (var _a = 0, _b = sourceFileOrBundle.prepends; _a < _b.length; _a++) {
                    var prepend = _b[_a];
                    ts.Debug.assertNode(prepend, ts.isUnparsedSource);
                    if (emitShebangIfNeeded(prepend)) {
                        return true;
                    }
                }
                for (var _c = 0, _d = sourceFileOrBundle.sourceFiles; _c < _d.length; _c++) {
                    var sourceFile = _d[_c];
                    // Emit only the first encountered shebang
                    if (emitShebangIfNeeded(sourceFile)) {
                        return true;
                    }
                }
            }
        }
        //
        // Helpers
        //
        function emitNodeWithWriter(node, writer) {
            if (!node)
                return;
            var savedWrite = write;
            write = writer;
            emit(node);
            write = savedWrite;
        }
        function emitModifiers(node, modifiers) {
            if (modifiers && modifiers.length) {
                emitList(node, modifiers, 262656 /* Modifiers */);
                writeSpace();
            }
        }
        function emitTypeAnnotation(node) {
            if (node) {
                writePunctuation(":");
                writeSpace();
                emit(node);
            }
        }
        function emitInitializer(node, equalCommentStartPos, container) {
            if (node) {
                writeSpace();
                emitTokenWithComment(62 /* EqualsToken */, equalCommentStartPos, writeOperator, container);
                writeSpace();
                emitExpression(node);
            }
        }
        function emitNodeWithPrefix(prefix, prefixWriter, node, emit) {
            if (node) {
                prefixWriter(prefix);
                emit(node);
            }
        }
        function emitWithLeadingSpace(node) {
            if (node) {
                writeSpace();
                emit(node);
            }
        }
        function emitExpressionWithLeadingSpace(node) {
            if (node) {
                writeSpace();
                emitExpression(node);
            }
        }
        function emitWithTrailingSpace(node) {
            if (node) {
                emit(node);
                writeSpace();
            }
        }
        function emitEmbeddedStatement(parent, node) {
            if (ts.isBlock(node) || ts.getEmitFlags(parent) & 1 /* SingleLine */) {
                writeSpace();
                emit(node);
            }
            else {
                writeLine();
                increaseIndent();
                if (ts.isEmptyStatement(node)) {
                    pipelineEmit(5 /* EmbeddedStatement */, node);
                }
                else {
                    emit(node);
                }
                decreaseIndent();
            }
        }
        function emitDecorators(parentNode, decorators) {
            emitList(parentNode, decorators, 2146305 /* Decorators */);
        }
        function emitTypeArguments(parentNode, typeArguments) {
            emitList(parentNode, typeArguments, 53776 /* TypeArguments */);
        }
        function emitTypeParameters(parentNode, typeParameters) {
            if (ts.isFunctionLike(parentNode) && parentNode.typeArguments) { // Quick info uses type arguments in place of type parameters on instantiated signatures
                return emitTypeArguments(parentNode, parentNode.typeArguments);
            }
            emitList(parentNode, typeParameters, 53776 /* TypeParameters */);
        }
        function emitParameters(parentNode, parameters) {
            emitList(parentNode, parameters, 2576 /* Parameters */);
        }
        function canEmitSimpleArrowHead(parentNode, parameters) {
            var parameter = ts.singleOrUndefined(parameters);
            return parameter
                && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
                && ts.isArrowFunction(parentNode) // only arrow functions may have simple arrow head
                && !parentNode.type // arrow function may not have return type annotation
                && !ts.some(parentNode.decorators) // parent may not have decorators
                && !ts.some(parentNode.modifiers) // parent may not have modifiers
                && !ts.some(parentNode.typeParameters) // parent may not have type parameters
                && !ts.some(parameter.decorators) // parameter may not have decorators
                && !ts.some(parameter.modifiers) // parameter may not have modifiers
                && !parameter.dotDotDotToken // parameter may not be rest
                && !parameter.questionToken // parameter may not be optional
                && !parameter.type // parameter may not have a type annotation
                && !parameter.initializer // parameter may not have an initializer
                && ts.isIdentifier(parameter.name); // parameter name must be identifier
        }
        function emitParametersForArrow(parentNode, parameters) {
            if (canEmitSimpleArrowHead(parentNode, parameters)) {
                emitList(parentNode, parameters, 2576 /* Parameters */ & ~2048 /* Parenthesis */);
            }
            else {
                emitParameters(parentNode, parameters);
            }
        }
        function emitParametersForIndexSignature(parentNode, parameters) {
            emitList(parentNode, parameters, 8848 /* IndexSignatureParameters */);
        }
        function emitList(parentNode, children, format, start, count) {
            emitNodeList(emit, parentNode, children, format, start, count);
        }
        function emitExpressionList(parentNode, children, format, start, count) {
            emitNodeList(emitExpression, parentNode, children, format, start, count); // TODO: GH#18217
        }
        function writeDelimiter(format) {
            switch (format & 60 /* DelimitersMask */) {
                case 0 /* None */:
                    break;
                case 16 /* CommaDelimited */:
                    writePunctuation(",");
                    break;
                case 4 /* BarDelimited */:
                    writeSpace();
                    writePunctuation("|");
                    break;
                case 32 /* AsteriskDelimited */:
                    writeSpace();
                    writePunctuation("*");
                    writeSpace();
                    break;
                case 8 /* AmpersandDelimited */:
                    writeSpace();
                    writePunctuation("&");
                    break;
            }
        }
        function emitNodeList(emit, parentNode, children, format, start, count) {
            if (start === void 0) { start = 0; }
            if (count === void 0) { count = children ? children.length - start : 0; }
            var isUndefined = children === undefined;
            if (isUndefined && format & 16384 /* OptionalIfUndefined */) {
                return;
            }
            var isEmpty = children === undefined || start >= children.length || count === 0;
            if (isEmpty && format & 32768 /* OptionalIfEmpty */) {
                if (onBeforeEmitNodeArray) {
                    onBeforeEmitNodeArray(children);
                }
                if (onAfterEmitNodeArray) {
                    onAfterEmitNodeArray(children);
                }
                return;
            }
            if (format & 15360 /* BracketsMask */) {
                writePunctuation(getOpeningBracket(format));
                if (isEmpty && !isUndefined) {
                    // TODO: GH#18217
                    emitTrailingCommentsOfPosition(children.pos, /*prefixSpace*/ true); // Emit comments within empty bracketed lists
                }
            }
            if (onBeforeEmitNodeArray) {
                onBeforeEmitNodeArray(children);
            }
            if (isEmpty) {
                // Write a line terminator if the parent node was multi-line
                if (format & 1 /* MultiLine */ && !(preserveSourceNewlines && ts.rangeIsOnSingleLine(parentNode, currentSourceFile))) {
                    writeLine();
                }
                else if (format & 256 /* SpaceBetweenBraces */ && !(format & 524288 /* NoSpaceIfEmpty */)) {
                    writeSpace();
                }
            }
            else {
                // Write the opening line terminator or leading whitespace.
                var mayEmitInterveningComments = (format & 262144 /* NoInterveningComments */) === 0;
                var shouldEmitInterveningComments = mayEmitInterveningComments;
                var leadingLineTerminatorCount = getLeadingLineTerminatorCount(parentNode, children, format); // TODO: GH#18217
                if (leadingLineTerminatorCount) {
                    writeLine(leadingLineTerminatorCount);
                    shouldEmitInterveningComments = false;
                }
                else if (format & 256 /* SpaceBetweenBraces */) {
                    writeSpace();
                }
                // Increase the indent, if requested.
                if (format & 128 /* Indented */) {
                    increaseIndent();
                }
                // Emit each child.
                var previousSibling = void 0;
                var previousSourceFileTextKind = void 0;
                var shouldDecreaseIndentAfterEmit = false;
                for (var i = 0; i < count; i++) {
                    var child = children[start + i];
                    // Write the delimiter if this is not the first node.
                    if (format & 32 /* AsteriskDelimited */) {
                        // always write JSDoc in the format "\n *"
                        writeLine();
                        writeDelimiter(format);
                    }
                    else if (previousSibling) {
                        // i.e
                        //      function commentedParameters(
                        //          /* Parameter a */
                        //          a
                        //          /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline
                        //          ,
                        if (format & 60 /* DelimitersMask */ && previousSibling.end !== parentNode.end) {
                            emitLeadingCommentsOfPosition(previousSibling.end);
                        }
                        writeDelimiter(format);
                        recordBundleFileInternalSectionEnd(previousSourceFileTextKind);
                        // Write either a line terminator or whitespace to separate the elements.
                        var separatingLineTerminatorCount = getSeparatingLineTerminatorCount(previousSibling, child, format);
                        if (separatingLineTerminatorCount > 0) {
                            // If a synthesized node in a single-line list starts on a new
                            // line, we should increase the indent.
                            if ((format & (3 /* LinesMask */ | 128 /* Indented */)) === 0 /* SingleLine */) {
                                increaseIndent();
                                shouldDecreaseIndentAfterEmit = true;
                            }
                            writeLine(separatingLineTerminatorCount);
                            shouldEmitInterveningComments = false;
                        }
                        else if (previousSibling && format & 512 /* SpaceBetweenSiblings */) {
                            writeSpace();
                        }
                    }
                    // Emit this child.
                    previousSourceFileTextKind = recordBundleFileInternalSectionStart(child);
                    if (shouldEmitInterveningComments) {
                        if (emitTrailingCommentsOfPosition) {
                            var commentRange = ts.getCommentRange(child);
                            emitTrailingCommentsOfPosition(commentRange.pos);
                        }
                    }
                    else {
                        shouldEmitInterveningComments = mayEmitInterveningComments;
                    }
                    emit(child);
                    if (shouldDecreaseIndentAfterEmit) {
                        decreaseIndent();
                        shouldDecreaseIndentAfterEmit = false;
                    }
                    previousSibling = child;
                }
                // Write a trailing comma, if requested.
                var hasTrailingComma = (format & 64 /* AllowTrailingComma */) && children.hasTrailingComma;
                if (format & 16 /* CommaDelimited */ && hasTrailingComma) {
                    writePunctuation(",");
                }
                // Emit any trailing comment of the last element in the list
                // i.e
                //       var array = [...
                //          2
                //          /* end of element 2 */
                //       ];
                if (previousSibling && format & 60 /* DelimitersMask */ && previousSibling.end !== parentNode.end && !(ts.getEmitFlags(previousSibling) & 1024 /* NoTrailingComments */)) {
                    emitLeadingCommentsOfPosition(previousSibling.end);
                }
                // Decrease the indent, if requested.
                if (format & 128 /* Indented */) {
                    decreaseIndent();
                }
                recordBundleFileInternalSectionEnd(previousSourceFileTextKind);
                // Write the closing line terminator or closing whitespace.
                var closingLineTerminatorCount = getClosingLineTerminatorCount(parentNode, children, format);
                if (closingLineTerminatorCount) {
                    writeLine(closingLineTerminatorCount);
                }
                else if (format & (2097152 /* SpaceAfterList */ | 256 /* SpaceBetweenBraces */)) {
                    writeSpace();
                }
            }
            if (onAfterEmitNodeArray) {
                onAfterEmitNodeArray(children);
            }
            if (format & 15360 /* BracketsMask */) {
                if (isEmpty && !isUndefined) {
                    // TODO: GH#18217
                    emitLeadingCommentsOfPosition(children.end); // Emit leading comments within empty lists
                }
                writePunctuation(getClosingBracket(format));
            }
        }
        // Writers
        function writeLiteral(s) {
            writer.writeLiteral(s);
        }
        function writeStringLiteral(s) {
            writer.writeStringLiteral(s);
        }
        function writeBase(s) {
            writer.write(s);
        }
        function writeSymbol(s, sym) {
            writer.writeSymbol(s, sym);
        }
        function writePunctuation(s) {
            writer.writePunctuation(s);
        }
        function writeTrailingSemicolon() {
            writer.writeTrailingSemicolon(";");
        }
        function writeKeyword(s) {
            writer.writeKeyword(s);
        }
        function writeOperator(s) {
            writer.writeOperator(s);
        }
        function writeParameter(s) {
            writer.writeParameter(s);
        }
        function writeComment(s) {
            writer.writeComment(s);
        }
        function writeSpace() {
            writer.writeSpace(" ");
        }
        function writeProperty(s) {
            writer.writeProperty(s);
        }
        function writeLine(count) {
            if (count === void 0) { count = 1; }
            for (var i = 0; i < count; i++) {
                writer.writeLine(i > 0);
            }
        }
        function increaseIndent() {
            writer.increaseIndent();
        }
        function decreaseIndent() {
            writer.decreaseIndent();
        }
        function writeToken(token, pos, writer, contextNode) {
            return !sourceMapsDisabled
                ? emitTokenWithSourceMap(contextNode, token, writer, pos, writeTokenText)
                : writeTokenText(token, writer, pos);
        }
        function writeTokenNode(node, writer) {
            if (onBeforeEmitToken) {
                onBeforeEmitToken(node);
            }
            writer(ts.tokenToString(node.kind));
            if (onAfterEmitToken) {
                onAfterEmitToken(node);
            }
        }
        function writeTokenText(token, writer, pos) {
            var tokenString = ts.tokenToString(token);
            writer(tokenString);
            return pos < 0 ? pos : pos + tokenString.length;
        }
        function writeLineOrSpace(node) {
            if (ts.getEmitFlags(node) & 1 /* SingleLine */) {
                writeSpace();
            }
            else {
                writeLine();
            }
        }
        function writeLines(text) {
            var lines = text.split(/\r\n?|\n/g);
            var indentation = ts.guessIndentation(lines);
            for (var _a = 0, lines_3 = lines; _a < lines_3.length; _a++) {
                var lineText = lines_3[_a];
                var line = indentation ? lineText.slice(indentation) : lineText;
                if (line.length) {
                    writeLine();
                    write(line);
                }
            }
        }
        function writeLinesAndIndent(lineCount, writeSpaceIfNotIndenting) {
            if (lineCount) {
                increaseIndent();
                writeLine(lineCount);
            }
            else if (writeSpaceIfNotIndenting) {
                writeSpace();
            }
        }
        // Helper function to decrease the indent if we previously indented.  Allows multiple
        // previous indent values to be considered at a time.  This also allows caller to just
        // call this once, passing in all their appropriate indent values, instead of needing
        // to call this helper function multiple times.
        function decreaseIndentIf(value1, value2) {
            if (value1) {
                decreaseIndent();
            }
            if (value2) {
                decreaseIndent();
            }
        }
        function getLeadingLineTerminatorCount(parentNode, children, format) {
            if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
                if (format & 65536 /* PreferNewLine */) {
                    return 1;
                }
                var firstChild_1 = children[0];
                if (firstChild_1 === undefined) {
                    return ts.rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
                }
                if (firstChild_1.kind === 11 /* JsxText */) {
                    // JsxText will be written with its leading whitespace, so don't add more manually.
                    return 0;
                }
                if (!ts.positionIsSynthesized(parentNode.pos) && !ts.nodeIsSynthesized(firstChild_1) && (!firstChild_1.parent || firstChild_1.parent === parentNode)) {
                    if (preserveSourceNewlines) {
                        return getEffectiveLines(function (includeComments) { return ts.getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(firstChild_1.pos, parentNode.pos, currentSourceFile, includeComments); });
                    }
                    return ts.rangeStartPositionsAreOnSameLine(parentNode, firstChild_1, currentSourceFile) ? 0 : 1;
                }
                if (synthesizedNodeStartsOnNewLine(firstChild_1, format)) {
                    return 1;
                }
            }
            return format & 1 /* MultiLine */ ? 1 : 0;
        }
        function getSeparatingLineTerminatorCount(previousNode, nextNode, format) {
            if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
                if (previousNode === undefined || nextNode === undefined) {
                    return 0;
                }
                if (nextNode.kind === 11 /* JsxText */) {
                    // JsxText will be written with its leading whitespace, so don't add more manually.
                    return 0;
                }
                else if (!ts.nodeIsSynthesized(previousNode) && !ts.nodeIsSynthesized(nextNode) && previousNode.parent === nextNode.parent) {
                    if (preserveSourceNewlines) {
                        return getEffectiveLines(function (includeComments) { return ts.getLinesBetweenRangeEndAndRangeStart(previousNode, nextNode, currentSourceFile, includeComments); });
                    }
                    return ts.rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile) ? 0 : 1;
                }
                else if (synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format)) {
                    return 1;
                }
            }
            else if (ts.getStartsOnNewLine(nextNode)) {
                return 1;
            }
            return format & 1 /* MultiLine */ ? 1 : 0;
        }
        function getClosingLineTerminatorCount(parentNode, children, format) {
            if (format & 2 /* PreserveLines */ || preserveSourceNewlines) {
                if (format & 65536 /* PreferNewLine */) {
                    return 1;
                }
                var lastChild_1 = ts.lastOrUndefined(children);
                if (lastChild_1 === undefined) {
                    return ts.rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
                }
                if (!ts.positionIsSynthesized(parentNode.pos) && !ts.nodeIsSynthesized(lastChild_1) && (!lastChild_1.parent || lastChild_1.parent === parentNode)) {
                    if (preserveSourceNewlines) {
                        return getEffectiveLines(function (includeComments) { return ts.getLinesBetweenPositionAndNextNonWhitespaceCharacter(lastChild_1.end, parentNode.end, currentSourceFile, includeComments); });
                    }
                    return ts.rangeEndPositionsAreOnSameLine(parentNode, lastChild_1, currentSourceFile) ? 0 : 1;
                }
                if (synthesizedNodeStartsOnNewLine(lastChild_1, format)) {
                    return 1;
                }
            }
            if (format & 1 /* MultiLine */ && !(format & 131072 /* NoTrailingNewLine */)) {
                return 1;
            }
            return 0;
        }
        function getEffectiveLines(getLineDifference) {
            // If 'preserveSourceNewlines' is disabled, we should never call this function
            // because it could be more expensive than alternative approximations.
            ts.Debug.assert(!!preserveSourceNewlines);
            // We start by measuring the line difference from a position to its adjacent comments,
            // so that this is counted as a one-line difference, not two:
            //
            //   node1;
            //   // NODE2 COMMENT
            //   node2;
            var lines = getLineDifference(/*includeComments*/ true);
            if (lines === 0) {
                // However, if the line difference considering comments was 0, we might have this:
                //
                //   node1; // NODE2 COMMENT
                //   node2;
                //
                // in which case we should be ignoring node2's comment, so this too is counted as
                // a one-line difference, not zero.
                return getLineDifference(/*includeComments*/ false);
            }
            return lines;
        }
        function writeLineSeparatorsAndIndentBefore(node, parent) {
            var leadingNewlines = preserveSourceNewlines && getLeadingLineTerminatorCount(parent, [node], 0 /* None */);
            if (leadingNewlines) {
                writeLinesAndIndent(leadingNewlines, /*writeLinesIfNotIndenting*/ false);
            }
            return !!leadingNewlines;
        }
        function writeLineSeparatorsAfter(node, parent) {
            var trailingNewlines = preserveSourceNewlines && getClosingLineTerminatorCount(parent, [node], 0 /* None */);
            if (trailingNewlines) {
                writeLine(trailingNewlines);
            }
        }
        function synthesizedNodeStartsOnNewLine(node, format) {
            if (ts.nodeIsSynthesized(node)) {
                var startsOnNewLine = ts.getStartsOnNewLine(node);
                if (startsOnNewLine === undefined) {
                    return (format & 65536 /* PreferNewLine */) !== 0;
                }
                return startsOnNewLine;
            }
            return (format & 65536 /* PreferNewLine */) !== 0;
        }
        function getLinesBetweenNodes(parent, node1, node2) {
            if (ts.getEmitFlags(parent) & 131072 /* NoIndentation */) {
                return 0;
            }
            parent = skipSynthesizedParentheses(parent);
            node1 = skipSynthesizedParentheses(node1);
            node2 = skipSynthesizedParentheses(node2);
            // Always use a newline for synthesized code if the synthesizer desires it.
            if (ts.getStartsOnNewLine(node2)) {
                return 1;
            }
            if (!ts.nodeIsSynthesized(parent) && !ts.nodeIsSynthesized(node1) && !ts.nodeIsSynthesized(node2)) {
                if (preserveSourceNewlines) {
                    return getEffectiveLines(function (includeComments) { return ts.getLinesBetweenRangeEndAndRangeStart(node1, node2, currentSourceFile, includeComments); });
                }
                return ts.rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile) ? 0 : 1;
            }
            return 0;
        }
        function isEmptyBlock(block) {
            return block.statements.length === 0
                && ts.rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile);
        }
        function skipSynthesizedParentheses(node) {
            while (node.kind === 200 /* ParenthesizedExpression */ && ts.nodeIsSynthesized(node)) {
                node = node.expression;
            }
            return node;
        }
        function getTextOfNode(node, includeTrivia) {
            if (ts.isGeneratedIdentifier(node)) {
                return generateName(node);
            }
            else if ((ts.isIdentifier(node) || ts.isPrivateIdentifier(node)) && (ts.nodeIsSynthesized(node) || !node.parent || !currentSourceFile || (node.parent && currentSourceFile && ts.getSourceFileOfNode(node) !== ts.getOriginalNode(currentSourceFile)))) {
                return ts.idText(node);
            }
            else if (node.kind === 10 /* StringLiteral */ && node.textSourceNode) {
                return getTextOfNode(node.textSourceNode, includeTrivia);
            }
            else if (ts.isLiteralExpression(node) && (ts.nodeIsSynthesized(node) || !node.parent)) {
                return node.text;
            }
            return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
        }
        function getLiteralTextOfNode(node, neverAsciiEscape, jsxAttributeEscape) {
            if (node.kind === 10 /* StringLiteral */ && node.textSourceNode) {
                var textSourceNode = node.textSourceNode;
                if (ts.isIdentifier(textSourceNode)) {
                    return jsxAttributeEscape ? "\"" + ts.escapeJsxAttributeString(getTextOfNode(textSourceNode)) + "\"" :
                        neverAsciiEscape || (ts.getEmitFlags(node) & 16777216 /* NoAsciiEscaping */) ? "\"" + ts.escapeString(getTextOfNode(textSourceNode)) + "\"" :
                            "\"" + ts.escapeNonAsciiString(getTextOfNode(textSourceNode)) + "\"";
                }
                else {
                    return getLiteralTextOfNode(textSourceNode, neverAsciiEscape, jsxAttributeEscape);
                }
            }
            return ts.getLiteralText(node, currentSourceFile, neverAsciiEscape, jsxAttributeEscape);
        }
        /**
         * Push a new name generation scope.
         */
        function pushNameGenerationScope(node) {
            if (node && ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                return;
            }
            tempFlagsStack.push(tempFlags);
            tempFlags = 0;
            reservedNamesStack.push(reservedNames);
        }
        /**
         * Pop the current name generation scope.
         */
        function popNameGenerationScope(node) {
            if (node && ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                return;
            }
            tempFlags = tempFlagsStack.pop();
            reservedNames = reservedNamesStack.pop();
        }
        function reserveNameInNestedScopes(name) {
            if (!reservedNames || reservedNames === ts.lastOrUndefined(reservedNamesStack)) {
                reservedNames = ts.createMap();
            }
            reservedNames.set(name, true);
        }
        function generateNames(node) {
            if (!node)
                return;
            switch (node.kind) {
                case 223 /* Block */:
                    ts.forEach(node.statements, generateNames);
                    break;
                case 238 /* LabeledStatement */:
                case 236 /* WithStatement */:
                case 228 /* DoStatement */:
                case 229 /* WhileStatement */:
                    generateNames(node.statement);
                    break;
                case 227 /* IfStatement */:
                    generateNames(node.thenStatement);
                    generateNames(node.elseStatement);
                    break;
                case 230 /* ForStatement */:
                case 232 /* ForOfStatement */:
                case 231 /* ForInStatement */:
                    generateNames(node.initializer);
                    generateNames(node.statement);
                    break;
                case 237 /* SwitchStatement */:
                    generateNames(node.caseBlock);
                    break;
                case 251 /* CaseBlock */:
                    ts.forEach(node.clauses, generateNames);
                    break;
                case 277 /* CaseClause */:
                case 278 /* DefaultClause */:
                    ts.forEach(node.statements, generateNames);
                    break;
                case 240 /* TryStatement */:
                    generateNames(node.tryBlock);
                    generateNames(node.catchClause);
                    generateNames(node.finallyBlock);
                    break;
                case 280 /* CatchClause */:
                    generateNames(node.variableDeclaration);
                    generateNames(node.block);
                    break;
                case 225 /* VariableStatement */:
                    generateNames(node.declarationList);
                    break;
                case 243 /* VariableDeclarationList */:
                    ts.forEach(node.declarations, generateNames);
                    break;
                case 242 /* VariableDeclaration */:
                case 156 /* Parameter */:
                case 191 /* BindingElement */:
                case 245 /* ClassDeclaration */:
                    generateNameIfNeeded(node.name);
                    break;
                case 244 /* FunctionDeclaration */:
                    generateNameIfNeeded(node.name);
                    if (ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) {
                        ts.forEach(node.parameters, generateNames);
                        generateNames(node.body);
                    }
                    break;
                case 189 /* ObjectBindingPattern */:
                case 190 /* ArrayBindingPattern */:
                    ts.forEach(node.elements, generateNames);
                    break;
                case 254 /* ImportDeclaration */:
                    generateNames(node.importClause);
                    break;
                case 255 /* ImportClause */:
                    generateNameIfNeeded(node.name);
                    generateNames(node.namedBindings);
                    break;
                case 256 /* NamespaceImport */:
                    generateNameIfNeeded(node.name);
                    break;
                case 262 /* NamespaceExport */:
                    generateNameIfNeeded(node.name);
                    break;
                case 257 /* NamedImports */:
                    ts.forEach(node.elements, generateNames);
                    break;
                case 258 /* ImportSpecifier */:
                    generateNameIfNeeded(node.propertyName || node.name);
                    break;
            }
        }
        function generateMemberNames(node) {
            if (!node)
                return;
            switch (node.kind) {
                case 281 /* PropertyAssignment */:
                case 282 /* ShorthandPropertyAssignment */:
                case 159 /* PropertyDeclaration */:
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    generateNameIfNeeded(node.name);
                    break;
            }
        }
        function generateNameIfNeeded(name) {
            if (name) {
                if (ts.isGeneratedIdentifier(name)) {
                    generateName(name);
                }
                else if (ts.isBindingPattern(name)) {
                    generateNames(name);
                }
            }
        }
        /**
         * Generate the text for a generated identifier.
         */
        function generateName(name) {
            if ((name.autoGenerateFlags & 7 /* KindMask */) === 4 /* Node */) {
                // Node names generate unique names based on their original node
                // and are cached based on that node's id.
                return generateNameCached(getNodeForGeneratedName(name), name.autoGenerateFlags);
            }
            else {
                // Auto, Loop, and Unique names are cached based on their unique
                // autoGenerateId.
                var autoGenerateId = name.autoGenerateId;
                return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
            }
        }
        function generateNameCached(node, flags) {
            var nodeId = ts.getNodeId(node);
            return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node, flags));
        }
        /**
         * Returns a value indicating whether a name is unique globally, within the current file,
         * or within the NameGenerator.
         */
        function isUniqueName(name) {
            return isFileLevelUniqueName(name)
                && !generatedNames.has(name)
                && !(reservedNames && reservedNames.has(name));
        }
        /**
         * Returns a value indicating whether a name is unique globally or within the current file.
         */
        function isFileLevelUniqueName(name) {
            return currentSourceFile ? ts.isFileLevelUniqueName(currentSourceFile, name, hasGlobalName) : true;
        }
        /**
         * Returns a value indicating whether a name is unique within a container.
         */
        function isUniqueLocalName(name, container) {
            for (var node = container; ts.isNodeDescendantOf(node, container); node = node.nextContainer) {
                if (node.locals) {
                    var local = node.locals.get(ts.escapeLeadingUnderscores(name));
                    // We conservatively include alias symbols to cover cases where they're emitted as locals
                    if (local && local.flags & (111551 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */)) {
                        return false;
                    }
                }
            }
            return true;
        }
        /**
         * Return the next available name in the pattern _a ... _z, _0, _1, ...
         * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name.
         * Note that names generated by makeTempVariableName and makeUniqueName will never conflict.
         */
        function makeTempVariableName(flags, reservedInNestedScopes) {
            if (flags && !(tempFlags & flags)) {
                var name = flags === 268435456 /* _i */ ? "_i" : "_n";
                if (isUniqueName(name)) {
                    tempFlags |= flags;
                    if (reservedInNestedScopes) {
                        reserveNameInNestedScopes(name);
                    }
                    return name;
                }
            }
            while (true) {
                var count = tempFlags & 268435455 /* CountMask */;
                tempFlags++;
                // Skip over 'i' and 'n'
                if (count !== 8 && count !== 13) {
                    var name = count < 26
                        ? "_" + String.fromCharCode(97 /* a */ + count)
                        : "_" + (count - 26);
                    if (isUniqueName(name)) {
                        if (reservedInNestedScopes) {
                            reserveNameInNestedScopes(name);
                        }
                        return name;
                    }
                }
            }
        }
        /**
         * Generate a name that is unique within the current file and doesn't conflict with any names
         * in global scope. The name is formed by adding an '_n' suffix to the specified base name,
         * where n is a positive integer. Note that names generated by makeTempVariableName and
         * makeUniqueName are guaranteed to never conflict.
         * If `optimistic` is set, the first instance will use 'baseName' verbatim instead of 'baseName_1'
         */
        function makeUniqueName(baseName, checkFn, optimistic, scoped) {
            if (checkFn === void 0) { checkFn = isUniqueName; }
            if (optimistic) {
                if (checkFn(baseName)) {
                    if (scoped) {
                        reserveNameInNestedScopes(baseName);
                    }
                    else {
                        generatedNames.set(baseName, true);
                    }
                    return baseName;
                }
            }
            // Find the first unique 'name_n', where n is a positive number
            if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) {
                baseName += "_";
            }
            var i = 1;
            while (true) {
                var generatedName = baseName + i;
                if (checkFn(generatedName)) {
                    if (scoped) {
                        reserveNameInNestedScopes(generatedName);
                    }
                    else {
                        generatedNames.set(generatedName, true);
                    }
                    return generatedName;
                }
                i++;
            }
        }
        function makeFileLevelOptimisticUniqueName(name) {
            return makeUniqueName(name, isFileLevelUniqueName, /*optimistic*/ true);
        }
        /**
         * Generates a unique name for a ModuleDeclaration or EnumDeclaration.
         */
        function generateNameForModuleOrEnum(node) {
            var name = getTextOfNode(node.name);
            // Use module/enum name itself if it is unique, otherwise make a unique variation
            return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
        }
        /**
         * Generates a unique name for an ImportDeclaration or ExportDeclaration.
         */
        function generateNameForImportOrExportDeclaration(node) {
            var expr = ts.getExternalModuleName(node); // TODO: GH#18217
            var baseName = ts.isStringLiteral(expr) ?
                ts.makeIdentifierFromModuleName(expr.text) : "module";
            return makeUniqueName(baseName);
        }
        /**
         * Generates a unique name for a default export.
         */
        function generateNameForExportDefault() {
            return makeUniqueName("default");
        }
        /**
         * Generates a unique name for a class expression.
         */
        function generateNameForClassExpression() {
            return makeUniqueName("class");
        }
        function generateNameForMethodOrAccessor(node) {
            if (ts.isIdentifier(node.name)) {
                return generateNameCached(node.name);
            }
            return makeTempVariableName(0 /* Auto */);
        }
        /**
         * Generates a unique name from a node.
         */
        function generateNameForNode(node, flags) {
            switch (node.kind) {
                case 75 /* Identifier */:
                    return makeUniqueName(getTextOfNode(node), isUniqueName, !!(flags & 16 /* Optimistic */), !!(flags & 8 /* ReservedInNestedScopes */));
                case 249 /* ModuleDeclaration */:
                case 248 /* EnumDeclaration */:
                    return generateNameForModuleOrEnum(node);
                case 254 /* ImportDeclaration */:
                case 260 /* ExportDeclaration */:
                    return generateNameForImportOrExportDeclaration(node);
                case 244 /* FunctionDeclaration */:
                case 245 /* ClassDeclaration */:
                case 259 /* ExportAssignment */:
                    return generateNameForExportDefault();
                case 214 /* ClassExpression */:
                    return generateNameForClassExpression();
                case 161 /* MethodDeclaration */:
                case 163 /* GetAccessor */:
                case 164 /* SetAccessor */:
                    return generateNameForMethodOrAccessor(node);
                case 154 /* ComputedPropertyName */:
                    return makeTempVariableName(0 /* Auto */, /*reserveInNestedScopes*/ true);
                default:
                    return makeTempVariableName(0 /* Auto */);
            }
        }
        /**
         * Generates a unique identifier for a node.
         */
        function makeName(name) {
            switch (name.autoGenerateFlags & 7 /* KindMask */) {
                case 1 /* Auto */:
                    return makeTempVariableName(0 /* Auto */, !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
                case 2 /* Loop */:
                    return makeTempVariableName(268435456 /* _i */, !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
                case 3 /* Unique */:
                    return makeUniqueName(ts.idText(name), (name.autoGenerateFlags & 32 /* FileLevel */) ? isFileLevelUniqueName : isUniqueName, !!(name.autoGenerateFlags & 16 /* Optimistic */), !!(name.autoGenerateFlags & 8 /* ReservedInNestedScopes */));
            }
            return ts.Debug.fail("Unsupported GeneratedIdentifierKind.");
        }
        /**
         * Gets the node from which a name should be generated.
         */
        function getNodeForGeneratedName(name) {
            var autoGenerateId = name.autoGenerateId;
            var node = name;
            var original = node.original;
            while (original) {
                node = original;
                // if "node" is a different generated name (having a different
                // "autoGenerateId"), use it and stop traversing.
                if (ts.isIdentifier(node)
                    && !!(node.autoGenerateFlags & 4 /* Node */)
                    && node.autoGenerateId !== autoGenerateId) {
                    break;
                }
                original = node.original;
            }
            // otherwise, return the original node for the source;
            return node;
        }
        // Comments
        function pipelineEmitWithComments(hint, node) {
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
            enterComment();
            hasWrittenComment = false;
            var emitFlags = ts.getEmitFlags(node);
            var _a = ts.getCommentRange(node), pos = _a.pos, end = _a.end;
            var isEmittedNode = node.kind !== 325 /* NotEmittedStatement */;
            // We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation.
            // It is expensive to walk entire tree just to set one kind of node to have no comments.
            var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0 || node.kind === 11 /* JsxText */;
            var skipTrailingComments = end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0 || node.kind === 11 /* JsxText */;
            // Save current container state on the stack.
            var savedContainerPos = containerPos;
            var savedContainerEnd = containerEnd;
            var savedDeclarationListContainerEnd = declarationListContainerEnd;
            if ((pos > 0 || end > 0) && pos !== end) {
                // Emit leading comments if the position is not synthesized and the node
                // has not opted out from emitting leading comments.
                if (!skipLeadingComments) {
                    emitLeadingComments(pos, isEmittedNode);
                }
                if (!skipLeadingComments || (pos >= 0 && (emitFlags & 512 /* NoLeadingComments */) !== 0)) {
                    // Advance the container position if comments get emitted or if they've been disabled explicitly using NoLeadingComments.
                    containerPos = pos;
                }
                if (!skipTrailingComments || (end >= 0 && (emitFlags & 1024 /* NoTrailingComments */) !== 0)) {
                    // As above.
                    containerEnd = end;
                    // To avoid invalid comment emit in a down-level binding pattern, we
                    // keep track of the last declaration list container's end
                    if (node.kind === 243 /* VariableDeclarationList */) {
                        declarationListContainerEnd = end;
                    }
                }
            }
            ts.forEach(ts.getSyntheticLeadingComments(node), emitLeadingSynthesizedComment);
            exitComment();
            var pipelinePhase = getNextPipelinePhase(2 /* Comments */, hint, node);
            if (emitFlags & 2048 /* NoNestedComments */) {
                commentsDisabled = true;
                pipelinePhase(hint, node);
                commentsDisabled = false;
            }
            else {
                pipelinePhase(hint, node);
            }
            enterComment();
            ts.forEach(ts.getSyntheticTrailingComments(node), emitTrailingSynthesizedComment);
            if ((pos > 0 || end > 0) && pos !== end) {
                // Restore previous container state.
                containerPos = savedContainerPos;
                containerEnd = savedContainerEnd;
                declarationListContainerEnd = savedDeclarationListContainerEnd;
                // Emit trailing comments if the position is not synthesized and the node
                // has not opted out from emitting leading comments and is an emitted node.
                if (!skipTrailingComments && isEmittedNode) {
                    emitTrailingComments(end);
                }
            }
            exitComment();
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
        }
        function emitLeadingSynthesizedComment(comment) {
            if (comment.kind === 2 /* SingleLineCommentTrivia */) {
                writer.writeLine();
            }
            writeSynthesizedComment(comment);
            if (comment.hasTrailingNewLine || comment.kind === 2 /* SingleLineCommentTrivia */) {
                writer.writeLine();
            }
            else {
                writer.writeSpace(" ");
            }
        }
        function emitTrailingSynthesizedComment(comment) {
            if (!writer.isAtStartOfLine()) {
                writer.writeSpace(" ");
            }
            writeSynthesizedComment(comment);
            if (comment.hasTrailingNewLine) {
                writer.writeLine();
            }
        }
        function writeSynthesizedComment(comment) {
            var text = formatSynthesizedComment(comment);
            var lineMap = comment.kind === 3 /* MultiLineCommentTrivia */ ? ts.computeLineStarts(text) : undefined;
            ts.writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
        }
        function formatSynthesizedComment(comment) {
            return comment.kind === 3 /* MultiLineCommentTrivia */
                ? "/*" + comment.text + "*/"
                : "//" + comment.text;
        }
        function emitBodyWithDetachedComments(node, detachedRange, emitCallback) {
            enterComment();
            var pos = detachedRange.pos, end = detachedRange.end;
            var emitFlags = ts.getEmitFlags(node);
            var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0;
            var skipTrailingComments = commentsDisabled || end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0;
            if (!skipLeadingComments) {
                emitDetachedCommentsAndUpdateCommentsInfo(detachedRange);
            }
            exitComment();
            if (emitFlags & 2048 /* NoNestedComments */ && !commentsDisabled) {
                commentsDisabled = true;
                emitCallback(node);
                commentsDisabled = false;
            }
            else {
                emitCallback(node);
            }
            enterComment();
            if (!skipTrailingComments) {
                emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true);
                if (hasWrittenComment && !writer.isAtStartOfLine()) {
                    writer.writeLine();
                }
            }
            exitComment();
        }
        function emitLeadingComments(pos, isEmittedNode) {
            hasWrittenComment = false;
            if (isEmittedNode) {
                forEachLeadingCommentToEmit(pos, emitLeadingComment);
            }
            else if (pos === 0) {
                // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node,
                // unless it is a triple slash comment at the top of the file.
                // For Example:
                //      /// <reference-path ...>
                //      declare var x;
                //      /// <reference-path ...>
                //      interface F {}
                //  The first /// will NOT be removed while the second one will be removed even though both node will not be emitted
                forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment);
            }
        }
        function emitTripleSlashLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
            if (isTripleSlashComment(commentPos, commentEnd)) {
                emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos);
            }
        }
        function shouldWriteComment(text, pos) {
            if (printerOptions.onlyPrintJsDocStyle) {
                return (ts.isJSDocLikeText(text, pos) || ts.isPinnedComment(text, pos));
            }
            return true;
        }
        function emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            if (!hasWrittenComment) {
                ts.emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos);
                hasWrittenComment = true;
            }
            // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
            else if (kind === 3 /* MultiLineCommentTrivia */) {
                writer.writeSpace(" ");
            }
        }
        function emitLeadingCommentsOfPosition(pos) {
            if (commentsDisabled || pos === -1) {
                return;
            }
            emitLeadingComments(pos, /*isEmittedNode*/ true);
        }
        function emitTrailingComments(pos) {
            forEachTrailingCommentToEmit(pos, emitTrailingComment);
        }
        function emitTrailingComment(commentPos, commentEnd, _kind, hasTrailingNewLine) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
            if (!writer.isAtStartOfLine()) {
                writer.writeSpace(" ");
            }
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
        }
        function emitTrailingCommentsOfPosition(pos, prefixSpace) {
            if (commentsDisabled) {
                return;
            }
            enterComment();
            forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition);
            exitComment();
        }
        function emitTrailingCommentOfPosition(commentPos, commentEnd, _kind, hasTrailingNewLine) {
            // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
            emitPos(commentPos);
            ts.writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
            if (hasTrailingNewLine) {
                writer.writeLine();
            }
            else {
                writer.writeSpace(" ");
            }
        }
        function forEachLeadingCommentToEmit(pos, cb) {
            // Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments
            if (currentSourceFile && (containerPos === -1 || pos !== containerPos)) {
                if (hasDetachedComments(pos)) {
                    forEachLeadingCommentWithoutDetachedComments(cb);
                }
                else {
                    ts.forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
                }
            }
        }
        function forEachTrailingCommentToEmit(end, cb) {
            // Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments
            if (currentSourceFile && (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd))) {
                ts.forEachTrailingCommentRange(currentSourceFile.text, end, cb);
            }
        }
        function hasDetachedComments(pos) {
            return detachedCommentsInfo !== undefined && ts.last(detachedCommentsInfo).nodePos === pos;
        }
        function forEachLeadingCommentWithoutDetachedComments(cb) {
            // get the leading comments from detachedPos
            var pos = ts.last(detachedCommentsInfo).detachedCommentEndPos;
            if (detachedCommentsInfo.length - 1) {
                detachedCommentsInfo.pop();
            }
            else {
                detachedCommentsInfo = undefined;
            }
            ts.forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
        }
        function emitDetachedCommentsAndUpdateCommentsInfo(range) {
            var currentDetachedCommentInfo = ts.emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
            if (currentDetachedCommentInfo) {
                if (detachedCommentsInfo) {
                    detachedCommentsInfo.push(currentDetachedCommentInfo);
                }
                else {
                    detachedCommentsInfo = [currentDetachedCommentInfo];
                }
            }
        }
        function emitComment(text, lineMap, writer, commentPos, commentEnd, newLine) {
            if (!shouldWriteComment(currentSourceFile.text, commentPos))
                return;
            emitPos(commentPos);
            ts.writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
            emitPos(commentEnd);
        }
        /**
         * Determine if the given comment is a triple-slash
         *
         * @return true if the comment is a triple-slash comment else false
         */
        function isTripleSlashComment(commentPos, commentEnd) {
            return ts.isRecognizedTripleSlashComment(currentSourceFile.text, commentPos, commentEnd);
        }
        // Source Maps
        function getParsedSourceMap(node) {
            if (node.parsedSourceMap === undefined && node.sourceMapText !== undefined) {
                node.parsedSourceMap = ts.tryParseRawSourceMap(node.sourceMapText) || false;
            }
            return node.parsedSourceMap || undefined;
        }
        function pipelineEmitWithSourceMap(hint, node) {
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
            var pipelinePhase = getNextPipelinePhase(3 /* SourceMaps */, hint, node);
            if (ts.isUnparsedSource(node) || ts.isUnparsedPrepend(node)) {
                pipelinePhase(hint, node);
            }
            else if (ts.isUnparsedNode(node)) {
                var parsed = getParsedSourceMap(node.parent);
                if (parsed && sourceMapGenerator) {
                    sourceMapGenerator.appendSourceMap(writer.getLine(), writer.getColumn(), parsed, node.parent.sourceMapPath, node.parent.getLineAndCharacterOfPosition(node.pos), node.parent.getLineAndCharacterOfPosition(node.end));
                }
                pipelinePhase(hint, node);
            }
            else {
                var _a = ts.getSourceMapRange(node), pos = _a.pos, end = _a.end, _b = _a.source, source = _b === void 0 ? sourceMapSource : _b;
                var emitFlags = ts.getEmitFlags(node);
                if (node.kind !== 325 /* NotEmittedStatement */
                    && (emitFlags & 16 /* NoLeadingSourceMap */) === 0
                    && pos >= 0) {
                    emitSourcePos(source, skipSourceTrivia(source, pos));
                }
                if (emitFlags & 64 /* NoNestedSourceMaps */) {
                    sourceMapsDisabled = true;
                    pipelinePhase(hint, node);
                    sourceMapsDisabled = false;
                }
                else {
                    pipelinePhase(hint, node);
                }
                if (node.kind !== 325 /* NotEmittedStatement */
                    && (emitFlags & 32 /* NoTrailingSourceMap */) === 0
                    && end >= 0) {
                    emitSourcePos(source, end);
                }
            }
            ts.Debug.assert(lastNode === node || lastSubstitution === node);
        }
        /**
         * Skips trivia such as comments and white-space that can be optionally overridden by the source-map source
         */
        function skipSourceTrivia(source, pos) {
            return source.skipTrivia ? source.skipTrivia(pos) : ts.skipTrivia(source.text, pos);
        }
        /**
         * Emits a mapping.
         *
         * If the position is synthetic (undefined or a negative value), no mapping will be
         * created.
         *
         * @param pos The position.
         */
        function emitPos(pos) {
            if (sourceMapsDisabled || ts.positionIsSynthesized(pos) || isJsonSourceMapSource(sourceMapSource)) {
                return;
            }
            var _a = ts.getLineAndCharacterOfPosition(sourceMapSource, pos), sourceLine = _a.line, sourceCharacter = _a.character;
            sourceMapGenerator.addMapping(writer.getLine(), writer.getColumn(), sourceMapSourceIndex, sourceLine, sourceCharacter, 
            /*nameIndex*/ undefined);
        }
        function emitSourcePos(source, pos) {
            if (source !== sourceMapSource) {
                var savedSourceMapSource = sourceMapSource;
                setSourceMapSource(source);
                emitPos(pos);
                setSourceMapSource(savedSourceMapSource);
            }
            else {
                emitPos(pos);
            }
        }
        /**
         * Emits a token of a node with possible leading and trailing source maps.
         *
         * @param node The node containing the token.
         * @param token The token to emit.
         * @param tokenStartPos The start pos of the token.
         * @param emitCallback The callback used to emit the token.
         */
        function emitTokenWithSourceMap(node, token, writer, tokenPos, emitCallback) {
            if (sourceMapsDisabled || node && ts.isInJsonFile(node)) {
                return emitCallback(token, writer, tokenPos);
            }
            var emitNode = node && node.emitNode;
            var emitFlags = emitNode && emitNode.flags || 0 /* None */;
            var range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
            var source = range && range.source || sourceMapSource;
            tokenPos = skipSourceTrivia(source, range ? range.pos : tokenPos);
            if ((emitFlags & 128 /* NoTokenLeadingSourceMaps */) === 0 && tokenPos >= 0) {
                emitSourcePos(source, tokenPos);
            }
            tokenPos = emitCallback(token, writer, tokenPos);
            if (range)
                tokenPos = range.end;
            if ((emitFlags & 256 /* NoTokenTrailingSourceMaps */) === 0 && tokenPos >= 0) {
                emitSourcePos(source, tokenPos);
            }
            return tokenPos;
        }
        function setSourceMapSource(source) {
            if (sourceMapsDisabled) {
                return;
            }
            sourceMapSource = source;
            if (isJsonSourceMapSource(source)) {
                return;
            }
            sourceMapSourceIndex = sourceMapGenerator.addSource(source.fileName);
            if (printerOptions.inlineSources) {
                sourceMapGenerator.setSourceContent(sourceMapSourceIndex, source.text);
            }
        }
        function isJsonSourceMapSource(sourceFile) {
            return ts.fileExtensionIs(sourceFile.fileName, ".json" /* Json */);
        }
    }
    ts.createPrinter = createPrinter;
    function createBracketsMap() {
        var brackets = [];
        brackets[1024 /* Braces */] = ["{", "}"];
        brackets[2048 /* Parenthesis */] = ["(", ")"];
        brackets[4096 /* AngleBrackets */] = ["<", ">"];
        brackets[8192 /* SquareBrackets */] = ["[", "]"];
        return brackets;
    }
    function getOpeningBracket(format) {
        return brackets[format & 15360 /* BracketsMask */][0];
    }
    function getClosingBracket(format) {
        return brackets[format & 15360 /* BracketsMask */][1];
    }
    // Flags enum to track count of temp variables and a few dedicated names
    var TempFlags;
    (function (TempFlags) {
        TempFlags[TempFlags["Auto"] = 0] = "Auto";
        TempFlags[TempFlags["CountMask"] = 268435455] = "CountMask";
        TempFlags[TempFlags["_i"] = 268435456] = "_i";
    })(TempFlags || (TempFlags = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    function createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames) {
        if (!host.getDirectories || !host.readDirectory) {
            return undefined;
        }
        var cachedReadDirectoryResult = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        return {
            useCaseSensitiveFileNames: useCaseSensitiveFileNames,
            fileExists: fileExists,
            readFile: function (path, encoding) { return host.readFile(path, encoding); },
            directoryExists: host.directoryExists && directoryExists,
            getDirectories: getDirectories,
            readDirectory: readDirectory,
            createDirectory: host.createDirectory && createDirectory,
            writeFile: host.writeFile && writeFile,
            addOrDeleteFileOrDirectory: addOrDeleteFileOrDirectory,
            addOrDeleteFile: addOrDeleteFile,
            clearCache: clearCache,
            realpath: host.realpath && realpath
        };
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getCachedFileSystemEntries(rootDirPath) {
            return cachedReadDirectoryResult.get(ts.ensureTrailingDirectorySeparator(rootDirPath));
        }
        function getCachedFileSystemEntriesForBaseDir(path) {
            return getCachedFileSystemEntries(ts.getDirectoryPath(path));
        }
        function getBaseNameOfFileName(fileName) {
            return ts.getBaseFileName(ts.normalizePath(fileName));
        }
        function createCachedFileSystemEntries(rootDir, rootDirPath) {
            var resultFromHost = {
                files: ts.map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/ ["*.*"]), getBaseNameOfFileName) || [],
                directories: host.getDirectories(rootDir) || []
            };
            cachedReadDirectoryResult.set(ts.ensureTrailingDirectorySeparator(rootDirPath), resultFromHost);
            return resultFromHost;
        }
        /**
         * If the readDirectory result was already cached, it returns that
         * Otherwise gets result from host and caches it.
         * The host request is done under try catch block to avoid caching incorrect result
         */
        function tryReadDirectory(rootDir, rootDirPath) {
            rootDirPath = ts.ensureTrailingDirectorySeparator(rootDirPath);
            var cachedResult = getCachedFileSystemEntries(rootDirPath);
            if (cachedResult) {
                return cachedResult;
            }
            try {
                return createCachedFileSystemEntries(rootDir, rootDirPath);
            }
            catch (_e) {
                // If there is exception to read directories, dont cache the result and direct the calls to host
                ts.Debug.assert(!cachedReadDirectoryResult.has(ts.ensureTrailingDirectorySeparator(rootDirPath)));
                return undefined;
            }
        }
        function fileNameEqual(name1, name2) {
            return getCanonicalFileName(name1) === getCanonicalFileName(name2);
        }
        function hasEntry(entries, name) {
            return ts.some(entries, function (file) { return fileNameEqual(file, name); });
        }
        function updateFileSystemEntry(entries, baseName, isValid) {
            if (hasEntry(entries, baseName)) {
                if (!isValid) {
                    return ts.filterMutate(entries, function (entry) { return !fileNameEqual(entry, baseName); });
                }
            }
            else if (isValid) {
                return entries.push(baseName);
            }
        }
        function writeFile(fileName, data, writeByteOrderMark) {
            var path = toPath(fileName);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            if (result) {
                updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true);
            }
            return host.writeFile(fileName, data, writeByteOrderMark);
        }
        function fileExists(fileName) {
            var path = toPath(fileName);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            return result && hasEntry(result.files, getBaseNameOfFileName(fileName)) ||
                host.fileExists(fileName);
        }
        function directoryExists(dirPath) {
            var path = toPath(dirPath);
            return cachedReadDirectoryResult.has(ts.ensureTrailingDirectorySeparator(path)) || host.directoryExists(dirPath);
        }
        function createDirectory(dirPath) {
            var path = toPath(dirPath);
            var result = getCachedFileSystemEntriesForBaseDir(path);
            var baseFileName = getBaseNameOfFileName(dirPath);
            if (result) {
                updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true);
            }
            host.createDirectory(dirPath);
        }
        function getDirectories(rootDir) {
            var rootDirPath = toPath(rootDir);
            var result = tryReadDirectory(rootDir, rootDirPath);
            if (result) {
                return result.directories.slice();
            }
            return host.getDirectories(rootDir);
        }
        function readDirectory(rootDir, extensions, excludes, includes, depth) {
            var rootDirPath = toPath(rootDir);
            var result = tryReadDirectory(rootDir, rootDirPath);
            if (result) {
                return ts.matchFiles(rootDir, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries, realpath);
            }
            return host.readDirectory(rootDir, extensions, excludes, includes, depth);
            function getFileSystemEntries(dir) {
                var path = toPath(dir);
                if (path === rootDirPath) {
                    return result;
                }
                return tryReadDirectory(dir, path) || ts.emptyFileSystemEntries;
            }
        }
        function realpath(s) {
            return host.realpath ? host.realpath(s) : s;
        }
        function addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath) {
            var existingResult = getCachedFileSystemEntries(fileOrDirectoryPath);
            if (existingResult) {
                // Just clear the cache for now
                // For now just clear the cache, since this could mean that multiple level entries might need to be re-evaluated
                clearCache();
                return undefined;
            }
            var parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath);
            if (!parentResult) {
                return undefined;
            }
            // This was earlier a file (hence not in cached directory contents)
            // or we never cached the directory containing it
            if (!host.directoryExists) {
                // Since host doesnt support directory exists, clear the cache as otherwise it might not be same
                clearCache();
                return undefined;
            }
            var baseName = getBaseNameOfFileName(fileOrDirectory);
            var fsQueryResult = {
                fileExists: host.fileExists(fileOrDirectoryPath),
                directoryExists: host.directoryExists(fileOrDirectoryPath)
            };
            if (fsQueryResult.directoryExists || hasEntry(parentResult.directories, baseName)) {
                // Folder added or removed, clear the cache instead of updating the folder and its structure
                clearCache();
            }
            else {
                // No need to update the directory structure, just files
                updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
            }
            return fsQueryResult;
        }
        function addOrDeleteFile(fileName, filePath, eventKind) {
            if (eventKind === ts.FileWatcherEventKind.Changed) {
                return;
            }
            var parentResult = getCachedFileSystemEntriesForBaseDir(filePath);
            if (parentResult) {
                updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === ts.FileWatcherEventKind.Created);
            }
        }
        function updateFilesOfFileSystemEntry(parentResult, baseName, fileExists) {
            updateFileSystemEntry(parentResult.files, baseName, fileExists);
        }
        function clearCache() {
            cachedReadDirectoryResult.clear();
        }
    }
    ts.createCachedDirectoryStructureHost = createCachedDirectoryStructureHost;
    var ConfigFileProgramReloadLevel;
    (function (ConfigFileProgramReloadLevel) {
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["None"] = 0] = "None";
        /** Update the file name list from the disk */
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial";
        /** Reload completely by re-reading contents of config file from disk and updating program */
        ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full";
    })(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {}));
    /**
     * Updates the existing missing file watches with the new set of missing files after new program is created
     */
    function updateMissingFilePathsWatch(program, missingFileWatches, createMissingFileWatch) {
        var missingFilePaths = program.getMissingFilePaths();
        var newMissingFilePathMap = ts.arrayToSet(missingFilePaths);
        // Update the missing file paths watcher
        ts.mutateMap(missingFileWatches, newMissingFilePathMap, {
            // Watch the missing files
            createNewValue: createMissingFileWatch,
            // Files that are no longer missing (e.g. because they are no longer required)
            // should no longer be watched.
            onDeleteValue: ts.closeFileWatcher
        });
    }
    ts.updateMissingFilePathsWatch = updateMissingFilePathsWatch;
    /**
     * Updates the existing wild card directory watches with the new set of wild card directories from the config file
     * after new program is created because the config file was reloaded or program was created first time from the config file
     * Note that there is no need to call this function when the program is updated with additional files without reloading config files,
     * as wildcard directories wont change unless reloading config file
     */
    function updateWatchingWildcardDirectories(existingWatchedForWildcards, wildcardDirectories, watchDirectory) {
        ts.mutateMap(existingWatchedForWildcards, wildcardDirectories, {
            // Create new watch and recursive info
            createNewValue: createWildcardDirectoryWatcher,
            // Close existing watch thats not needed any more
            onDeleteValue: closeFileWatcherOf,
            // Close existing watch that doesnt match in the flags
            onExistingValue: updateWildcardDirectoryWatcher
        });
        function createWildcardDirectoryWatcher(directory, flags) {
            // Create new watch and recursive info
            return {
                watcher: watchDirectory(directory, flags),
                flags: flags
            };
        }
        function updateWildcardDirectoryWatcher(existingWatcher, flags, directory) {
            // Watcher needs to be updated if the recursive flags dont match
            if (existingWatcher.flags === flags) {
                return;
            }
            existingWatcher.watcher.close();
            existingWatchedForWildcards.set(directory, createWildcardDirectoryWatcher(directory, flags));
        }
    }
    ts.updateWatchingWildcardDirectories = updateWatchingWildcardDirectories;
    function isEmittedFileOfProgram(program, file) {
        if (!program) {
            return false;
        }
        return program.isEmittedFile(file);
    }
    ts.isEmittedFileOfProgram = isEmittedFileOfProgram;
    var WatchLogLevel;
    (function (WatchLogLevel) {
        WatchLogLevel[WatchLogLevel["None"] = 0] = "None";
        WatchLogLevel[WatchLogLevel["TriggerOnly"] = 1] = "TriggerOnly";
        WatchLogLevel[WatchLogLevel["Verbose"] = 2] = "Verbose";
    })(WatchLogLevel = ts.WatchLogLevel || (ts.WatchLogLevel = {}));
    function getWatchFactory(watchLogLevel, log, getDetailWatchInfo) {
        return getWatchFactoryWith(watchLogLevel, log, getDetailWatchInfo, watchFile, watchDirectory);
    }
    ts.getWatchFactory = getWatchFactory;
    function getWatchFactoryWith(watchLogLevel, log, getDetailWatchInfo, watchFile, watchDirectory) {
        var createFileWatcher = getCreateFileWatcher(watchLogLevel, watchFile);
        var createFilePathWatcher = watchLogLevel === WatchLogLevel.None ? watchFilePath : createFileWatcher;
        var createDirectoryWatcher = getCreateFileWatcher(watchLogLevel, watchDirectory);
        if (watchLogLevel === WatchLogLevel.Verbose && ts.sysLog === ts.noop) {
            ts.setSysLog(function (s) { return log(s); });
        }
        return {
            watchFile: function (host, file, callback, pollingInterval, options, detailInfo1, detailInfo2) {
                return createFileWatcher(host, file, callback, pollingInterval, options, /*passThrough*/ undefined, detailInfo1, detailInfo2, watchFile, log, "FileWatcher", getDetailWatchInfo);
            },
            watchFilePath: function (host, file, callback, pollingInterval, options, path, detailInfo1, detailInfo2) {
                return createFilePathWatcher(host, file, callback, pollingInterval, options, path, detailInfo1, detailInfo2, watchFile, log, "FileWatcher", getDetailWatchInfo);
            },
            watchDirectory: function (host, directory, callback, flags, options, detailInfo1, detailInfo2) {
                return createDirectoryWatcher(host, directory, callback, flags, options, /*passThrough*/ undefined, detailInfo1, detailInfo2, watchDirectory, log, "DirectoryWatcher", getDetailWatchInfo);
            }
        };
    }
    function watchFile(host, file, callback, pollingInterval, options) {
        return host.watchFile(file, callback, pollingInterval, options);
    }
    function watchFilePath(host, file, callback, pollingInterval, options, path) {
        return watchFile(host, file, function (fileName, eventKind) { return callback(fileName, eventKind, path); }, pollingInterval, options);
    }
    function watchDirectory(host, directory, callback, flags, options) {
        return host.watchDirectory(directory, callback, (flags & 1 /* Recursive */) !== 0, options);
    }
    function getCreateFileWatcher(watchLogLevel, addWatch) {
        switch (watchLogLevel) {
            case WatchLogLevel.None:
                return addWatch;
            case WatchLogLevel.TriggerOnly:
                return createFileWatcherWithTriggerLogging;
            case WatchLogLevel.Verbose:
                return addWatch === watchDirectory ? createDirectoryWatcherWithLogging : createFileWatcherWithLogging;
        }
    }
    function createFileWatcherWithLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        log(watchCaption + ":: Added:: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo));
        var watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
        return {
            close: function () {
                log(watchCaption + ":: Close:: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo));
                watcher.close();
            }
        };
    }
    function createDirectoryWatcherWithLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        var watchInfo = watchCaption + ":: Added:: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo);
        log(watchInfo);
        var start = ts.timestamp();
        var watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
        var elapsed = ts.timestamp() - start;
        log("Elapsed:: " + elapsed + "ms " + watchInfo);
        return {
            close: function () {
                var watchInfo = watchCaption + ":: Close:: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo);
                log(watchInfo);
                var start = ts.timestamp();
                watcher.close();
                var elapsed = ts.timestamp() - start;
                log("Elapsed:: " + elapsed + "ms " + watchInfo);
            }
        };
    }
    function createFileWatcherWithTriggerLogging(host, file, cb, flags, options, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo) {
        return addWatch(host, file, function (fileName, cbOptional) {
            var triggerredInfo = watchCaption + ":: Triggered with " + fileName + " " + (cbOptional !== undefined ? cbOptional : "") + ":: " + getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo);
            log(triggerredInfo);
            var start = ts.timestamp();
            cb(fileName, cbOptional, passThrough);
            var elapsed = ts.timestamp() - start;
            log("Elapsed:: " + elapsed + "ms " + triggerredInfo);
        }, flags, options);
    }
    function getFallbackOptions(options) {
        var fallbackPolling = options === null || options === void 0 ? void 0 : options.fallbackPolling;
        return {
            watchFile: fallbackPolling !== undefined ?
                fallbackPolling :
                ts.WatchFileKind.PriorityPollingInterval
        };
    }
    ts.getFallbackOptions = getFallbackOptions;
    function getWatchInfo(file, flags, options, detailInfo1, detailInfo2, getDetailWatchInfo) {
        return "WatchInfo: " + file + " " + flags + " " + JSON.stringify(options) + " " + (getDetailWatchInfo ? getDetailWatchInfo(detailInfo1, detailInfo2) : detailInfo2 === undefined ? detailInfo1 : detailInfo1 + " " + detailInfo2);
    }
    function closeFileWatcherOf(objWithWatcher) {
        objWithWatcher.watcher.close();
    }
    ts.closeFileWatcherOf = closeFileWatcherOf;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function findConfigFile(searchPath, fileExists, configName) {
        if (configName === void 0) { configName = "tsconfig.json"; }
        return ts.forEachAncestorDirectory(searchPath, function (ancestor) {
            var fileName = ts.combinePaths(ancestor, configName);
            return fileExists(fileName) ? fileName : undefined;
        });
    }
    ts.findConfigFile = findConfigFile;
    function resolveTripleslashReference(moduleName, containingFile) {
        var basePath = ts.getDirectoryPath(containingFile);
        var referencedFileName = ts.isRootedDiskPath(moduleName) ? moduleName : ts.combinePaths(basePath, moduleName);
        return ts.normalizePath(referencedFileName);
    }
    ts.resolveTripleslashReference = resolveTripleslashReference;
    /* @internal */
    function computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName) {
        var commonPathComponents;
        var failed = ts.forEach(fileNames, function (sourceFile) {
            // Each file contributes into common source file path
            var sourcePathComponents = ts.getNormalizedPathComponents(sourceFile, currentDirectory);
            sourcePathComponents.pop(); // The base file name is not part of the common directory path
            if (!commonPathComponents) {
                // first file
                commonPathComponents = sourcePathComponents;
                return;
            }
            var n = Math.min(commonPathComponents.length, sourcePathComponents.length);
            for (var i = 0; i < n; i++) {
                if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) {
                    if (i === 0) {
                        // Failed to find any common path component
                        return true;
                    }
                    // New common path found that is 0 -> i-1
                    commonPathComponents.length = i;
                    break;
                }
            }
            // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents
            if (sourcePathComponents.length < commonPathComponents.length) {
                commonPathComponents.length = sourcePathComponents.length;
            }
        });
        // A common path can not be found when paths span multiple drives on windows, for example
        if (failed) {
            return "";
        }
        if (!commonPathComponents) { // Can happen when all input files are .d.ts files
            return currentDirectory;
        }
        return ts.getPathFromPathComponents(commonPathComponents);
    }
    ts.computeCommonSourceDirectoryOfFilenames = computeCommonSourceDirectoryOfFilenames;
    function createCompilerHost(options, setParentNodes) {
        return createCompilerHostWorker(options, setParentNodes);
    }
    ts.createCompilerHost = createCompilerHost;
    /*@internal*/
    // TODO(shkamat): update this after reworking ts build API
    function createCompilerHostWorker(options, setParentNodes, system) {
        if (system === void 0) { system = ts.sys; }
        var existingDirectories = ts.createMap();
        var getCanonicalFileName = ts.createGetCanonicalFileName(system.useCaseSensitiveFileNames);
        function getSourceFile(fileName, languageVersion, onError) {
            var text;
            try {
                ts.performance.mark("beforeIORead");
                text = compilerHost.readFile(fileName);
                ts.performance.mark("afterIORead");
                ts.performance.measure("I/O Read", "beforeIORead", "afterIORead");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
                text = "";
            }
            return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined;
        }
        function directoryExists(directoryPath) {
            if (existingDirectories.has(directoryPath)) {
                return true;
            }
            if ((compilerHost.directoryExists || system.directoryExists)(directoryPath)) {
                existingDirectories.set(directoryPath, true);
                return true;
            }
            return false;
        }
        function writeFile(fileName, data, writeByteOrderMark, onError) {
            try {
                ts.performance.mark("beforeIOWrite");
                // NOTE: If patchWriteFileEnsuringDirectory has been called,
                // the system.writeFile will do its own directory creation and
                // the ensureDirectoriesExist call will always be redundant.
                ts.writeFileEnsuringDirectories(fileName, data, writeByteOrderMark, function (path, data, writeByteOrderMark) { return writeFileWorker(path, data, writeByteOrderMark); }, function (path) { return (compilerHost.createDirectory || system.createDirectory)(path); }, function (path) { return directoryExists(path); });
                ts.performance.mark("afterIOWrite");
                ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
            }
        }
        var outputFingerprints;
        function writeFileWorker(fileName, data, writeByteOrderMark) {
            if (!ts.isWatchSet(options) || !system.createHash || !system.getModifiedTime) {
                system.writeFile(fileName, data, writeByteOrderMark);
                return;
            }
            if (!outputFingerprints) {
                outputFingerprints = ts.createMap();
            }
            var hash = system.createHash(data);
            var mtimeBefore = system.getModifiedTime(fileName);
            if (mtimeBefore) {
                var fingerprint = outputFingerprints.get(fileName);
                // If output has not been changed, and the file has no external modification
                if (fingerprint &&
                    fingerprint.byteOrderMark === writeByteOrderMark &&
                    fingerprint.hash === hash &&
                    fingerprint.mtime.getTime() === mtimeBefore.getTime()) {
                    return;
                }
            }
            system.writeFile(fileName, data, writeByteOrderMark);
            var mtimeAfter = system.getModifiedTime(fileName) || ts.missingFileModifiedTime;
            outputFingerprints.set(fileName, {
                hash: hash,
                byteOrderMark: writeByteOrderMark,
                mtime: mtimeAfter
            });
        }
        function getDefaultLibLocation() {
            return ts.getDirectoryPath(ts.normalizePath(system.getExecutingFilePath()));
        }
        var newLine = ts.getNewLineCharacter(options, function () { return system.newLine; });
        var realpath = system.realpath && (function (path) { return system.realpath(path); });
        var compilerHost = {
            getSourceFile: getSourceFile,
            getDefaultLibLocation: getDefaultLibLocation,
            getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); },
            writeFile: writeFile,
            getCurrentDirectory: ts.memoize(function () { return system.getCurrentDirectory(); }),
            useCaseSensitiveFileNames: function () { return system.useCaseSensitiveFileNames; },
            getCanonicalFileName: getCanonicalFileName,
            getNewLine: function () { return newLine; },
            fileExists: function (fileName) { return system.fileExists(fileName); },
            readFile: function (fileName) { return system.readFile(fileName); },
            trace: function (s) { return system.write(s + newLine); },
            directoryExists: function (directoryName) { return system.directoryExists(directoryName); },
            getEnvironmentVariable: function (name) { return system.getEnvironmentVariable ? system.getEnvironmentVariable(name) : ""; },
            getDirectories: function (path) { return system.getDirectories(path); },
            realpath: realpath,
            readDirectory: function (path, extensions, include, exclude, depth) { return system.readDirectory(path, extensions, include, exclude, depth); },
            createDirectory: function (d) { return system.createDirectory(d); },
            createHash: ts.maybeBind(system, system.createHash)
        };
        return compilerHost;
    }
    ts.createCompilerHostWorker = createCompilerHostWorker;
    /*@internal*/
    function changeCompilerHostLikeToUseCache(host, toPath, getSourceFile) {
        var originalReadFile = host.readFile;
        var originalFileExists = host.fileExists;
        var originalDirectoryExists = host.directoryExists;
        var originalCreateDirectory = host.createDirectory;
        var originalWriteFile = host.writeFile;
        var readFileCache = ts.createMap();
        var fileExistsCache = ts.createMap();
        var directoryExistsCache = ts.createMap();
        var sourceFileCache = ts.createMap();
        var readFileWithCache = function (fileName) {
            var key = toPath(fileName);
            var value = readFileCache.get(key);
            if (value !== undefined)
                return value !== false ? value : undefined;
            return setReadFileCache(key, fileName);
        };
        var setReadFileCache = function (key, fileName) {
            var newValue = originalReadFile.call(host, fileName);
            readFileCache.set(key, newValue !== undefined ? newValue : false);
            return newValue;
        };
        host.readFile = function (fileName) {
            var key = toPath(fileName);
            var value = readFileCache.get(key);
            if (value !== undefined)
                return value !== false ? value : undefined; // could be .d.ts from output
            // Cache json or buildInfo
            if (!ts.fileExtensionIs(fileName, ".json" /* Json */) && !ts.isBuildInfoFile(fileName)) {
                return originalReadFile.call(host, fileName);
            }
            return setReadFileCache(key, fileName);
        };
        var getSourceFileWithCache = getSourceFile ? function (fileName, languageVersion, onError, shouldCreateNewSourceFile) {
            var key = toPath(fileName);
            var value = sourceFileCache.get(key);
            if (value)
                return value;
            var sourceFile = getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
            if (sourceFile && (ts.isDeclarationFileName(fileName) || ts.fileExtensionIs(fileName, ".json" /* Json */))) {
                sourceFileCache.set(key, sourceFile);
            }
            return sourceFile;
        } : undefined;
        // fileExists for any kind of extension
        host.fileExists = function (fileName) {
            var key = toPath(fileName);
            var value = fileExistsCache.get(key);
            if (value !== undefined)
                return value;
            var newValue = originalFileExists.call(host, fileName);
            fileExistsCache.set(key, !!newValue);
            return newValue;
        };
        if (originalWriteFile) {
            host.writeFile = function (fileName, data, writeByteOrderMark, onError, sourceFiles) {
                var key = toPath(fileName);
                fileExistsCache.delete(key);
                var value = readFileCache.get(key);
                if (value !== undefined && value !== data) {
                    readFileCache.delete(key);
                    sourceFileCache.delete(key);
                }
                else if (getSourceFileWithCache) {
                    var sourceFile = sourceFileCache.get(key);
                    if (sourceFile && sourceFile.text !== data) {
                        sourceFileCache.delete(key);
                    }
                }
                originalWriteFile.call(host, fileName, data, writeByteOrderMark, onError, sourceFiles);
            };
        }
        // directoryExists
        if (originalDirectoryExists && originalCreateDirectory) {
            host.directoryExists = function (directory) {
                var key = toPath(directory);
                var value = directoryExistsCache.get(key);
                if (value !== undefined)
                    return value;
                var newValue = originalDirectoryExists.call(host, directory);
                directoryExistsCache.set(key, !!newValue);
                return newValue;
            };
            host.createDirectory = function (directory) {
                var key = toPath(directory);
                directoryExistsCache.delete(key);
                originalCreateDirectory.call(host, directory);
            };
        }
        return {
            originalReadFile: originalReadFile,
            originalFileExists: originalFileExists,
            originalDirectoryExists: originalDirectoryExists,
            originalCreateDirectory: originalCreateDirectory,
            originalWriteFile: originalWriteFile,
            getSourceFileWithCache: getSourceFileWithCache,
            readFileWithCache: readFileWithCache
        };
    }
    ts.changeCompilerHostLikeToUseCache = changeCompilerHostLikeToUseCache;
    function getPreEmitDiagnostics(program, sourceFile, cancellationToken) {
        var diagnostics;
        diagnostics = ts.addRange(diagnostics, program.getConfigFileParsingDiagnostics());
        diagnostics = ts.addRange(diagnostics, program.getOptionsDiagnostics(cancellationToken));
        diagnostics = ts.addRange(diagnostics, program.getSyntacticDiagnostics(sourceFile, cancellationToken));
        diagnostics = ts.addRange(diagnostics, program.getGlobalDiagnostics(cancellationToken));
        diagnostics = ts.addRange(diagnostics, program.getSemanticDiagnostics(sourceFile, cancellationToken));
        if (ts.getEmitDeclarations(program.getCompilerOptions())) {
            diagnostics = ts.addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken));
        }
        return ts.sortAndDeduplicateDiagnostics(diagnostics || ts.emptyArray);
    }
    ts.getPreEmitDiagnostics = getPreEmitDiagnostics;
    function formatDiagnostics(diagnostics, host) {
        var output = "";
        for (var _i = 0, diagnostics_2 = diagnostics; _i < diagnostics_2.length; _i++) {
            var diagnostic = diagnostics_2[_i];
            output += formatDiagnostic(diagnostic, host);
        }
        return output;
    }
    ts.formatDiagnostics = formatDiagnostics;
    function formatDiagnostic(diagnostic, host) {
        var errorMessage = ts.diagnosticCategoryName(diagnostic) + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine();
        if (diagnostic.file) {
            var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; // TODO: GH#18217
            var fileName = diagnostic.file.fileName;
            var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); });
            return relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): " + errorMessage;
        }
        return errorMessage;
    }
    ts.formatDiagnostic = formatDiagnostic;
    /** @internal */
    var ForegroundColorEscapeSequences;
    (function (ForegroundColorEscapeSequences) {
        ForegroundColorEscapeSequences["Grey"] = "\u001B[90m";
        ForegroundColorEscapeSequences["Red"] = "\u001B[91m";
        ForegroundColorEscapeSequences["Yellow"] = "\u001B[93m";
        ForegroundColorEscapeSequences["Blue"] = "\u001B[94m";
        ForegroundColorEscapeSequences["Cyan"] = "\u001B[96m";
    })(ForegroundColorEscapeSequences = ts.ForegroundColorEscapeSequences || (ts.ForegroundColorEscapeSequences = {}));
    var gutterStyleSequence = "\u001b[7m";
    var gutterSeparator = " ";
    var resetEscapeSequence = "\u001b[0m";
    var ellipsis = "...";
    var halfIndent = "  ";
    var indent = "    ";
    function getCategoryFormat(category) {
        switch (category) {
            case ts.DiagnosticCategory.Error: return ForegroundColorEscapeSequences.Red;
            case ts.DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow;
            case ts.DiagnosticCategory.Suggestion: return ts.Debug.fail("Should never get an Info diagnostic on the command line.");
            case ts.DiagnosticCategory.Message: return ForegroundColorEscapeSequences.Blue;
        }
    }
    /** @internal */
    function formatColorAndReset(text, formatStyle) {
        return formatStyle + text + resetEscapeSequence;
    }
    ts.formatColorAndReset = formatColorAndReset;
    function formatCodeSpan(file, start, length, indent, squiggleColor, host) {
        var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character;
        var _b = ts.getLineAndCharacterOfPosition(file, start + length), lastLine = _b.line, lastLineChar = _b.character;
        var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line;
        var hasMoreThanFiveLines = (lastLine - firstLine) >= 4;
        var gutterWidth = (lastLine + 1 + "").length;
        if (hasMoreThanFiveLines) {
            gutterWidth = Math.max(ellipsis.length, gutterWidth);
        }
        var context = "";
        for (var i = firstLine; i <= lastLine; i++) {
            context += host.getNewLine();
            // If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
            // so we'll skip ahead to the second-to-last line.
            if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
                context += indent + formatColorAndReset(ts.padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
                i = lastLine - 1;
            }
            var lineStart = ts.getPositionOfLineAndCharacter(file, i, 0);
            var lineEnd = i < lastLineInFile ? ts.getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length;
            var lineContent = file.text.slice(lineStart, lineEnd);
            lineContent = lineContent.replace(/\s+$/g, ""); // trim from end
            lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
            // Output the gutter and the actual contents of the line.
            context += indent + formatColorAndReset(ts.padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
            context += lineContent + host.getNewLine();
            // Output the gutter and the error span for the line using tildes.
            context += indent + formatColorAndReset(ts.padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
            context += squiggleColor;
            if (i === firstLine) {
                // If we're on the last line, then limit it to the last character of the last line.
                // Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position.
                var lastCharForLine = i === lastLine ? lastLineChar : undefined;
                context += lineContent.slice(0, firstLineChar).replace(/\S/g, " ");
                context += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~");
            }
            else if (i === lastLine) {
                context += lineContent.slice(0, lastLineChar).replace(/./g, "~");
            }
            else {
                // Squiggle the entire line.
                context += lineContent.replace(/./g, "~");
            }
            context += resetEscapeSequence;
        }
        return context;
    }
    /* @internal */
    function formatLocation(file, start, host, color) {
        if (color === void 0) { color = formatColorAndReset; }
        var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character; // TODO: GH#18217
        var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName;
        var output = "";
        output += color(relativeFileName, ForegroundColorEscapeSequences.Cyan);
        output += ":";
        output += color("" + (firstLine + 1), ForegroundColorEscapeSequences.Yellow);
        output += ":";
        output += color("" + (firstLineChar + 1), ForegroundColorEscapeSequences.Yellow);
        return output;
    }
    ts.formatLocation = formatLocation;
    function formatDiagnosticsWithColorAndContext(diagnostics, host) {
        var output = "";
        for (var _i = 0, diagnostics_3 = diagnostics; _i < diagnostics_3.length; _i++) {
            var diagnostic = diagnostics_3[_i];
            if (diagnostic.file) {
                var file = diagnostic.file, start = diagnostic.start;
                output += formatLocation(file, start, host); // TODO: GH#18217
                output += " - ";
            }
            output += formatColorAndReset(ts.diagnosticCategoryName(diagnostic), getCategoryFormat(diagnostic.category));
            output += formatColorAndReset(" TS" + diagnostic.code + ": ", ForegroundColorEscapeSequences.Grey);
            output += flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine());
            if (diagnostic.file) {
                output += host.getNewLine();
                output += formatCodeSpan(diagnostic.file, diagnostic.start, diagnostic.length, "", getCategoryFormat(diagnostic.category), host); // TODO: GH#18217
                if (diagnostic.relatedInformation) {
                    output += host.getNewLine();
                    for (var _a = 0, _b = diagnostic.relatedInformation; _a < _b.length; _a++) {
                        var _c = _b[_a], file = _c.file, start = _c.start, length_8 = _c.length, messageText = _c.messageText;
                        if (file) {
                            output += host.getNewLine();
                            output += halfIndent + formatLocation(file, start, host); // TODO: GH#18217
                            output += formatCodeSpan(file, start, length_8, indent, ForegroundColorEscapeSequences.Cyan, host); // TODO: GH#18217
                        }
                        output += host.getNewLine();
                        output += indent + flattenDiagnosticMessageText(messageText, host.getNewLine());
                    }
                }
            }
            output += host.getNewLine();
        }
        return output;
    }
    ts.formatDiagnosticsWithColorAndContext = formatDiagnosticsWithColorAndContext;
    function flattenDiagnosticMessageText(diag, newLine, indent) {
        if (indent === void 0) { indent = 0; }
        if (ts.isString(diag)) {
            return diag;
        }
        else if (diag === undefined) {
            return "";
        }
        var result = "";
        if (indent) {
            result += newLine;
            for (var i = 0; i < indent; i++) {
                result += "  ";
            }
        }
        result += diag.messageText;
        indent++;
        if (diag.next) {
            for (var _i = 0, _a = diag.next; _i < _a.length; _i++) {
                var kid = _a[_i];
                result += flattenDiagnosticMessageText(kid, newLine, indent);
            }
        }
        return result;
    }
    ts.flattenDiagnosticMessageText = flattenDiagnosticMessageText;
    /* @internal */
    function loadWithLocalCache(names, containingFile, redirectedReference, loader) {
        if (names.length === 0) {
            return [];
        }
        var resolutions = [];
        var cache = ts.createMap();
        for (var _i = 0, names_2 = names; _i < names_2.length; _i++) {
            var name = names_2[_i];
            var result = void 0;
            if (cache.has(name)) {
                result = cache.get(name);
            }
            else {
                cache.set(name, result = loader(name, containingFile, redirectedReference));
            }
            resolutions.push(result);
        }
        return resolutions;
    }
    ts.loadWithLocalCache = loadWithLocalCache;
    /* @internal */
    ts.inferredTypesContainingFile = "__inferred type names__.ts";
    /**
     * Determines if program structure is upto date or needs to be recreated
     */
    /* @internal */
    function isProgramUptoDate(program, rootFileNames, newOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, projectReferences) {
        // If we haven't created a program yet or have changed automatic type directives, then it is not up-to-date
        if (!program || hasChangedAutomaticTypeDirectiveNames) {
            return false;
        }
        // If root file names don't match
        if (!ts.arrayIsEqualTo(program.getRootFileNames(), rootFileNames)) {
            return false;
        }
        var seenResolvedRefs;
        // If project references don't match
        if (!ts.arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) {
            return false;
        }
        // If any file is not up-to-date, then the whole program is not up-to-date
        if (program.getSourceFiles().some(sourceFileNotUptoDate)) {
            return false;
        }
        // If any of the missing file paths are now created
        if (program.getMissingFilePaths().some(fileExists)) {
            return false;
        }
        var currentOptions = program.getCompilerOptions();
        // If the compilation settings do no match, then the program is not up-to-date
        if (!ts.compareDataObjects(currentOptions, newOptions)) {
            return false;
        }
        // If everything matches but the text of config file is changed,
        // error locations can change for program options, so update the program
        if (currentOptions.configFile && newOptions.configFile) {
            return currentOptions.configFile.text === newOptions.configFile.text;
        }
        return true;
        function sourceFileNotUptoDate(sourceFile) {
            return !sourceFileVersionUptoDate(sourceFile) ||
                hasInvalidatedResolution(sourceFile.path);
        }
        function sourceFileVersionUptoDate(sourceFile) {
            return sourceFile.version === getSourceVersion(sourceFile.resolvedPath, sourceFile.fileName);
        }
        function projectReferenceUptoDate(oldRef, newRef, index) {
            if (!ts.projectReferenceIsEqualTo(oldRef, newRef)) {
                return false;
            }
            return resolvedProjectReferenceUptoDate(program.getResolvedProjectReferences()[index], oldRef);
        }
        function resolvedProjectReferenceUptoDate(oldResolvedRef, oldRef) {
            if (oldResolvedRef) {
                if (ts.contains(seenResolvedRefs, oldResolvedRef)) {
                    // Assume true
                    return true;
                }
                // If sourceFile for the oldResolvedRef existed, check the version for uptodate
                if (!sourceFileVersionUptoDate(oldResolvedRef.sourceFile)) {
                    return false;
                }
                // Add to seen before checking the referenced paths of this config file
                (seenResolvedRefs || (seenResolvedRefs = [])).push(oldResolvedRef);
                // If child project references are upto date, this project reference is uptodate
                return !ts.forEach(oldResolvedRef.references, function (childResolvedRef, index) {
                    return !resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences[index]);
                });
            }
            // In old program, not able to resolve project reference path,
            // so if config file doesnt exist, it is uptodate.
            return !fileExists(resolveProjectReferencePath(oldRef));
        }
    }
    ts.isProgramUptoDate = isProgramUptoDate;
    function getConfigFileParsingDiagnostics(configFileParseResult) {
        return configFileParseResult.options.configFile ? __spreadArrays(configFileParseResult.options.configFile.parseDiagnostics, configFileParseResult.errors) :
            configFileParseResult.errors;
    }
    ts.getConfigFileParsingDiagnostics = getConfigFileParsingDiagnostics;
    /**
     * Determine if source file needs to be re-created even if its text hasn't changed
     */
    function shouldProgramCreateNewSourceFiles(program, newOptions) {
        if (!program)
            return false;
        // If any compiler options change, we can't reuse old source file even if version match
        // The change in options like these could result in change in syntax tree or `sourceFile.bindDiagnostics`.
        var oldOptions = program.getCompilerOptions();
        return !!ts.sourceFileAffectingCompilerOptions.some(function (option) {
            return !ts.isJsonEqual(ts.getCompilerOptionValue(oldOptions, option), ts.getCompilerOptionValue(newOptions, option));
        });
    }
    function createCreateProgramOptions(rootNames, options, host, oldProgram, configFileParsingDiagnostics) {
        return {
            rootNames: rootNames,
            options: options,
            host: host,
            oldProgram: oldProgram,
            configFileParsingDiagnostics: configFileParsingDiagnostics
        };
    }
    function createProgram(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) {
        var _a;
        var createProgramOptions = ts.isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217
        var rootNames = createProgramOptions.rootNames, options = createProgramOptions.options, configFileParsingDiagnostics = createProgramOptions.configFileParsingDiagnostics, projectReferences = createProgramOptions.projectReferences;
        var oldProgram = createProgramOptions.oldProgram;
        var processingDefaultLibFiles;
        var processingOtherFiles;
        var files;
        var symlinks;
        var commonSourceDirectory;
        var diagnosticsProducingTypeChecker;
        var noDiagnosticsTypeChecker;
        var classifiableNames;
        var ambientModuleNameToUnmodifiedFileName = ts.createMap();
        // Todo:: Use this to report why file was included in --extendedDiagnostics
        var refFileMap;
        var cachedBindAndCheckDiagnosticsForFile = {};
        var cachedDeclarationDiagnosticsForFile = {};
        var resolvedTypeReferenceDirectives = ts.createMap();
        var fileProcessingDiagnostics = ts.createDiagnosticCollection();
        // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules.
        // This works as imported modules are discovered recursively in a depth first manner, specifically:
        // - For each root file, findSourceFile is called.
        // - This calls processImportedModules for each module imported in the source file.
        // - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
        // As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
        // The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
        var maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
        var currentNodeModulesDepth = 0;
        // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
        // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed.
        var modulesWithElidedImports = ts.createMap();
        // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled.
        var sourceFilesFoundSearchingNodeModules = ts.createMap();
        ts.performance.mark("beforeProgram");
        var host = createProgramOptions.host || createCompilerHost(options);
        var configParsingHost = parseConfigHostFromCompilerHostLike(host);
        var skipDefaultLib = options.noLib;
        var getDefaultLibraryFileName = ts.memoize(function () { return host.getDefaultLibFileName(options); });
        var defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : ts.getDirectoryPath(getDefaultLibraryFileName());
        var programDiagnostics = ts.createDiagnosticCollection();
        var currentDirectory = host.getCurrentDirectory();
        var supportedExtensions = ts.getSupportedExtensions(options);
        var supportedExtensionsWithJsonIfResolveJsonModule = ts.getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
        // Map storing if there is emit blocking diagnostics for given input
        var hasEmitBlockingDiagnostics = ts.createMap();
        var _compilerOptionsObjectLiteralSyntax;
        var moduleResolutionCache;
        var actualResolveModuleNamesWorker;
        var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse;
        if (host.resolveModuleNames) {
            actualResolveModuleNamesWorker = function (moduleNames, containingFile, reusedNames, redirectedReference) { return host.resolveModuleNames(ts.Debug.checkEachDefined(moduleNames), containingFile, reusedNames, redirectedReference, options).map(function (resolved) {
                // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
                if (!resolved || resolved.extension !== undefined) {
                    return resolved;
                }
                var withExtension = ts.clone(resolved);
                withExtension.extension = ts.extensionFromPath(resolved.resolvedFileName);
                return withExtension;
            }); };
        }
        else {
            moduleResolutionCache = ts.createModuleResolutionCache(currentDirectory, function (x) { return host.getCanonicalFileName(x); }, options);
            var loader_1 = function (moduleName, containingFile, redirectedReference) { return ts.resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache, redirectedReference).resolvedModule; }; // TODO: GH#18217
            actualResolveModuleNamesWorker = function (moduleNames, containingFile, _reusedNames, redirectedReference) { return loadWithLocalCache(ts.Debug.checkEachDefined(moduleNames), containingFile, redirectedReference, loader_1); };
        }
        var actualResolveTypeReferenceDirectiveNamesWorker;
        if (host.resolveTypeReferenceDirectives) {
            actualResolveTypeReferenceDirectiveNamesWorker = function (typeDirectiveNames, containingFile, redirectedReference) { return host.resolveTypeReferenceDirectives(ts.Debug.checkEachDefined(typeDirectiveNames), containingFile, redirectedReference, options); };
        }
        else {
            var loader_2 = function (typesRef, containingFile, redirectedReference) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host, redirectedReference).resolvedTypeReferenceDirective; }; // TODO: GH#18217
            actualResolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile, redirectedReference) { return loadWithLocalCache(ts.Debug.checkEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader_2); };
        }
        // Map from a stringified PackageId to the source file with that id.
        // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile).
        // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around.
        var packageIdToSourceFile = ts.createMap();
        // Maps from a SourceFile's `.path` to the name of the package it was imported with.
        var sourceFileToPackageName = ts.createMap();
        // Key is a file name. Value is the (non-empty, or undefined) list of files that redirect to it.
        var redirectTargetsMap = ts.createMultiMap();
        /**
         * map with
         * - SourceFile if present
         * - false if sourceFile missing for source of project reference redirect
         * - undefined otherwise
         */
        var filesByName = ts.createMap();
        var missingFilePaths;
        // stores 'filename -> file association' ignoring case
        // used to track cases when two file names differ only in casing
        var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined;
        // A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
        var resolvedProjectReferences;
        var projectReferenceRedirects;
        var mapFromFileToProjectReferenceRedirects;
        var mapFromToProjectReferenceRedirectSource;
        var useSourceOfProjectReferenceRedirect = !!((_a = host.useSourceOfProjectReferenceRedirect) === null || _a === void 0 ? void 0 : _a.call(host)) &&
            !options.disableSourceOfProjectReferenceRedirect;
        var _b = updateHostForUseSourceOfProjectReferenceRedirect({
            compilerHost: host,
            useSourceOfProjectReferenceRedirect: useSourceOfProjectReferenceRedirect,
            toPath: toPath,
            getResolvedProjectReferences: getResolvedProjectReferences,
            getSourceOfProjectReferenceRedirect: getSourceOfProjectReferenceRedirect,
            forEachResolvedProjectReference: forEachResolvedProjectReference
        }), onProgramCreateComplete = _b.onProgramCreateComplete, fileExists = _b.fileExists;
        var shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
        // We set `structuralIsReused` to `undefined` because `tryReuseStructureFromOldProgram` calls `tryReuseStructureFromOldProgram` which checks
        // `structuralIsReused`, which would be a TDZ violation if it was not set in advance to `undefined`.
        var structuralIsReused;
        structuralIsReused = tryReuseStructureFromOldProgram(); // eslint-disable-line prefer-const
        if (structuralIsReused !== 2 /* Completely */) {
            processingDefaultLibFiles = [];
            processingOtherFiles = [];
            if (projectReferences) {
                if (!resolvedProjectReferences) {
                    resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
                }
                if (rootNames.length) {
                    for (var _i = 0, resolvedProjectReferences_1 = resolvedProjectReferences; _i < resolvedProjectReferences_1.length; _i++) {
                        var parsedRef = resolvedProjectReferences_1[_i];
                        if (!parsedRef)
                            continue;
                        var out = parsedRef.commandLine.options.outFile || parsedRef.commandLine.options.out;
                        if (useSourceOfProjectReferenceRedirect) {
                            if (out || ts.getEmitModuleKind(parsedRef.commandLine.options) === ts.ModuleKind.None) {
                                for (var _c = 0, _d = parsedRef.commandLine.fileNames; _c < _d.length; _c++) {
                                    var fileName = _d[_c];
                                    processSourceFile(fileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
                                }
                            }
                        }
                        else {
                            if (out) {
                                processSourceFile(ts.changeExtension(out, ".d.ts"), /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
                            }
                            else if (ts.getEmitModuleKind(parsedRef.commandLine.options) === ts.ModuleKind.None) {
                                for (var _e = 0, _f = parsedRef.commandLine.fileNames; _e < _f.length; _e++) {
                                    var fileName = _f[_e];
                                    if (!ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) && !ts.fileExtensionIs(fileName, ".json" /* Json */)) {
                                        processSourceFile(ts.getOutputDeclarationFileName(fileName, parsedRef.commandLine, !host.useCaseSensitiveFileNames()), /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false); });
            // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
            var typeReferences = rootNames.length ? ts.getAutomaticTypeDirectiveNames(options, host) : ts.emptyArray;
            if (typeReferences.length) {
                // This containingFilename needs to match with the one used in managed-side
                var containingDirectory = options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : host.getCurrentDirectory();
                var containingFilename = ts.combinePaths(containingDirectory, ts.inferredTypesContainingFile);
                var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
                for (var i = 0; i < typeReferences.length; i++) {
                    processTypeReferenceDirective(typeReferences[i], resolutions[i]);
                }
            }
            // Do not process the default library if:
            //  - The '--noLib' flag is used.
            //  - A 'no-default-lib' reference comment is encountered in
            //      processing the root files.
            if (rootNames.length && !skipDefaultLib) {
                // If '--lib' is not specified, include default library file according to '--target'
                // otherwise, using options specified in '--lib' instead of '--target' default library file
                var defaultLibraryFileName = getDefaultLibraryFileName();
                if (!options.lib && defaultLibraryFileName) {
                    processRootFile(defaultLibraryFileName, /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false);
                }
                else {
                    ts.forEach(options.lib, function (libFileName) {
                        processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ false);
                    });
                }
            }
            missingFilePaths = ts.arrayFrom(ts.mapDefinedIterator(filesByName.entries(), function (_a) {
                var path = _a[0], file = _a[1];
                return file === undefined ? path : undefined;
            }));
            files = ts.stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
            processingDefaultLibFiles = undefined;
            processingOtherFiles = undefined;
        }
        ts.Debug.assert(!!missingFilePaths);
        // Release any files we have acquired in the old program but are
        // not part of the new program.
        if (oldProgram && host.onReleaseOldSourceFile) {
            var oldSourceFiles = oldProgram.getSourceFiles();
            for (var _g = 0, oldSourceFiles_1 = oldSourceFiles; _g < oldSourceFiles_1.length; _g++) {
                var oldSourceFile = oldSourceFiles_1[_g];
                var newFile = getSourceFileByPath(oldSourceFile.resolvedPath);
                if (shouldCreateNewSourceFile || !newFile ||
                    // old file wasnt redirect but new file is
                    (oldSourceFile.resolvedPath === oldSourceFile.path && newFile.resolvedPath !== oldSourceFile.path)) {
                    host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions(), !!getSourceFileByPath(oldSourceFile.path));
                }
            }
            oldProgram.forEachResolvedProjectReference(function (resolvedProjectReference, resolvedProjectReferencePath) {
                if (resolvedProjectReference && !getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
                    host.onReleaseOldSourceFile(resolvedProjectReference.sourceFile, oldProgram.getCompilerOptions(), /*hasSourceFileByPath*/ false);
                }
            });
        }
        // unconditionally set oldProgram to undefined to prevent it from being captured in closure
        oldProgram = undefined;
        var program = {
            getRootFileNames: function () { return rootNames; },
            getSourceFile: getSourceFile,
            getSourceFileByPath: getSourceFileByPath,
            getSourceFiles: function () { return files; },
            getMissingFilePaths: function () { return missingFilePaths; },
            getRefFileMap: function () { return refFileMap; },
            getFilesByNameMap: function () { return filesByName; },
            getCompilerOptions: function () { return options; },
            getSyntacticDiagnostics: getSyntacticDiagnostics,
            getOptionsDiagnostics: getOptionsDiagnostics,
            getGlobalDiagnostics: getGlobalDiagnostics,
            getSemanticDiagnostics: getSemanticDiagnostics,
            getSuggestionDiagnostics: getSuggestionDiagnostics,
            getDeclarationDiagnostics: getDeclarationDiagnostics,
            getBindAndCheckDiagnostics: getBindAndCheckDiagnostics,
            getProgramDiagnostics: getProgramDiagnostics,
            getTypeChecker: getTypeChecker,
            getClassifiableNames: getClassifiableNames,
            getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker,
            getCommonSourceDirectory: getCommonSourceDirectory,
            emit: emit,
            getCurrentDirectory: function () { return currentDirectory; },
            getNodeCount: function () { return getDiagnosticsProducingTypeChecker().getNodeCount(); },
            getIdentifierCount: function () { return getDiagnosticsProducingTypeChecker().getIdentifierCount(); },
            getSymbolCount: function () { return getDiagnosticsProducingTypeChecker().getSymbolCount(); },
            getTypeCount: function () { return getDiagnosticsProducingTypeChecker().getTypeCount(); },
            getInstantiationCount: function () { return getDiagnosticsProducingTypeChecker().getInstantiationCount(); },
            getRelationCacheSizes: function () { return getDiagnosticsProducingTypeChecker().getRelationCacheSizes(); },
            getFileProcessingDiagnostics: function () { return fileProcessingDiagnostics; },
            getResolvedTypeReferenceDirectives: function () { return resolvedTypeReferenceDirectives; },
            isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
            isSourceFileDefaultLibrary: isSourceFileDefaultLibrary,
            dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker,
            getSourceFileFromReference: getSourceFileFromReference,
            getLibFileFromReference: getLibFileFromReference,
            sourceFileToPackageName: sourceFileToPackageName,
            redirectTargetsMap: redirectTargetsMap,
            isEmittedFile: isEmittedFile,
            getConfigFileParsingDiagnostics: getConfigFileParsingDiagnostics,
            getResolvedModuleWithFailedLookupLocationsFromCache: getResolvedModuleWithFailedLookupLocationsFromCache,
            getProjectReferences: getProjectReferences,
            getResolvedProjectReferences: getResolvedProjectReferences,
            getProjectReferenceRedirect: getProjectReferenceRedirect,
            getResolvedProjectReferenceToRedirect: getResolvedProjectReferenceToRedirect,
            getResolvedProjectReferenceByPath: getResolvedProjectReferenceByPath,
            forEachResolvedProjectReference: forEachResolvedProjectReference,
            isSourceOfProjectReferenceRedirect: isSourceOfProjectReferenceRedirect,
            emitBuildInfo: emitBuildInfo,
            fileExists: fileExists,
            getProbableSymlinks: getProbableSymlinks,
            useCaseSensitiveFileNames: function () { return host.useCaseSensitiveFileNames(); },
        };
        onProgramCreateComplete();
        verifyCompilerOptions();
        ts.performance.mark("afterProgram");
        ts.performance.measure("Program", "beforeProgram", "afterProgram");
        return program;
        function resolveModuleNamesWorker(moduleNames, containingFile, reusedNames, redirectedReference) {
            ts.performance.mark("beforeResolveModule");
            var result = actualResolveModuleNamesWorker(moduleNames, containingFile, reusedNames, redirectedReference);
            ts.performance.mark("afterResolveModule");
            ts.performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule");
            return result;
        }
        function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFile, redirectedReference) {
            ts.performance.mark("beforeResolveTypeReference");
            var result = actualResolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames, containingFile, redirectedReference);
            ts.performance.mark("afterResolveTypeReference");
            ts.performance.measure("ResolveTypeReference", "beforeResolveTypeReference", "afterResolveTypeReference");
            return result;
        }
        function compareDefaultLibFiles(a, b) {
            return ts.compareValues(getDefaultLibFilePriority(a), getDefaultLibFilePriority(b));
        }
        function getDefaultLibFilePriority(a) {
            if (ts.containsPath(defaultLibraryPath, a.fileName, /*ignoreCase*/ false)) {
                var basename = ts.getBaseFileName(a.fileName);
                if (basename === "lib.d.ts" || basename === "lib.es6.d.ts")
                    return 0;
                var name = ts.removeSuffix(ts.removePrefix(basename, "lib."), ".d.ts");
                var index = ts.libs.indexOf(name);
                if (index !== -1)
                    return index + 1;
            }
            return ts.libs.length + 2;
        }
        function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile) {
            return moduleResolutionCache && ts.resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache);
        }
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function getCommonSourceDirectory() {
            if (commonSourceDirectory === undefined) {
                var emittedFiles = ts.filter(files, function (file) { return ts.sourceFileMayBeEmitted(file, program); });
                if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) {
                    // If a rootDir is specified use it as the commonSourceDirectory
                    commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory);
                }
                else if (options.composite && options.configFilePath) {
                    // Project compilations never infer their root from the input source paths
                    commonSourceDirectory = ts.getDirectoryPath(ts.normalizeSlashes(options.configFilePath));
                    checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory);
                }
                else {
                    commonSourceDirectory = computeCommonSourceDirectory(emittedFiles);
                }
                if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== ts.directorySeparator) {
                    // Make sure directory path ends with directory separator so this string can directly
                    // used to replace with "" to get the relative path of the source file and the relative path doesn't
                    // start with / making it rooted path
                    commonSourceDirectory += ts.directorySeparator;
                }
            }
            return commonSourceDirectory;
        }
        function getClassifiableNames() {
            if (!classifiableNames) {
                // Initialize a checker so that all our files are bound.
                getTypeChecker();
                classifiableNames = ts.createUnderscoreEscapedMap();
                for (var _i = 0, files_2 = files; _i < files_2.length; _i++) {
                    var sourceFile = files_2[_i];
                    ts.copyEntries(sourceFile.classifiableNames, classifiableNames);
                }
            }
            return classifiableNames;
        }
        function resolveModuleNamesReusingOldState(moduleNames, containingFile, file) {
            if (structuralIsReused === 0 /* Not */ && !file.ambientModuleNames.length) {
                // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
                // the best we can do is fallback to the default logic.
                return resolveModuleNamesWorker(moduleNames, containingFile, /*reusedNames*/ undefined, getResolvedProjectReferenceToRedirect(file.originalFileName));
            }
            var oldSourceFile = oldProgram && oldProgram.getSourceFile(containingFile);
            if (oldSourceFile !== file && file.resolvedModules) {
                // `file` was created for the new program.
                //
                // We only set `file.resolvedModules` via work from the current function,
                // so it is defined iff we already called the current function on `file`.
                // That call happened no later than the creation of the `file` object,
                // which per above occurred during the current program creation.
                // Since we assume the filesystem does not change during program creation,
                // it is safe to reuse resolutions from the earlier call.
                var result_11 = [];
                for (var _i = 0, moduleNames_1 = moduleNames; _i < moduleNames_1.length; _i++) {
                    var moduleName = moduleNames_1[_i];
                    var resolvedModule = file.resolvedModules.get(moduleName);
                    result_11.push(resolvedModule);
                }
                return result_11;
            }
            // At this point, we know at least one of the following hold:
            // - file has local declarations for ambient modules
            // - old program state is available
            // With this information, we can infer some module resolutions without performing resolution.
            /** An ordered list of module names for which we cannot recover the resolution. */
            var unknownModuleNames;
            /**
             * The indexing of elements in this list matches that of `moduleNames`.
             *
             * Before combining results, result[i] is in one of the following states:
             * * undefined: needs to be recomputed,
             * * predictedToResolveToAmbientModuleMarker: known to be an ambient module.
             * Needs to be reset to undefined before returning,
             * * ResolvedModuleFull instance: can be reused.
             */
            var result;
            var reusedNames;
            /** A transient placeholder used to mark predicted resolution in the result list. */
            var predictedToResolveToAmbientModuleMarker = {};
            for (var i = 0; i < moduleNames.length; i++) {
                var moduleName = moduleNames[i];
                // If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
                if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) {
                    var oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules.get(moduleName);
                    if (oldResolvedModule) {
                        if (ts.isTraceEnabled(options, host)) {
                            ts.trace(host, ts.Diagnostics.Reusing_resolution_of_module_0_to_file_1_from_old_program, moduleName, containingFile);
                        }
                        (result || (result = new Array(moduleNames.length)))[i] = oldResolvedModule;
                        (reusedNames || (reusedNames = [])).push(moduleName);
                        continue;
                    }
                }
                // We know moduleName resolves to an ambient module provided that moduleName:
                // - is in the list of ambient modules locally declared in the current source file.
                // - resolved to an ambient module in the old program whose declaration is in an unmodified file
                //   (so the same module declaration will land in the new program)
                var resolvesToAmbientModuleInNonModifiedFile = false;
                if (ts.contains(file.ambientModuleNames, moduleName)) {
                    resolvesToAmbientModuleInNonModifiedFile = true;
                    if (ts.isTraceEnabled(options, host)) {
                        ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, containingFile);
                    }
                }
                else {
                    resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName);
                }
                if (resolvesToAmbientModuleInNonModifiedFile) {
                    (result || (result = new Array(moduleNames.length)))[i] = predictedToResolveToAmbientModuleMarker;
                }
                else {
                    // Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result.
                    (unknownModuleNames || (unknownModuleNames = [])).push(moduleName);
                }
            }
            var resolutions = unknownModuleNames && unknownModuleNames.length
                ? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames, getResolvedProjectReferenceToRedirect(file.originalFileName))
                : ts.emptyArray;
            // Combine results of resolutions and predicted results
            if (!result) {
                // There were no unresolved/ambient resolutions.
                ts.Debug.assert(resolutions.length === moduleNames.length);
                return resolutions;
            }
            var j = 0;
            for (var i = 0; i < result.length; i++) {
                if (result[i]) {
                    // `result[i]` is either a `ResolvedModuleFull` or a marker.
                    // If it is the former, we can leave it as is.
                    if (result[i] === predictedToResolveToAmbientModuleMarker) {
                        result[i] = undefined; // TODO: GH#18217
                    }
                }
                else {
                    result[i] = resolutions[j];
                    j++;
                }
            }
            ts.Debug.assert(j === resolutions.length);
            return result;
            // If we change our policy of rechecking failed lookups on each program create,
            // we should adjust the value returned here.
            function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName) {
                var resolutionToFile = ts.getResolvedModule(oldSourceFile, moduleName);
                var resolvedFile = resolutionToFile && oldProgram.getSourceFile(resolutionToFile.resolvedFileName);
                if (resolutionToFile && resolvedFile) {
                    // In the old program, we resolved to an ambient module that was in the same
                    //   place as we expected to find an actual module file.
                    // We actually need to return 'false' here even though this seems like a 'true' case
                    //   because the normal module resolution algorithm will find this anyway.
                    return false;
                }
                // at least one of declarations should come from non-modified source file
                var unmodifiedFile = ambientModuleNameToUnmodifiedFileName.get(moduleName);
                if (!unmodifiedFile) {
                    return false;
                }
                if (ts.isTraceEnabled(options, host)) {
                    ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, unmodifiedFile);
                }
                return true;
            }
        }
        function canReuseProjectReferences() {
            return !forEachProjectReference(oldProgram.getProjectReferences(), oldProgram.getResolvedProjectReferences(), function (oldResolvedRef, index, parent) {
                var newRef = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var newResolvedRef = parseProjectReferenceConfigFile(newRef);
                if (oldResolvedRef) {
                    // Resolved project reference has gone missing or changed
                    return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile;
                }
                else {
                    // A previously-unresolved reference may be resolved now
                    return newResolvedRef !== undefined;
                }
            }, function (oldProjectReferences, parent) {
                // If array of references is changed, we cant resue old program
                var newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path).commandLine.projectReferences : projectReferences;
                return !ts.arrayIsEqualTo(oldProjectReferences, newReferences, ts.projectReferenceIsEqualTo);
            });
        }
        function tryReuseStructureFromOldProgram() {
            if (!oldProgram) {
                return 0 /* Not */;
            }
            // check properties that can affect structure of the program or module resolution strategy
            // if any of these properties has changed - structure cannot be reused
            var oldOptions = oldProgram.getCompilerOptions();
            if (ts.changesAffectModuleResolution(oldOptions, options)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            ts.Debug.assert(!(oldProgram.structureIsReused & (2 /* Completely */ | 1 /* SafeModules */)));
            // there is an old program, check if we can reuse its structure
            var oldRootNames = oldProgram.getRootFileNames();
            if (!ts.arrayIsEqualTo(oldRootNames, rootNames)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            if (!ts.arrayIsEqualTo(options.types, oldOptions.types)) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            // Check if any referenced project tsconfig files are different
            if (!canReuseProjectReferences()) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            if (projectReferences) {
                resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
            }
            // check if program source files has changed in the way that can affect structure of the program
            var newSourceFiles = [];
            var modifiedSourceFiles = [];
            oldProgram.structureIsReused = 2 /* Completely */;
            // If the missing file paths are now present, it can change the progam structure,
            // and hence cant reuse the structure.
            // This is same as how we dont reuse the structure if one of the file from old program is now missing
            if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) {
                return oldProgram.structureIsReused = 0 /* Not */;
            }
            var oldSourceFiles = oldProgram.getSourceFiles();
            var SeenPackageName;
            (function (SeenPackageName) {
                SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists";
                SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified";
            })(SeenPackageName || (SeenPackageName = {}));
            var seenPackageNames = ts.createMap();
            for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) {
                var oldSourceFile = oldSourceFiles_2[_i];
                var newSourceFile = host.getSourceFileByPath
                    ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.resolvedPath, options.target, /*onError*/ undefined, shouldCreateNewSourceFile)
                    : host.getSourceFile(oldSourceFile.fileName, options.target, /*onError*/ undefined, shouldCreateNewSourceFile); // TODO: GH#18217
                if (!newSourceFile) {
                    return oldProgram.structureIsReused = 0 /* Not */;
                }
                ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`");
                var fileChanged = void 0;
                if (oldSourceFile.redirectInfo) {
                    // We got `newSourceFile` by path, so it is actually for the unredirected file.
                    // This lets us know if the unredirected file has changed. If it has we should break the redirect.
                    if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) {
                        // Underlying file has changed. Might not redirect anymore. Must rebuild program.
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    fileChanged = false;
                    newSourceFile = oldSourceFile; // Use the redirect.
                }
                else if (oldProgram.redirectTargetsMap.has(oldSourceFile.path)) {
                    // If a redirected-to source file changes, the redirect may be broken.
                    if (newSourceFile !== oldSourceFile) {
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    fileChanged = false;
                }
                else {
                    fileChanged = newSourceFile !== oldSourceFile;
                }
                // Since the project references havent changed, its right to set originalFileName and resolvedPath here
                newSourceFile.path = oldSourceFile.path;
                newSourceFile.originalFileName = oldSourceFile.originalFileName;
                newSourceFile.resolvedPath = oldSourceFile.resolvedPath;
                newSourceFile.fileName = oldSourceFile.fileName;
                var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
                if (packageName !== undefined) {
                    // If there are 2 different source files for the same package name and at least one of them changes,
                    // they might become redirects. So we must rebuild the program.
                    var prevKind = seenPackageNames.get(packageName);
                    var newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */;
                    if ((prevKind !== undefined && newKind === 1 /* Modified */) || prevKind === 1 /* Modified */) {
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    seenPackageNames.set(packageName, newKind);
                }
                if (fileChanged) {
                    // The `newSourceFile` object was created for the new program.
                    if (!ts.arrayIsEqualTo(oldSourceFile.libReferenceDirectives, newSourceFile.libReferenceDirectives, fileReferenceIsEqualTo)) {
                        // 'lib' references has changed. Matches behavior in changesAffectModuleResolution
                        return oldProgram.structureIsReused = 0 /* Not */;
                    }
                    if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) {
                        // value of no-default-lib has changed
                        // this will affect if default library is injected into the list of files
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // check tripleslash references
                    if (!ts.arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) {
                        // tripleslash references has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // check imports and module augmentations
                    collectExternalModuleReferences(newSourceFile);
                    if (!ts.arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) {
                        // imports has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) {
                        // moduleAugmentations has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if ((oldSourceFile.flags & 3145728 /* PermanentlySetIncrementalFlags */) !== (newSourceFile.flags & 3145728 /* PermanentlySetIncrementalFlags */)) {
                        // dynamicImport has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    if (!ts.arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
                        // 'types' references has changed
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                    }
                    // tentatively approve the file
                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
                }
                else if (hasInvalidatedResolution(oldSourceFile.path)) {
                    // 'module/types' references could have changed
                    oldProgram.structureIsReused = 1 /* SafeModules */;
                    // add file to the modified list so that we will resolve it later
                    modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
                }
                // if file has passed all checks it should be safe to reuse it
                newSourceFiles.push(newSourceFile);
            }
            if (oldProgram.structureIsReused !== 2 /* Completely */) {
                return oldProgram.structureIsReused;
            }
            var modifiedFiles = modifiedSourceFiles.map(function (f) { return f.oldFile; });
            for (var _a = 0, oldSourceFiles_3 = oldSourceFiles; _a < oldSourceFiles_3.length; _a++) {
                var oldFile = oldSourceFiles_3[_a];
                if (!ts.contains(modifiedFiles, oldFile)) {
                    for (var _b = 0, _c = oldFile.ambientModuleNames; _b < _c.length; _b++) {
                        var moduleName = _c[_b];
                        ambientModuleNameToUnmodifiedFileName.set(moduleName, oldFile.fileName);
                    }
                }
            }
            // try to verify results of module resolution
            for (var _d = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _d < modifiedSourceFiles_1.length; _d++) {
                var _e = modifiedSourceFiles_1[_d], oldSourceFile = _e.oldFile, newSourceFile = _e.newFile;
                var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.originalFileName, currentDirectory);
                var moduleNames = getModuleNames(newSourceFile);
                var resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile);
                // ensure that module resolution results are still correct
                var resolutionsChanged = ts.hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, ts.moduleResolutionIsEqualTo);
                if (resolutionsChanged) {
                    oldProgram.structureIsReused = 1 /* SafeModules */;
                    newSourceFile.resolvedModules = ts.zipToMap(moduleNames, resolutions);
                }
                else {
                    newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
                }
                if (resolveTypeReferenceDirectiveNamesWorker) {
                    // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
                    var typesReferenceDirectives = ts.map(newSourceFile.typeReferenceDirectives, function (ref) { return ts.toFileNameLowerCase(ref.fileName); });
                    var resolutions_1 = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath, getResolvedProjectReferenceToRedirect(newSourceFile.originalFileName));
                    // ensure that types resolutions are still correct
                    var resolutionsChanged_1 = ts.hasChangesInResolutions(typesReferenceDirectives, resolutions_1, oldSourceFile.resolvedTypeReferenceDirectiveNames, ts.typeDirectiveIsEqualTo);
                    if (resolutionsChanged_1) {
                        oldProgram.structureIsReused = 1 /* SafeModules */;
                        newSourceFile.resolvedTypeReferenceDirectiveNames = ts.zipToMap(typesReferenceDirectives, resolutions_1);
                    }
                    else {
                        newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
                    }
                }
            }
            if (oldProgram.structureIsReused !== 2 /* Completely */) {
                return oldProgram.structureIsReused;
            }
            if (host.hasChangedAutomaticTypeDirectiveNames) {
                return oldProgram.structureIsReused = 1 /* SafeModules */;
            }
            missingFilePaths = oldProgram.getMissingFilePaths();
            refFileMap = oldProgram.getRefFileMap();
            // update fileName -> file mapping
            ts.Debug.assert(newSourceFiles.length === oldProgram.getSourceFiles().length);
            for (var _f = 0, newSourceFiles_1 = newSourceFiles; _f < newSourceFiles_1.length; _f++) {
                var newSourceFile = newSourceFiles_1[_f];
                filesByName.set(newSourceFile.path, newSourceFile);
            }
            var oldFilesByNameMap = oldProgram.getFilesByNameMap();
            oldFilesByNameMap.forEach(function (oldFile, path) {
                if (!oldFile) {
                    filesByName.set(path, oldFile);
                    return;
                }
                if (oldFile.path === path) {
                    // Set the file as found during node modules search if it was found that way in old progra,
                    if (oldProgram.isSourceFileFromExternalLibrary(oldFile)) {
                        sourceFilesFoundSearchingNodeModules.set(oldFile.path, true);
                    }
                    return;
                }
                filesByName.set(path, filesByName.get(oldFile.path));
            });
            files = newSourceFiles;
            fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
            for (var _g = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _g < modifiedSourceFiles_2.length; _g++) {
                var modifiedFile = modifiedSourceFiles_2[_g];
                fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
            }
            resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
            sourceFileToPackageName = oldProgram.sourceFileToPackageName;
            redirectTargetsMap = oldProgram.redirectTargetsMap;
            return oldProgram.structureIsReused = 2 /* Completely */;
        }
        function getEmitHost(writeFileCallback) {
            return {
                getPrependNodes: getPrependNodes,
                getCanonicalFileName: getCanonicalFileName,
                getCommonSourceDirectory: program.getCommonSourceDirectory,
                getCompilerOptions: program.getCompilerOptions,
                getCurrentDirectory: function () { return currentDirectory; },
                getNewLine: function () { return host.getNewLine(); },
                getSourceFile: program.getSourceFile,
                getSourceFileByPath: program.getSourceFileByPath,
                getSourceFiles: program.getSourceFiles,
                getLibFileFromReference: program.getLibFileFromReference,
                isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary,
                getResolvedProjectReferenceToRedirect: getResolvedProjectReferenceToRedirect,
                getProjectReferenceRedirect: getProjectReferenceRedirect,
                isSourceOfProjectReferenceRedirect: isSourceOfProjectReferenceRedirect,
                getProbableSymlinks: getProbableSymlinks,
                writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }),
                isEmitBlocked: isEmitBlocked,
                readFile: function (f) { return host.readFile(f); },
                fileExists: function (f) {
                    // Use local caches
                    var path = toPath(f);
                    if (getSourceFileByPath(path))
                        return true;
                    if (ts.contains(missingFilePaths, path))
                        return false;
                    // Before falling back to the host
                    return host.fileExists(f);
                },
                useCaseSensitiveFileNames: function () { return host.useCaseSensitiveFileNames(); },
                getProgramBuildInfo: function () { return program.getProgramBuildInfo && program.getProgramBuildInfo(); },
                getSourceFileFromReference: function (file, ref) { return program.getSourceFileFromReference(file, ref); },
                redirectTargetsMap: redirectTargetsMap,
            };
        }
        function emitBuildInfo(writeFileCallback) {
            ts.Debug.assert(!options.out && !options.outFile);
            ts.performance.mark("beforeEmit");
            var emitResult = ts.emitFiles(ts.notImplementedResolver, getEmitHost(writeFileCallback), 
            /*targetSourceFile*/ undefined, 
            /*transformers*/ ts.noTransformers, 
            /*emitOnlyDtsFiles*/ false, 
            /*onlyBuildInfo*/ true);
            ts.performance.mark("afterEmit");
            ts.performance.measure("Emit", "beforeEmit", "afterEmit");
            return emitResult;
        }
        function getResolvedProjectReferences() {
            return resolvedProjectReferences;
        }
        function getProjectReferences() {
            return projectReferences;
        }
        function getPrependNodes() {
            return createPrependNodes(projectReferences, function (_ref, index) { return resolvedProjectReferences[index].commandLine; }, function (fileName) {
                var path = toPath(fileName);
                var sourceFile = getSourceFileByPath(path);
                return sourceFile ? sourceFile.text : filesByName.has(path) ? undefined : host.readFile(path);
            });
        }
        function isSourceFileFromExternalLibrary(file) {
            return !!sourceFilesFoundSearchingNodeModules.get(file.path);
        }
        function isSourceFileDefaultLibrary(file) {
            if (file.hasNoDefaultLib) {
                return true;
            }
            if (!options.noLib) {
                return false;
            }
            // If '--lib' is not specified, include default library file according to '--target'
            // otherwise, using options specified in '--lib' instead of '--target' default library file
            var equalityComparer = host.useCaseSensitiveFileNames() ? ts.equateStringsCaseSensitive : ts.equateStringsCaseInsensitive;
            if (!options.lib) {
                return equalityComparer(file.fileName, getDefaultLibraryFileName());
            }
            else {
                return ts.some(options.lib, function (libFileName) { return equalityComparer(file.fileName, ts.combinePaths(defaultLibraryPath, libFileName)); });
            }
        }
        function getDiagnosticsProducingTypeChecker() {
            return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ true));
        }
        function dropDiagnosticsProducingTypeChecker() {
            diagnosticsProducingTypeChecker = undefined;
        }
        function getTypeChecker() {
            return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false));
        }
        function emit(sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers, forceDtsEmit) {
            return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers, forceDtsEmit); });
        }
        function isEmitBlocked(emitFileName) {
            return hasEmitBlockingDiagnostics.has(toPath(emitFileName));
        }
        function emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, customTransformers, forceDtsEmit) {
            if (!forceDtsEmit) {
                var result = handleNoEmitOptions(program, sourceFile, cancellationToken);
                if (result)
                    return result;
            }
            // Create the emit resolver outside of the "emitTime" tracking code below.  That way
            // any cost associated with it (like type checking) are appropriate associated with
            // the type-checking counter.
            //
            // If the -out option is specified, we should not pass the source file to getEmitResolver.
            // This is because in the -out scenario all files need to be emitted, and therefore all
            // files need to be type checked. And the way to specify that all files need to be type
            // checked is to not pass the file to getEmitResolver.
            var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken);
            ts.performance.mark("beforeEmit");
            var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile, ts.getTransformers(options, customTransformers, emitOnlyDtsFiles), emitOnlyDtsFiles, 
            /*onlyBuildInfo*/ false, forceDtsEmit);
            ts.performance.mark("afterEmit");
            ts.performance.measure("Emit", "beforeEmit", "afterEmit");
            return emitResult;
        }
        function getSourceFile(fileName) {
            return getSourceFileByPath(toPath(fileName));
        }
        function getSourceFileByPath(path) {
            return filesByName.get(path) || undefined;
        }
        function getDiagnosticsHelper(sourceFile, getDiagnostics, cancellationToken) {
            if (sourceFile) {
                return getDiagnostics(sourceFile, cancellationToken);
            }
            return ts.sortAndDeduplicateDiagnostics(ts.flatMap(program.getSourceFiles(), function (sourceFile) {
                if (cancellationToken) {
                    cancellationToken.throwIfCancellationRequested();
                }
                return getDiagnostics(sourceFile, cancellationToken);
            }));
        }
        function getSyntacticDiagnostics(sourceFile, cancellationToken) {
            return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken);
        }
        function getSemanticDiagnostics(sourceFile, cancellationToken) {
            return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken);
        }
        function getBindAndCheckDiagnostics(sourceFile, cancellationToken) {
            return getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken);
        }
        function getProgramDiagnostics(sourceFile) {
            if (ts.skipTypeChecking(sourceFile, options, program)) {
                return ts.emptyArray;
            }
            var fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
            var programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
            return getMergedProgramDiagnostics(sourceFile, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
        }
        function getMergedProgramDiagnostics(sourceFile) {
            var _a;
            var allDiagnostics = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                allDiagnostics[_i - 1] = arguments[_i];
            }
            var flatDiagnostics = ts.flatten(allDiagnostics);
            if (!((_a = sourceFile.commentDirectives) === null || _a === void 0 ? void 0 : _a.length)) {
                return flatDiagnostics;
            }
            return getDiagnosticsWithPrecedingDirectives(sourceFile, sourceFile.commentDirectives, flatDiagnostics).diagnostics;
        }
        function getDeclarationDiagnostics(sourceFile, cancellationToken) {
            var options = program.getCompilerOptions();
            // collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit)
            if (!sourceFile || options.out || options.outFile) {
                return getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
            }
            else {
                return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken);
            }
        }
        function getSyntacticDiagnosticsForFile(sourceFile) {
            // For JavaScript files, we report semantic errors for using TypeScript-only
            // constructs from within a JavaScript file as syntactic errors.
            if (ts.isSourceFileJS(sourceFile)) {
                if (!sourceFile.additionalSyntacticDiagnostics) {
                    sourceFile.additionalSyntacticDiagnostics = getJSSyntacticDiagnosticsForFile(sourceFile);
                }
                return ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
            }
            return sourceFile.parseDiagnostics;
        }
        function runWithCancellationToken(func) {
            try {
                return func();
            }
            catch (e) {
                if (e instanceof ts.OperationCanceledException) {
                    // We were canceled while performing the operation.  Because our type checker
                    // might be a bad state, we need to throw it away.
                    //
                    // Note: we are overly aggressive here.  We do not actually *have* to throw away
                    // the "noDiagnosticsTypeChecker".  However, for simplicity, i'd like to keep
                    // the lifetimes of these two TypeCheckers the same.  Also, we generally only
                    // cancel when the user has made a change anyways.  And, in that case, we (the
                    // program instance) will get thrown away anyways.  So trying to keep one of
                    // these type checkers alive doesn't serve much purpose.
                    noDiagnosticsTypeChecker = undefined;
                    diagnosticsProducingTypeChecker = undefined;
                }
                throw e;
            }
        }
        function getSemanticDiagnosticsForFile(sourceFile, cancellationToken) {
            return ts.concatenate(getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken), getProgramDiagnostics(sourceFile));
        }
        function getBindAndCheckDiagnosticsForFile(sourceFile, cancellationToken) {
            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedBindAndCheckDiagnosticsForFile, getBindAndCheckDiagnosticsForFileNoCache);
        }
        function getBindAndCheckDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                if (ts.skipTypeChecking(sourceFile, options, program)) {
                    return ts.emptyArray;
                }
                var typeChecker = getDiagnosticsProducingTypeChecker();
                ts.Debug.assert(!!sourceFile.bindDiagnostics);
                var isCheckJs = ts.isCheckJsEnabledForFile(sourceFile, options);
                var isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false;
                // By default, only type-check .ts, .tsx, 'Deferred' and 'External' files (external files are added by plugins)
                var includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === 3 /* TS */ || sourceFile.scriptKind === 4 /* TSX */ ||
                    sourceFile.scriptKind === 5 /* External */ || isCheckJs || sourceFile.scriptKind === 7 /* Deferred */);
                var bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : ts.emptyArray;
                var checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : ts.emptyArray;
                return getMergedBindAndCheckDiagnostics(sourceFile, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined);
            });
        }
        function getMergedBindAndCheckDiagnostics(sourceFile) {
            var _a;
            var allDiagnostics = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                allDiagnostics[_i - 1] = arguments[_i];
            }
            var flatDiagnostics = ts.flatten(allDiagnostics);
            if (!((_a = sourceFile.commentDirectives) === null || _a === void 0 ? void 0 : _a.length)) {
                return flatDiagnostics;
            }
            var _b = getDiagnosticsWithPrecedingDirectives(sourceFile, sourceFile.commentDirectives, flatDiagnostics), diagnostics = _b.diagnostics, directives = _b.directives;
            for (var _c = 0, _d = directives.getUnusedExpectations(); _c < _d.length; _c++) {
                var errorExpectation = _d[_c];
                diagnostics.push(ts.createDiagnosticForRange(sourceFile, errorExpectation.range, ts.Diagnostics.Unused_ts_expect_error_directive));
            }
            return diagnostics;
        }
        /**
         * Creates a map of comment directives along with the diagnostics immediately preceded by one of them.
         * Comments that match to any of those diagnostics are marked as used.
         */
        function getDiagnosticsWithPrecedingDirectives(sourceFile, commentDirectives, flatDiagnostics) {
            // Diagnostics are only reported if there is no comment directive preceding them
            // This will modify the directives map by marking "used" ones with a corresponding diagnostic
            var directives = ts.createCommentDirectivesMap(sourceFile, commentDirectives);
            var diagnostics = flatDiagnostics.filter(function (diagnostic) { return markPrecedingCommentDirectiveLine(diagnostic, directives) === -1; });
            return { diagnostics: diagnostics, directives: directives };
        }
        function getSuggestionDiagnostics(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                return getDiagnosticsProducingTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken);
            });
        }
        /**
         * @returns The line index marked as preceding the diagnostic, or -1 if none was.
         */
        function markPrecedingCommentDirectiveLine(diagnostic, directives) {
            var file = diagnostic.file, start = diagnostic.start;
            if (!file) {
                return -1;
            }
            // Start out with the line just before the text
            var lineStarts = ts.getLineStarts(file);
            var line = ts.computeLineAndCharacterOfPosition(lineStarts, start).line - 1; // TODO: GH#18217
            while (line >= 0) {
                // As soon as that line is known to have a comment directive, use that
                if (directives.markUsed(line)) {
                    return line;
                }
                // Stop searching if the line is not empty and not a comment
                var lineText = file.text.slice(lineStarts[line], lineStarts[line + 1]).trim();
                if (lineText !== "" && !/^(\s*)\/\/(.*)$/.test(lineText)) {
                    return -1;
                }
                line--;
            }
            return -1;
        }
        function getJSSyntacticDiagnosticsForFile(sourceFile) {
            return runWithCancellationToken(function () {
                var diagnostics = [];
                walk(sourceFile, sourceFile);
                ts.forEachChildRecursively(sourceFile, walk, walkArray);
                return diagnostics;
                function walk(node, parent) {
                    // Return directly from the case if the given node doesnt want to visit each child
                    // Otherwise break to visit each child
                    switch (parent.kind) {
                        case 156 /* Parameter */:
                        case 159 /* PropertyDeclaration */:
                        case 161 /* MethodDeclaration */:
                            if (parent.questionToken === node) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, "?"));
                                return "skip";
                            }
                        // falls through
                        case 160 /* MethodSignature */:
                        case 162 /* Constructor */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                        case 201 /* FunctionExpression */:
                        case 244 /* FunctionDeclaration */:
                        case 202 /* ArrowFunction */:
                        case 242 /* VariableDeclaration */:
                            // type annotation
                            if (parent.type === node) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Type_annotations_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                    }
                    switch (node.kind) {
                        case 255 /* ImportClause */:
                            if (node.isTypeOnly) {
                                diagnostics.push(createDiagnosticForNode(node.parent, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "import type"));
                                return "skip";
                            }
                            break;
                        case 260 /* ExportDeclaration */:
                            if (node.isTypeOnly) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, "export type"));
                                return "skip";
                            }
                            break;
                        case 253 /* ImportEqualsDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.import_can_only_be_used_in_TypeScript_files));
                            return "skip";
                        case 259 /* ExportAssignment */:
                            if (node.isExportEquals) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.export_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                            break;
                        case 279 /* HeritageClause */:
                            var heritageClause = node;
                            if (heritageClause.token === 113 /* ImplementsKeyword */) {
                                diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.implements_clauses_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                            break;
                        case 246 /* InterfaceDeclaration */:
                            var interfaceKeyword = ts.tokenToString(114 /* InterfaceKeyword */);
                            ts.Debug.assertIsDefined(interfaceKeyword);
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, interfaceKeyword));
                            return "skip";
                        case 249 /* ModuleDeclaration */:
                            var moduleKeyword = node.flags & 16 /* Namespace */ ? ts.tokenToString(136 /* NamespaceKeyword */) : ts.tokenToString(135 /* ModuleKeyword */);
                            ts.Debug.assertIsDefined(moduleKeyword);
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, moduleKeyword));
                            return "skip";
                        case 247 /* TypeAliasDeclaration */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Type_aliases_can_only_be_used_in_TypeScript_files));
                            return "skip";
                        case 248 /* EnumDeclaration */:
                            var enumKeyword = ts.Debug.checkDefined(ts.tokenToString(88 /* EnumKeyword */));
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_declarations_can_only_be_used_in_TypeScript_files, enumKeyword));
                            return "skip";
                        case 218 /* NonNullExpression */:
                            diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Non_null_assertions_can_only_be_used_in_TypeScript_files));
                            return "skip";
                        case 217 /* AsExpression */:
                            diagnostics.push(createDiagnosticForNode(node.type, ts.Diagnostics.Type_assertion_expressions_can_only_be_used_in_TypeScript_files));
                            return "skip";
                        case 199 /* TypeAssertionExpression */:
                            ts.Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX.
                    }
                }
                function walkArray(nodes, parent) {
                    if (parent.decorators === nodes && !options.experimentalDecorators) {
                        diagnostics.push(createDiagnosticForNode(parent, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_in_your_tsconfig_or_jsconfig_to_remove_this_warning));
                    }
                    switch (parent.kind) {
                        case 245 /* ClassDeclaration */:
                        case 214 /* ClassExpression */:
                        case 161 /* MethodDeclaration */:
                        case 162 /* Constructor */:
                        case 163 /* GetAccessor */:
                        case 164 /* SetAccessor */:
                        case 201 /* FunctionExpression */:
                        case 244 /* FunctionDeclaration */:
                        case 202 /* ArrowFunction */:
                            // Check type parameters
                            if (nodes === parent.typeParameters) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Type_parameter_declarations_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                        // falls through
                        case 225 /* VariableStatement */:
                            // Check modifiers
                            if (nodes === parent.modifiers) {
                                checkModifiers(parent.modifiers, parent.kind === 225 /* VariableStatement */);
                                return "skip";
                            }
                            break;
                        case 159 /* PropertyDeclaration */:
                            // Check modifiers of property declaration
                            if (nodes === parent.modifiers) {
                                for (var _i = 0, _a = nodes; _i < _a.length; _i++) {
                                    var modifier = _a[_i];
                                    if (modifier.kind !== 120 /* StaticKeyword */) {
                                        diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, ts.tokenToString(modifier.kind)));
                                    }
                                }
                                return "skip";
                            }
                            break;
                        case 156 /* Parameter */:
                            // Check modifiers of parameter declaration
                            if (nodes === parent.modifiers) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Parameter_modifiers_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                            break;
                        case 196 /* CallExpression */:
                        case 197 /* NewExpression */:
                        case 216 /* ExpressionWithTypeArguments */:
                        case 267 /* JsxSelfClosingElement */:
                        case 268 /* JsxOpeningElement */:
                        case 198 /* TaggedTemplateExpression */:
                            // Check type arguments
                            if (nodes === parent.typeArguments) {
                                diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.Type_arguments_can_only_be_used_in_TypeScript_files));
                                return "skip";
                            }
                            break;
                    }
                }
                function checkModifiers(modifiers, isConstValid) {
                    for (var _i = 0, modifiers_1 = modifiers; _i < modifiers_1.length; _i++) {
                        var modifier = modifiers_1[_i];
                        switch (modifier.kind) {
                            case 81 /* ConstKeyword */:
                                if (isConstValid) {
                                    continue;
                                }
                            // to report error,
                            // falls through
                            case 119 /* PublicKeyword */:
                            case 117 /* PrivateKeyword */:
                            case 118 /* ProtectedKeyword */:
                            case 138 /* ReadonlyKeyword */:
                            case 130 /* DeclareKeyword */:
                            case 122 /* AbstractKeyword */:
                                diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics.The_0_modifier_can_only_be_used_in_TypeScript_files, ts.tokenToString(modifier.kind)));
                                break;
                            // These are all legal modifiers.
                            case 120 /* StaticKeyword */:
                            case 89 /* ExportKeyword */:
                            case 84 /* DefaultKeyword */:
                        }
                    }
                }
                function createDiagnosticForNodeArray(nodes, message, arg0, arg1, arg2) {
                    var start = nodes.pos;
                    return ts.createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2);
                }
                // Since these are syntactic diagnostics, parent might not have been set
                // this means the sourceFile cannot be infered from the node
                function createDiagnosticForNode(node, message, arg0, arg1, arg2) {
                    return ts.createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
                }
            });
        }
        function getDeclarationDiagnosticsWorker(sourceFile, cancellationToken) {
            return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache);
        }
        function getDeclarationDiagnosticsForFileNoCache(sourceFile, cancellationToken) {
            return runWithCancellationToken(function () {
                var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
                // Don't actually write any files since we're just getting diagnostics.
                return ts.getDeclarationDiagnostics(getEmitHost(ts.noop), resolver, sourceFile) || ts.emptyArray;
            });
        }
        function getAndCacheDiagnostics(sourceFile, cancellationToken, cache, getDiagnostics) {
            var cachedResult = sourceFile
                ? cache.perFile && cache.perFile.get(sourceFile.path)
                : cache.allDiagnostics;
            if (cachedResult) {
                return cachedResult;
            }
            var result = getDiagnostics(sourceFile, cancellationToken);
            if (sourceFile) {
                if (!cache.perFile) {
                    cache.perFile = ts.createMap();
                }
                cache.perFile.set(sourceFile.path, result);
            }
            else {
                cache.allDiagnostics = result;
            }
            return result;
        }
        function getDeclarationDiagnosticsForFile(sourceFile, cancellationToken) {
            return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
        }
        function getOptionsDiagnostics() {
            return ts.sortAndDeduplicateDiagnostics(ts.concatenate(fileProcessingDiagnostics.getGlobalDiagnostics(), ts.concatenate(programDiagnostics.getGlobalDiagnostics(), getOptionsDiagnosticsOfConfigFile())));
        }
        function getOptionsDiagnosticsOfConfigFile() {
            if (!options.configFile) {
                return ts.emptyArray;
            }
            var diagnostics = programDiagnostics.getDiagnostics(options.configFile.fileName);
            forEachResolvedProjectReference(function (resolvedRef) {
                if (resolvedRef) {
                    diagnostics = ts.concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName));
                }
            });
            return diagnostics;
        }
        function getGlobalDiagnostics() {
            return rootNames.length ? ts.sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice()) : ts.emptyArray;
        }
        function getConfigFileParsingDiagnostics() {
            return configFileParsingDiagnostics || ts.emptyArray;
        }
        function processRootFile(fileName, isDefaultLib, ignoreNoDefaultLib) {
            processSourceFile(ts.normalizePath(fileName), isDefaultLib, ignoreNoDefaultLib, /*packageId*/ undefined);
        }
        function fileReferenceIsEqualTo(a, b) {
            return a.fileName === b.fileName;
        }
        function moduleNameIsEqualTo(a, b) {
            return a.kind === 75 /* Identifier */
                ? b.kind === 75 /* Identifier */ && a.escapedText === b.escapedText
                : b.kind === 10 /* StringLiteral */ && a.text === b.text;
        }
        function collectExternalModuleReferences(file) {
            if (file.imports) {
                return;
            }
            var isJavaScriptFile = ts.isSourceFileJS(file);
            var isExternalModuleFile = ts.isExternalModule(file);
            // file.imports may not be undefined if there exists dynamic import
            var imports;
            var moduleAugmentations;
            var ambientModules;
            // If we are importing helpers, we need to add a synthetic reference to resolve the
            // helpers library.
            if (options.importHelpers
                && (options.isolatedModules || isExternalModuleFile)
                && !file.isDeclarationFile) {
                // synthesize 'import "tslib"' declaration
                var externalHelpersModuleReference = ts.createLiteral(ts.externalHelpersModuleNameText);
                var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference);
                ts.addEmitFlags(importDecl, 67108864 /* NeverApplyImportHelper */);
                externalHelpersModuleReference.parent = importDecl;
                importDecl.parent = file;
                imports = [externalHelpersModuleReference];
            }
            for (var _i = 0, _a = file.statements; _i < _a.length; _i++) {
                var node = _a[_i];
                collectModuleReferences(node, /*inAmbientModule*/ false);
            }
            if ((file.flags & 1048576 /* PossiblyContainsDynamicImport */) || isJavaScriptFile) {
                collectDynamicImportOrRequireCalls(file);
            }
            file.imports = imports || ts.emptyArray;
            file.moduleAugmentations = moduleAugmentations || ts.emptyArray;
            file.ambientModuleNames = ambientModules || ts.emptyArray;
            return;
            function collectModuleReferences(node, inAmbientModule) {
                if (ts.isAnyImportOrReExport(node)) {
                    var moduleNameExpr = ts.getExternalModuleName(node);
                    // TypeScript 1.0 spec (April 2014): 12.1.6
                    // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules
                    // only through top - level external module names. Relative external module names are not permitted.
                    if (moduleNameExpr && ts.isStringLiteral(moduleNameExpr) && moduleNameExpr.text && (!inAmbientModule || !ts.isExternalModuleNameRelative(moduleNameExpr.text))) {
                        imports = ts.append(imports, moduleNameExpr);
                    }
                }
                else if (ts.isModuleDeclaration(node)) {
                    if (ts.isAmbientModule(node) && (inAmbientModule || ts.hasModifier(node, 2 /* Ambient */) || file.isDeclarationFile)) {
                        var nameText = ts.getTextOfIdentifierOrLiteral(node.name);
                        // Ambient module declarations can be interpreted as augmentations for some existing external modules.
                        // This will happen in two cases:
                        // - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope
                        // - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name
                        //   immediately nested in top level ambient module declaration .
                        if (isExternalModuleFile || (inAmbientModule && !ts.isExternalModuleNameRelative(nameText))) {
                            (moduleAugmentations || (moduleAugmentations = [])).push(node.name);
                        }
                        else if (!inAmbientModule) {
                            if (file.isDeclarationFile) {
                                // for global .d.ts files record name of ambient module
                                (ambientModules || (ambientModules = [])).push(nameText);
                            }
                            // An AmbientExternalModuleDeclaration declares an external module.
                            // This type of declaration is permitted only in the global module.
                            // The StringLiteral must specify a top - level external module name.
                            // Relative external module names are not permitted
                            // NOTE: body of ambient module is always a module block, if it exists
                            var body = node.body;
                            if (body) {
                                for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
                                    var statement = _a[_i];
                                    collectModuleReferences(statement, /*inAmbientModule*/ true);
                                }
                            }
                        }
                    }
                }
            }
            function collectDynamicImportOrRequireCalls(file) {
                var r = /import|require/g;
                while (r.exec(file.text) !== null) { // eslint-disable-line no-null/no-null
                    var node = getNodeAtPosition(file, r.lastIndex);
                    if (ts.isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
                        imports = ts.append(imports, node.arguments[0]);
                    }
                    // we have to check the argument list has length of 1. We will still have to process these even though we have parsing error.
                    else if (ts.isImportCall(node) && node.arguments.length === 1 && ts.isStringLiteralLike(node.arguments[0])) {
                        imports = ts.append(imports, node.arguments[0]);
                    }
                    else if (ts.isLiteralImportTypeNode(node)) {
                        imports = ts.append(imports, node.argument.literal);
                    }
                }
            }
            /** Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only in JS files */
            function getNodeAtPosition(sourceFile, position) {
                var current = sourceFile;
                var getContainingChild = function (child) {
                    if (child.pos <= position && (position < child.end || (position === child.end && (child.kind === 1 /* EndOfFileToken */)))) {
                        return child;
                    }
                };
                while (true) {
                    var child = isJavaScriptFile && ts.hasJSDocNodes(current) && ts.forEach(current.jsDoc, getContainingChild) || ts.forEachChild(current, getContainingChild);
                    if (!child) {
                        return current;
                    }
                    current = child;
                }
            }
        }
        function getLibFileFromReference(ref) {
            var libName = ts.toFileNameLowerCase(ref.fileName);
            var libFileName = ts.libMap.get(libName);
            if (libFileName) {
                return getSourceFile(ts.combinePaths(defaultLibraryPath, libFileName));
            }
        }
        /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
        function getSourceFileFromReference(referencingFile, ref) {
            return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), function (fileName) { return filesByName.get(toPath(fileName)) || undefined; });
        }
        function getSourceFileFromReferenceWorker(fileName, getSourceFile, fail, refFile) {
            if (ts.hasExtension(fileName)) {
                var canonicalFileName_1 = host.getCanonicalFileName(fileName);
                if (!options.allowNonTsExtensions && !ts.forEach(supportedExtensionsWithJsonIfResolveJsonModule, function (extension) { return ts.fileExtensionIs(canonicalFileName_1, extension); })) {
                    if (fail) {
                        if (ts.hasJSFileExtension(canonicalFileName_1)) {
                            fail(ts.Diagnostics.File_0_is_a_JavaScript_file_Did_you_mean_to_enable_the_allowJs_option, fileName);
                        }
                        else {
                            fail(ts.Diagnostics.File_0_has_an_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
                        }
                    }
                    return undefined;
                }
                var sourceFile = getSourceFile(fileName);
                if (fail) {
                    if (!sourceFile) {
                        var redirect = getProjectReferenceRedirect(fileName);
                        if (redirect) {
                            fail(ts.Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, fileName);
                        }
                        else {
                            fail(ts.Diagnostics.File_0_not_found, fileName);
                        }
                    }
                    else if (refFile && canonicalFileName_1 === host.getCanonicalFileName(refFile.fileName)) {
                        fail(ts.Diagnostics.A_file_cannot_have_a_reference_to_itself);
                    }
                }
                return sourceFile;
            }
            else {
                var sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile(fileName);
                if (sourceFileNoExtension)
                    return sourceFileNoExtension;
                if (fail && options.allowNonTsExtensions) {
                    fail(ts.Diagnostics.File_0_not_found, fileName);
                    return undefined;
                }
                var sourceFileWithAddedExtension = ts.forEach(supportedExtensions, function (extension) { return getSourceFile(fileName + extension); });
                if (fail && !sourceFileWithAddedExtension)
                    fail(ts.Diagnostics.Could_not_resolve_the_path_0_with_the_extensions_Colon_1, fileName, "'" + supportedExtensions.join("', '") + "'");
                return sourceFileWithAddedExtension;
            }
        }
        /** This has side effects through `findSourceFile`. */
        function processSourceFile(fileName, isDefaultLib, ignoreNoDefaultLib, packageId, refFile) {
            getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, ignoreNoDefaultLib, refFile, packageId); }, // TODO: GH#18217
            function (diagnostic) {
                var args = [];
                for (var _i = 1; _i < arguments.length; _i++) {
                    args[_i - 1] = arguments[_i];
                }
                return fileProcessingDiagnostics.add(createRefFileDiagnostic.apply(void 0, __spreadArrays([refFile, diagnostic], args)));
            }, refFile && refFile.file);
        }
        function reportFileNamesDifferOnlyInCasingError(fileName, existingFile, refFile) {
            var refs = !refFile ? refFileMap && refFileMap.get(existingFile.path) : undefined;
            var refToReportErrorOn = refs && ts.find(refs, function (ref) { return ref.referencedFileName === existingFile.fileName; });
            fileProcessingDiagnostics.add(refToReportErrorOn ?
                createFileDiagnosticAtReference(refToReportErrorOn, ts.Diagnostics.Already_included_file_name_0_differs_from_file_name_1_only_in_casing, existingFile.fileName, fileName) :
                createRefFileDiagnostic(refFile, ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFile.fileName));
        }
        function createRedirectSourceFile(redirectTarget, unredirected, fileName, path, resolvedPath, originalFileName) {
            var redirect = Object.create(redirectTarget);
            redirect.fileName = fileName;
            redirect.path = path;
            redirect.resolvedPath = resolvedPath;
            redirect.originalFileName = originalFileName;
            redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected };
            sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
            Object.defineProperties(redirect, {
                id: {
                    get: function () { return this.redirectInfo.redirectTarget.id; },
                    set: function (value) { this.redirectInfo.redirectTarget.id = value; },
                },
                symbol: {
                    get: function () { return this.redirectInfo.redirectTarget.symbol; },
                    set: function (value) { this.redirectInfo.redirectTarget.symbol = value; },
                },
            });
            return redirect;
        }
        // Get source file from normalized fileName
        function findSourceFile(fileName, path, isDefaultLib, ignoreNoDefaultLib, refFile, packageId) {
            if (useSourceOfProjectReferenceRedirect) {
                var source = getSourceOfProjectReferenceRedirect(fileName);
                // If preserveSymlinks is true, module resolution wont jump the symlink
                // but the resolved real path may be the .d.ts from project reference
                // Note:: Currently we try the real path only if the
                // file is from node_modules to avoid having to run real path on all file paths
                if (!source &&
                    host.realpath &&
                    options.preserveSymlinks &&
                    ts.isDeclarationFileName(fileName) &&
                    ts.stringContains(fileName, ts.nodeModulesPathPart)) {
                    var realPath = host.realpath(fileName);
                    if (realPath !== fileName)
                        source = getSourceOfProjectReferenceRedirect(realPath);
                }
                if (source) {
                    var file_1 = ts.isString(source) ?
                        findSourceFile(source, toPath(source), isDefaultLib, ignoreNoDefaultLib, refFile, packageId) :
                        undefined;
                    if (file_1)
                        addFileToFilesByName(file_1, path, /*redirectedPath*/ undefined);
                    return file_1;
                }
            }
            var originalFileName = fileName;
            if (filesByName.has(path)) {
                var file_2 = filesByName.get(path);
                addFileToRefFileMap(fileName, file_2 || undefined, refFile);
                // try to check if we've already seen this file but with a different casing in path
                // NOTE: this only makes sense for case-insensitive file systems, and only on files which are not redirected
                if (file_2 && options.forceConsistentCasingInFileNames) {
                    var checkedName = file_2.fileName;
                    var isRedirect = toPath(checkedName) !== toPath(fileName);
                    if (isRedirect) {
                        fileName = getProjectReferenceRedirect(fileName) || fileName;
                    }
                    // Check if it differs only in drive letters its ok to ignore that error:
                    var checkedAbsolutePath = ts.getNormalizedAbsolutePathWithoutRoot(checkedName, currentDirectory);
                    var inputAbsolutePath = ts.getNormalizedAbsolutePathWithoutRoot(fileName, currentDirectory);
                    if (checkedAbsolutePath !== inputAbsolutePath) {
                        reportFileNamesDifferOnlyInCasingError(fileName, file_2, refFile);
                    }
                }
                // If the file was previously found via a node_modules search, but is now being processed as a root file,
                // then everything it sucks in may also be marked incorrectly, and needs to be checked again.
                if (file_2 && sourceFilesFoundSearchingNodeModules.get(file_2.path) && currentNodeModulesDepth === 0) {
                    sourceFilesFoundSearchingNodeModules.set(file_2.path, false);
                    if (!options.noResolve) {
                        processReferencedFiles(file_2, isDefaultLib);
                        processTypeReferenceDirectives(file_2);
                    }
                    if (!options.noLib) {
                        processLibReferenceDirectives(file_2);
                    }
                    modulesWithElidedImports.set(file_2.path, false);
                    processImportedModules(file_2);
                }
                // See if we need to reprocess the imports due to prior skipped imports
                else if (file_2 && modulesWithElidedImports.get(file_2.path)) {
                    if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
                        modulesWithElidedImports.set(file_2.path, false);
                        processImportedModules(file_2);
                    }
                }
                return file_2 || undefined;
            }
            var redirectedPath;
            if (refFile && !useSourceOfProjectReferenceRedirect) {
                var redirectProject = getProjectReferenceRedirectProject(fileName);
                if (redirectProject) {
                    if (redirectProject.commandLine.options.outFile || redirectProject.commandLine.options.out) {
                        // Shouldnt create many to 1 mapping file in --out scenario
                        return undefined;
                    }
                    var redirect = getProjectReferenceOutputName(redirectProject, fileName);
                    fileName = redirect;
                    // Once we start redirecting to a file, we can potentially come back to it
                    // via a back-reference from another file in the .d.ts folder. If that happens we'll
                    // end up trying to add it to the program *again* because we were tracking it via its
                    // original (un-redirected) name. So we have to map both the original path and the redirected path
                    // to the source file we're about to find/create
                    redirectedPath = toPath(redirect);
                }
            }
            // We haven't looked for this file, do so now and cache result
            var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) { return fileProcessingDiagnostics.add(createRefFileDiagnostic(refFile, ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); }, shouldCreateNewSourceFile);
            if (packageId) {
                var packageIdKey = ts.packageIdToString(packageId);
                var fileFromPackageId = packageIdToSourceFile.get(packageIdKey);
                if (fileFromPackageId) {
                    // Some other SourceFile already exists with this package name and version.
                    // Instead of creating a duplicate, just redirect to the existing one.
                    var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path, toPath(fileName), originalFileName); // TODO: GH#18217
                    redirectTargetsMap.add(fileFromPackageId.path, fileName);
                    addFileToFilesByName(dupFile, path, redirectedPath);
                    sourceFileToPackageName.set(path, packageId.name);
                    processingOtherFiles.push(dupFile);
                    return dupFile;
                }
                else if (file) {
                    // This is the first source file to have this packageId.
                    packageIdToSourceFile.set(packageIdKey, file);
                    sourceFileToPackageName.set(path, packageId.name);
                }
            }
            addFileToFilesByName(file, path, redirectedPath);
            if (file) {
                sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
                file.fileName = fileName; // Ensure that source file has same name as what we were looking for
                file.path = path;
                file.resolvedPath = toPath(fileName);
                file.originalFileName = originalFileName;
                addFileToRefFileMap(fileName, file, refFile);
                if (host.useCaseSensitiveFileNames()) {
                    var pathLowerCase = ts.toFileNameLowerCase(path);
                    // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
                    var existingFile = filesByNameIgnoreCase.get(pathLowerCase);
                    if (existingFile) {
                        reportFileNamesDifferOnlyInCasingError(fileName, existingFile, refFile);
                    }
                    else {
                        filesByNameIgnoreCase.set(pathLowerCase, file);
                    }
                }
                skipDefaultLib = skipDefaultLib || (file.hasNoDefaultLib && !ignoreNoDefaultLib);
                if (!options.noResolve) {
                    processReferencedFiles(file, isDefaultLib);
                    processTypeReferenceDirectives(file);
                }
                if (!options.noLib) {
                    processLibReferenceDirectives(file);
                }
                // always process imported modules to record module name resolutions
                processImportedModules(file);
                if (isDefaultLib) {
                    processingDefaultLibFiles.push(file);
                }
                else {
                    processingOtherFiles.push(file);
                }
            }
            return file;
        }
        function addFileToRefFileMap(referencedFileName, file, refFile) {
            if (refFile && file) {
                (refFileMap || (refFileMap = ts.createMultiMap())).add(file.path, {
                    referencedFileName: referencedFileName,
                    kind: refFile.kind,
                    index: refFile.index,
                    file: refFile.file.path
                });
            }
        }
        function addFileToFilesByName(file, path, redirectedPath) {
            if (redirectedPath) {
                filesByName.set(redirectedPath, file);
                filesByName.set(path, file || false);
            }
            else {
                filesByName.set(path, file);
            }
        }
        function getProjectReferenceRedirect(fileName) {
            var referencedProject = getProjectReferenceRedirectProject(fileName);
            return referencedProject && getProjectReferenceOutputName(referencedProject, fileName);
        }
        function getProjectReferenceRedirectProject(fileName) {
            // Ignore dts or any json files
            if (!resolvedProjectReferences || !resolvedProjectReferences.length || ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) || ts.fileExtensionIs(fileName, ".json" /* Json */)) {
                return undefined;
            }
            // If this file is produced by a referenced project, we need to rewrite it to
            // look in the output folder of the referenced project rather than the input
            return getResolvedProjectReferenceToRedirect(fileName);
        }
        function getProjectReferenceOutputName(referencedProject, fileName) {
            var out = referencedProject.commandLine.options.outFile || referencedProject.commandLine.options.out;
            return out ?
                ts.changeExtension(out, ".d.ts" /* Dts */) :
                ts.getOutputDeclarationFileName(fileName, referencedProject.commandLine, !host.useCaseSensitiveFileNames());
        }
        /**
         * Get the referenced project if the file is input file from that reference project
         */
        function getResolvedProjectReferenceToRedirect(fileName) {
            if (mapFromFileToProjectReferenceRedirects === undefined) {
                mapFromFileToProjectReferenceRedirects = ts.createMap();
                forEachResolvedProjectReference(function (referencedProject, referenceProjectPath) {
                    // not input file from the referenced project, ignore
                    if (referencedProject &&
                        toPath(options.configFilePath) !== referenceProjectPath) {
                        referencedProject.commandLine.fileNames.forEach(function (f) {
                            return mapFromFileToProjectReferenceRedirects.set(toPath(f), referenceProjectPath);
                        });
                    }
                });
            }
            var referencedProjectPath = mapFromFileToProjectReferenceRedirects.get(toPath(fileName));
            return referencedProjectPath && getResolvedProjectReferenceByPath(referencedProjectPath);
        }
        function forEachResolvedProjectReference(cb) {
            return forEachProjectReference(projectReferences, resolvedProjectReferences, function (resolvedRef, index, parent) {
                var ref = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var resolvedRefPath = toPath(resolveProjectReferencePath(ref));
                return cb(resolvedRef, resolvedRefPath);
            });
        }
        function getSourceOfProjectReferenceRedirect(file) {
            if (!ts.isDeclarationFileName(file))
                return undefined;
            if (mapFromToProjectReferenceRedirectSource === undefined) {
                mapFromToProjectReferenceRedirectSource = ts.createMap();
                forEachResolvedProjectReference(function (resolvedRef) {
                    if (resolvedRef) {
                        var out = resolvedRef.commandLine.options.outFile || resolvedRef.commandLine.options.out;
                        if (out) {
                            // Dont know which source file it means so return true?
                            var outputDts = ts.changeExtension(out, ".d.ts" /* Dts */);
                            mapFromToProjectReferenceRedirectSource.set(toPath(outputDts), true);
                        }
                        else {
                            ts.forEach(resolvedRef.commandLine.fileNames, function (fileName) {
                                if (!ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) && !ts.fileExtensionIs(fileName, ".json" /* Json */)) {
                                    var outputDts = ts.getOutputDeclarationFileName(fileName, resolvedRef.commandLine, host.useCaseSensitiveFileNames());
                                    mapFromToProjectReferenceRedirectSource.set(toPath(outputDts), fileName);
                                }
                            });
                        }
                    }
                });
            }
            return mapFromToProjectReferenceRedirectSource.get(toPath(file));
        }
        function isSourceOfProjectReferenceRedirect(fileName) {
            return useSourceOfProjectReferenceRedirect && !!getResolvedProjectReferenceToRedirect(fileName);
        }
        function forEachProjectReference(projectReferences, resolvedProjectReferences, cbResolvedRef, cbRef) {
            var seenResolvedRefs;
            return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined, cbResolvedRef, cbRef);
            function worker(projectReferences, resolvedProjectReferences, parent, cbResolvedRef, cbRef) {
                // Visit project references first
                if (cbRef) {
                    var result = cbRef(projectReferences, parent);
                    if (result) {
                        return result;
                    }
                }
                return ts.forEach(resolvedProjectReferences, function (resolvedRef, index) {
                    if (ts.contains(seenResolvedRefs, resolvedRef)) {
                        // ignore recursives
                        return undefined;
                    }
                    var result = cbResolvedRef(resolvedRef, index, parent);
                    if (result) {
                        return result;
                    }
                    if (!resolvedRef)
                        return undefined;
                    (seenResolvedRefs || (seenResolvedRefs = [])).push(resolvedRef);
                    return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef, cbResolvedRef, cbRef);
                });
            }
        }
        function getResolvedProjectReferenceByPath(projectReferencePath) {
            if (!projectReferenceRedirects) {
                return undefined;
            }
            return projectReferenceRedirects.get(projectReferencePath) || undefined;
        }
        function processReferencedFiles(file, isDefaultLib) {
            ts.forEach(file.referencedFiles, function (ref, index) {
                var referencedFileName = resolveTripleslashReference(ref.fileName, file.originalFileName);
                processSourceFile(referencedFileName, isDefaultLib, 
                /*ignoreNoDefaultLib*/ false, 
                /*packageId*/ undefined, {
                    kind: ts.RefFileKind.ReferenceFile,
                    index: index,
                    file: file,
                    pos: ref.pos,
                    end: ref.end
                });
            });
        }
        function processTypeReferenceDirectives(file) {
            // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
            var typeDirectives = ts.map(file.typeReferenceDirectives, function (ref) { return ts.toFileNameLowerCase(ref.fileName); });
            if (!typeDirectives) {
                return;
            }
            var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName, getResolvedProjectReferenceToRedirect(file.originalFileName));
            for (var i = 0; i < typeDirectives.length; i++) {
                var ref = file.typeReferenceDirectives[i];
                var resolvedTypeReferenceDirective = resolutions[i];
                // store resolved type directive on the file
                var fileName = ts.toFileNameLowerCase(ref.fileName);
                ts.setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective);
                processTypeReferenceDirective(fileName, resolvedTypeReferenceDirective, {
                    kind: ts.RefFileKind.TypeReferenceDirective,
                    index: i,
                    file: file,
                    pos: ref.pos,
                    end: ref.end
                });
            }
        }
        function processTypeReferenceDirective(typeReferenceDirective, resolvedTypeReferenceDirective, refFile) {
            // If we already found this library as a primary reference - nothing to do
            var previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective);
            if (previousResolution && previousResolution.primary) {
                return;
            }
            var saveResolution = true;
            if (resolvedTypeReferenceDirective) {
                if (resolvedTypeReferenceDirective.isExternalLibraryImport)
                    currentNodeModulesDepth++;
                if (resolvedTypeReferenceDirective.primary) {
                    // resolved from the primary path
                    processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile); // TODO: GH#18217
                }
                else {
                    // If we already resolved to this file, it must have been a secondary reference. Check file contents
                    // for sameness and possibly issue an error
                    if (previousResolution) {
                        // Don't bother reading the file again if it's the same file.
                        if (resolvedTypeReferenceDirective.resolvedFileName !== previousResolution.resolvedFileName) {
                            var otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName);
                            var existingFile_1 = getSourceFile(previousResolution.resolvedFileName);
                            if (otherFileText !== existingFile_1.text) {
                                // Try looking up ref for original file
                                var refs = !refFile ? refFileMap && refFileMap.get(existingFile_1.path) : undefined;
                                var refToReportErrorOn = refs && ts.find(refs, function (ref) { return ref.referencedFileName === existingFile_1.fileName; });
                                fileProcessingDiagnostics.add(refToReportErrorOn ?
                                    createFileDiagnosticAtReference(refToReportErrorOn, ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName) :
                                    createRefFileDiagnostic(refFile, ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName));
                            }
                        }
                        // don't overwrite previous resolution result
                        saveResolution = false;
                    }
                    else {
                        // First resolution of this library
                        processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile);
                    }
                }
                if (resolvedTypeReferenceDirective.isExternalLibraryImport)
                    currentNodeModulesDepth--;
            }
            else {
                fileProcessingDiagnostics.add(createRefFileDiagnostic(refFile, ts.Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective));
            }
            if (saveResolution) {
                resolvedTypeReferenceDirectives.set(typeReferenceDirective, resolvedTypeReferenceDirective);
            }
        }
        function processLibReferenceDirectives(file) {
            ts.forEach(file.libReferenceDirectives, function (libReference) {
                var libName = ts.toFileNameLowerCase(libReference.fileName);
                var libFileName = ts.libMap.get(libName);
                if (libFileName) {
                    // we ignore any 'no-default-lib' reference set on this file.
                    processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true);
                }
                else {
                    var unqualifiedLibName = ts.removeSuffix(ts.removePrefix(libName, "lib."), ".d.ts");
                    var suggestion = ts.getSpellingSuggestion(unqualifiedLibName, ts.libs, ts.identity);
                    var message = suggestion ? ts.Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : ts.Diagnostics.Cannot_find_lib_definition_for_0;
                    fileProcessingDiagnostics.add(ts.createFileDiagnostic(file, libReference.pos, libReference.end - libReference.pos, message, libName, suggestion));
                }
            });
        }
        function createRefFileDiagnostic(refFile, message) {
            var args = [];
            for (var _i = 2; _i < arguments.length; _i++) {
                args[_i - 2] = arguments[_i];
            }
            if (!refFile) {
                return ts.createCompilerDiagnostic.apply(void 0, __spreadArrays([message], args));
            }
            else {
                return ts.createFileDiagnostic.apply(void 0, __spreadArrays([refFile.file, refFile.pos, refFile.end - refFile.pos, message], args));
            }
        }
        function getCanonicalFileName(fileName) {
            return host.getCanonicalFileName(fileName);
        }
        function processImportedModules(file) {
            collectExternalModuleReferences(file);
            if (file.imports.length || file.moduleAugmentations.length) {
                // Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
                var moduleNames = getModuleNames(file);
                var resolutions = resolveModuleNamesReusingOldState(moduleNames, ts.getNormalizedAbsolutePath(file.originalFileName, currentDirectory), file);
                ts.Debug.assert(resolutions.length === moduleNames.length);
                for (var i = 0; i < moduleNames.length; i++) {
                    var resolution = resolutions[i];
                    ts.setResolvedModule(file, moduleNames[i], resolution);
                    if (!resolution) {
                        continue;
                    }
                    var isFromNodeModulesSearch = resolution.isExternalLibraryImport;
                    var isJsFile = !ts.resolutionExtensionIsTSOrJson(resolution.extension);
                    var isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile;
                    var resolvedFileName = resolution.resolvedFileName;
                    if (isFromNodeModulesSearch) {
                        currentNodeModulesDepth++;
                    }
                    // add file to program only if:
                    // - resolution was successful
                    // - noResolve is falsy
                    // - module name comes from the list of imports
                    // - it's not a top level JavaScript module that exceeded the search max
                    var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
                    // Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
                    // This may still end up being an untyped module -- the file won't be included but imports will be allowed.
                    var shouldAddFile = resolvedFileName
                        && !getResolutionDiagnostic(options, resolution)
                        && !options.noResolve
                        && i < file.imports.length
                        && !elideImport
                        && !(isJsFile && !options.allowJs)
                        && (ts.isInJSFile(file.imports[i]) || !(file.imports[i].flags & 4194304 /* JSDoc */));
                    if (elideImport) {
                        modulesWithElidedImports.set(file.path, true);
                    }
                    else if (shouldAddFile) {
                        var path = toPath(resolvedFileName);
                        var pos = ts.skipTrivia(file.text, file.imports[i].pos);
                        findSourceFile(resolvedFileName, path, 
                        /*isDefaultLib*/ false, 
                        /*ignoreNoDefaultLib*/ false, {
                            kind: ts.RefFileKind.Import,
                            index: i,
                            file: file,
                            pos: pos,
                            end: file.imports[i].end
                        }, resolution.packageId);
                    }
                    if (isFromNodeModulesSearch) {
                        currentNodeModulesDepth--;
                    }
                }
            }
            else {
                // no imports - drop cached module resolutions
                file.resolvedModules = undefined;
            }
        }
        function computeCommonSourceDirectory(sourceFiles) {
            var fileNames = ts.mapDefined(sourceFiles, function (file) { return file.isDeclarationFile ? undefined : file.fileName; });
            return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName);
        }
        function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) {
            var allFilesBelongToPath = true;
            var absoluteRootDirectoryPath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(rootDirectory, currentDirectory));
            var rootPaths;
            for (var _i = 0, sourceFiles_2 = sourceFiles; _i < sourceFiles_2.length; _i++) {
                var sourceFile = sourceFiles_2[_i];
                if (!sourceFile.isDeclarationFile) {
                    var absoluteSourceFilePath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
                    if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
                        if (!rootPaths)
                            rootPaths = ts.arrayToSet(rootNames, toPath);
                        addProgramDiagnosticAtRefPath(sourceFile, rootPaths, ts.Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, rootDirectory);
                        allFilesBelongToPath = false;
                    }
                }
            }
            return allFilesBelongToPath;
        }
        function parseProjectReferenceConfigFile(ref) {
            if (!projectReferenceRedirects) {
                projectReferenceRedirects = ts.createMap();
            }
            // The actual filename (i.e. add "/tsconfig.json" if necessary)
            var refPath = resolveProjectReferencePath(ref);
            var sourceFilePath = toPath(refPath);
            var fromCache = projectReferenceRedirects.get(sourceFilePath);
            if (fromCache !== undefined) {
                return fromCache || undefined;
            }
            var commandLine;
            var sourceFile;
            if (host.getParsedCommandLine) {
                commandLine = host.getParsedCommandLine(refPath);
                if (!commandLine) {
                    addFileToFilesByName(/*sourceFile*/ undefined, sourceFilePath, /*redirectedPath*/ undefined);
                    projectReferenceRedirects.set(sourceFilePath, false);
                    return undefined;
                }
                sourceFile = ts.Debug.checkDefined(commandLine.options.configFile);
                ts.Debug.assert(!sourceFile.path || sourceFile.path === sourceFilePath);
                addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
            }
            else {
                // An absolute path pointing to the containing directory of the config file
                var basePath = ts.getNormalizedAbsolutePath(ts.getDirectoryPath(refPath), host.getCurrentDirectory());
                sourceFile = host.getSourceFile(refPath, 100 /* JSON */);
                addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
                if (sourceFile === undefined) {
                    projectReferenceRedirects.set(sourceFilePath, false);
                    return undefined;
                }
                commandLine = ts.parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
            }
            sourceFile.fileName = refPath;
            sourceFile.path = sourceFilePath;
            sourceFile.resolvedPath = sourceFilePath;
            sourceFile.originalFileName = refPath;
            var resolvedRef = { commandLine: commandLine, sourceFile: sourceFile };
            projectReferenceRedirects.set(sourceFilePath, resolvedRef);
            if (commandLine.projectReferences) {
                resolvedRef.references = commandLine.projectReferences.map(parseProjectReferenceConfigFile);
            }
            return resolvedRef;
        }
        function verifyCompilerOptions() {
            if (options.strictPropertyInitialization && !ts.getStrictOptionValue(options, "strictNullChecks")) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
            }
            if (options.isolatedModules) {
                if (options.out) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules");
                }
                if (options.outFile) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules");
                }
            }
            if (options.inlineSourceMap) {
                if (options.sourceMap) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
                }
                if (options.mapRoot) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap");
                }
            }
            if (options.paths && options.baseUrl === undefined) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths");
            }
            if (options.composite) {
                if (options.declaration === false) {
                    createDiagnosticForOptionName(ts.Diagnostics.Composite_projects_may_not_disable_declaration_emit, "declaration");
                }
                if (options.incremental === false) {
                    createDiagnosticForOptionName(ts.Diagnostics.Composite_projects_may_not_disable_incremental_compilation, "declaration");
                }
            }
            if (options.tsBuildInfoFile) {
                if (!ts.isIncrementalCompilation(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "tsBuildInfoFile", "incremental", "composite");
                }
            }
            else if (options.incremental && !options.outFile && !options.out && !options.configFilePath) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_incremental_can_only_be_specified_using_tsconfig_emitting_to_single_file_or_when_option_tsBuildInfoFile_is_specified));
            }
            if (!options.listFilesOnly && options.noEmit && ts.isIncrementalCompilation(options)) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", options.incremental ? "incremental" : "composite");
            }
            verifyProjectReferences();
            // List of collected files is complete; validate exhautiveness if this is a project with a file list
            if (options.composite) {
                var rootPaths = ts.arrayToSet(rootNames, toPath);
                for (var _i = 0, files_3 = files; _i < files_3.length; _i++) {
                    var file = files_3[_i];
                    // Ignore file that is not emitted
                    if (ts.sourceFileMayBeEmitted(file, program) && !rootPaths.has(file.path)) {
                        addProgramDiagnosticAtRefPath(file, rootPaths, ts.Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern, file.fileName, options.configFilePath || "");
                    }
                }
            }
            if (options.paths) {
                for (var key in options.paths) {
                    if (!ts.hasProperty(options.paths, key)) {
                        continue;
                    }
                    if (!ts.hasZeroOrOneAsteriskCharacter(key)) {
                        createDiagnosticForOptionPaths(/*onKey*/ true, key, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key);
                    }
                    if (ts.isArray(options.paths[key])) {
                        var len = options.paths[key].length;
                        if (len === 0) {
                            createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key);
                        }
                        for (var i = 0; i < len; i++) {
                            var subst = options.paths[key][i];
                            var typeOfSubst = typeof subst;
                            if (typeOfSubst === "string") {
                                if (!ts.hasZeroOrOneAsteriskCharacter(subst)) {
                                    createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_in_pattern_1_can_have_at_most_one_Asterisk_character, subst, key);
                                }
                            }
                            else {
                                createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst);
                            }
                        }
                    }
                    else {
                        createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key);
                    }
                }
            }
            if (!options.sourceMap && !options.inlineSourceMap) {
                if (options.inlineSources) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources");
                }
                if (options.sourceRoot) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot");
                }
            }
            if (options.out && options.outFile) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile");
            }
            if (options.mapRoot && !(options.sourceMap || options.declarationMap)) {
                // Error to specify --mapRoot without --sourcemap
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "mapRoot", "sourceMap", "declarationMap");
            }
            if (options.declarationDir) {
                if (!ts.getEmitDeclarations(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationDir", "declaration", "composite");
                }
                if (options.out || options.outFile) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
                }
            }
            if (options.declarationMap && !ts.getEmitDeclarations(options)) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "declarationMap", "declaration", "composite");
            }
            if (options.lib && options.noLib) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
            }
            if (options.noImplicitUseStrict && ts.getStrictOptionValue(options, "alwaysStrict")) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
            }
            var languageVersion = options.target || 0 /* ES3 */;
            var outFile = options.outFile || options.out;
            var firstNonAmbientExternalModuleSourceFile = ts.find(files, function (f) { return ts.isExternalModule(f) && !f.isDeclarationFile; });
            if (options.isolatedModules) {
                if (options.module === ts.ModuleKind.None && languageVersion < 2 /* ES2015 */) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
                }
                var firstNonExternalModuleSourceFile = ts.find(files, function (f) { return !ts.isExternalModule(f) && !ts.isSourceFileJS(f) && !f.isDeclarationFile && f.scriptKind !== 6 /* JSON */; });
                if (firstNonExternalModuleSourceFile) {
                    var span = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.All_files_must_be_modules_when_the_isolatedModules_flag_is_provided));
                }
            }
            else if (firstNonAmbientExternalModuleSourceFile && languageVersion < 2 /* ES2015 */ && options.module === ts.ModuleKind.None) {
                // We cannot use createDiagnosticFromNode because nodes do not have parents yet
                var span = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
                programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none));
            }
            // Cannot specify module gen that isn't amd or system with --out
            if (outFile && !options.emitDeclarationOnly) {
                if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
                }
                else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) {
                    var span = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
                    programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span.start, span.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile"));
                }
            }
            if (options.resolveJsonModule) {
                if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
                }
                // Any emit other than common js, amd, es2015 or esnext is error
                else if (!ts.hasJsonModuleEmitEnabled(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module");
                }
            }
            // there has to be common source directory if user specified --outdir || --sourceRoot
            // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted
            if (options.outDir || // there is --outDir specified
                options.sourceRoot || // there is --sourceRoot specified
                options.mapRoot) { // there is --mapRoot specified
                // Precalculate and cache the common source directory
                var dir = getCommonSourceDirectory();
                // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
                if (options.outDir && dir === "" && files.some(function (file) { return ts.getRootLength(file.fileName) > 1; })) {
                    createDiagnosticForOptionName(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
                }
            }
            if (options.useDefineForClassFields && languageVersion === 0 /* ES3 */) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_when_option_target_is_ES3, "useDefineForClassFields");
            }
            if (options.checkJs && !options.allowJs) {
                programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
            }
            if (options.emitDeclarationOnly) {
                if (!ts.getEmitDeclarations(options)) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "emitDeclarationOnly", "declaration", "composite");
                }
                if (options.noEmit) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "emitDeclarationOnly", "noEmit");
                }
            }
            if (options.emitDecoratorMetadata &&
                !options.experimentalDecorators) {
                createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
            }
            if (options.jsxFactory) {
                if (options.reactNamespace) {
                    createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory");
                }
                if (!ts.parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
                    createOptionValueDiagnostic("jsxFactory", ts.Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory);
                }
            }
            else if (options.reactNamespace && !ts.isIdentifierText(options.reactNamespace, languageVersion)) {
                createOptionValueDiagnostic("reactNamespace", ts.Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
            }
            // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
            if (!options.noEmit && !options.suppressOutputPathCheck) {
                var emitHost = getEmitHost();
                var emitFilesSeen_1 = ts.createMap();
                ts.forEachEmittedFile(emitHost, function (emitFileNames) {
                    if (!options.emitDeclarationOnly) {
                        verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen_1);
                    }
                    verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen_1);
                });
            }
            // Verify that all the emit files are unique and don't overwrite input files
            function verifyEmitFilePath(emitFileName, emitFilesSeen) {
                if (emitFileName) {
                    var emitFilePath = toPath(emitFileName);
                    // Report error if the output overwrites input file
                    if (filesByName.has(emitFilePath)) {
                        var chain = void 0;
                        if (!options.configFilePath) {
                            // The program is from either an inferred project or an external project
                            chain = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
                        }
                        chain = ts.chainDiagnosticMessages(chain, ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnosticFromMessageChain(chain));
                    }
                    var emitFileKey = !host.useCaseSensitiveFileNames() ? ts.toFileNameLowerCase(emitFilePath) : emitFilePath;
                    // Report error if multiple files write into same file
                    if (emitFilesSeen.has(emitFileKey)) {
                        // Already seen the same emit file - report error
                        blockEmittingOfFile(emitFileName, ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
                    }
                    else {
                        emitFilesSeen.set(emitFileKey, true);
                    }
                }
            }
        }
        function createFileDiagnosticAtReference(refPathToReportErrorOn, message) {
            var _a, _b;
            var args = [];
            for (var _i = 2; _i < arguments.length; _i++) {
                args[_i - 2] = arguments[_i];
            }
            var refFile = ts.Debug.checkDefined(getSourceFileByPath(refPathToReportErrorOn.file));
            var kind = refPathToReportErrorOn.kind, index = refPathToReportErrorOn.index;
            var pos, end;
            switch (kind) {
                case ts.RefFileKind.Import:
                    pos = ts.skipTrivia(refFile.text, refFile.imports[index].pos);
                    end = refFile.imports[index].end;
                    break;
                case ts.RefFileKind.ReferenceFile:
                    (_a = refFile.referencedFiles[index], pos = _a.pos, end = _a.end);
                    break;
                case ts.RefFileKind.TypeReferenceDirective:
                    (_b = refFile.typeReferenceDirectives[index], pos = _b.pos, end = _b.end);
                    break;
                default:
                    return ts.Debug.assertNever(kind);
            }
            return ts.createFileDiagnostic.apply(void 0, __spreadArrays([refFile, pos, end - pos, message], args));
        }
        function addProgramDiagnosticAtRefPath(file, rootPaths, message) {
            var args = [];
            for (var _i = 3; _i < arguments.length; _i++) {
                args[_i - 3] = arguments[_i];
            }
            var refPaths = refFileMap && refFileMap.get(file.path);
            var refPathToReportErrorOn = ts.forEach(refPaths, function (refPath) { return rootPaths.has(refPath.file) ? refPath : undefined; }) ||
                ts.elementAt(refPaths, 0);
            programDiagnostics.add(refPathToReportErrorOn ? createFileDiagnosticAtReference.apply(void 0, __spreadArrays([refPathToReportErrorOn, message], args)) : ts.createCompilerDiagnostic.apply(void 0, __spreadArrays([message], args)));
        }
        function verifyProjectReferences() {
            var buildInfoPath = !options.noEmit && !options.suppressOutputPathCheck ? ts.getTsBuildInfoEmitOutputFilePath(options) : undefined;
            forEachProjectReference(projectReferences, resolvedProjectReferences, function (resolvedRef, index, parent) {
                var ref = (parent ? parent.commandLine.projectReferences : projectReferences)[index];
                var parentFile = parent && parent.sourceFile;
                if (!resolvedRef) {
                    createDiagnosticForReference(parentFile, index, ts.Diagnostics.File_0_not_found, ref.path);
                    return;
                }
                var options = resolvedRef.commandLine.options;
                if (!options.composite) {
                    // ok to not have composite if the current program is container only
                    var inputs = parent ? parent.commandLine.fileNames : rootNames;
                    if (inputs.length) {
                        createDiagnosticForReference(parentFile, index, ts.Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
                    }
                }
                if (ref.prepend) {
                    var out = options.outFile || options.out;
                    if (out) {
                        if (!host.fileExists(out)) {
                            createDiagnosticForReference(parentFile, index, ts.Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path);
                        }
                    }
                    else {
                        createDiagnosticForReference(parentFile, index, ts.Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path);
                    }
                }
                if (!parent && buildInfoPath && buildInfoPath === ts.getTsBuildInfoEmitOutputFilePath(options)) {
                    createDiagnosticForReference(parentFile, index, ts.Diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoPath, ref.path);
                    hasEmitBlockingDiagnostics.set(toPath(buildInfoPath), true);
                }
            });
        }
        function createDiagnosticForOptionPathKeyValue(key, valueIndex, message, arg0, arg1, arg2) {
            var needCompilerDiagnostic = true;
            var pathsSyntax = getOptionPathsSyntax();
            for (var _i = 0, pathsSyntax_1 = pathsSyntax; _i < pathsSyntax_1.length; _i++) {
                var pathProp = pathsSyntax_1[_i];
                if (ts.isObjectLiteralExpression(pathProp.initializer)) {
                    for (var _a = 0, _b = ts.getPropertyAssignment(pathProp.initializer, key); _a < _b.length; _a++) {
                        var keyProps = _b[_a];
                        var initializer = keyProps.initializer;
                        if (ts.isArrayLiteralExpression(initializer) && initializer.elements.length > valueIndex) {
                            programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, initializer.elements[valueIndex], message, arg0, arg1, arg2));
                            needCompilerDiagnostic = false;
                        }
                    }
                }
            }
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2));
            }
        }
        function createDiagnosticForOptionPaths(onKey, key, message, arg0) {
            var needCompilerDiagnostic = true;
            var pathsSyntax = getOptionPathsSyntax();
            for (var _i = 0, pathsSyntax_2 = pathsSyntax; _i < pathsSyntax_2.length; _i++) {
                var pathProp = pathsSyntax_2[_i];
                if (ts.isObjectLiteralExpression(pathProp.initializer) &&
                    createOptionDiagnosticInObjectLiteralSyntax(pathProp.initializer, onKey, key, /*key2*/ undefined, message, arg0)) {
                    needCompilerDiagnostic = false;
                }
            }
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0));
            }
        }
        function getOptionsSyntaxByName(name) {
            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
            if (compilerOptionsObjectLiteralSyntax) {
                return ts.getPropertyAssignment(compilerOptionsObjectLiteralSyntax, name);
            }
            return undefined;
        }
        function getOptionPathsSyntax() {
            return getOptionsSyntaxByName("paths") || ts.emptyArray;
        }
        function createDiagnosticForOptionName(message, option1, option2, option3) {
            createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3);
        }
        function createOptionValueDiagnostic(option1, message, arg0) {
            createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
        }
        function createDiagnosticForReference(sourceFile, index, message, arg0, arg1) {
            var referencesSyntax = ts.firstDefined(ts.getTsConfigPropArray(sourceFile || options.configFile, "references"), function (property) { return ts.isArrayLiteralExpression(property.initializer) ? property.initializer : undefined; });
            if (referencesSyntax && referencesSyntax.elements.length > index) {
                programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(sourceFile || options.configFile, referencesSyntax.elements[index], message, arg0, arg1));
            }
            else {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1));
            }
        }
        function createDiagnosticForOption(onKey, option1, option2, message, arg0, arg1, arg2) {
            var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
            var needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
                !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2);
            if (needCompilerDiagnostic) {
                programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2));
            }
        }
        function getCompilerOptionsObjectLiteralSyntax() {
            if (_compilerOptionsObjectLiteralSyntax === undefined) {
                _compilerOptionsObjectLiteralSyntax = null; // eslint-disable-line no-null/no-null
                var jsonObjectLiteral = ts.getTsConfigObjectLiteralExpression(options.configFile);
                if (jsonObjectLiteral) {
                    for (var _i = 0, _a = ts.getPropertyAssignment(jsonObjectLiteral, "compilerOptions"); _i < _a.length; _i++) {
                        var prop = _a[_i];
                        if (ts.isObjectLiteralExpression(prop.initializer)) {
                            _compilerOptionsObjectLiteralSyntax = prop.initializer;
                            break;
                        }
                    }
                }
            }
            return _compilerOptionsObjectLiteralSyntax;
        }
        function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral, onKey, key1, key2, message, arg0, arg1, arg2) {
            var props = ts.getPropertyAssignment(objectLiteral, key1, key2);
            for (var _i = 0, props_3 = props; _i < props_3.length; _i++) {
                var prop = props_3[_i];
                programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2));
            }
            return !!props.length;
        }
        function blockEmittingOfFile(emitFileName, diag) {
            hasEmitBlockingDiagnostics.set(toPath(emitFileName), true);
            programDiagnostics.add(diag);
        }
        function isEmittedFile(file) {
            if (options.noEmit) {
                return false;
            }
            // If this is source file, its not emitted file
            var filePath = toPath(file);
            if (getSourceFileByPath(filePath)) {
                return false;
            }
            // If options have --outFile or --out just check that
            var out = options.outFile || options.out;
            if (out) {
                return isSameFile(filePath, out) || isSameFile(filePath, ts.removeFileExtension(out) + ".d.ts" /* Dts */);
            }
            // If declarationDir is specified, return if its a file in that directory
            if (options.declarationDir && ts.containsPath(options.declarationDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames())) {
                return true;
            }
            // If --outDir, check if file is in that directory
            if (options.outDir) {
                return ts.containsPath(options.outDir, filePath, currentDirectory, !host.useCaseSensitiveFileNames());
            }
            if (ts.fileExtensionIsOneOf(filePath, ts.supportedJSExtensions) || ts.fileExtensionIs(filePath, ".d.ts" /* Dts */)) {
                // Otherwise just check if sourceFile with the name exists
                var filePathWithoutExtension = ts.removeFileExtension(filePath);
                return !!getSourceFileByPath((filePathWithoutExtension + ".ts" /* Ts */)) ||
                    !!getSourceFileByPath((filePathWithoutExtension + ".tsx" /* Tsx */));
            }
            return false;
        }
        function isSameFile(file1, file2) {
            return ts.comparePaths(file1, file2, currentDirectory, !host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
        }
        function getProbableSymlinks() {
            if (host.getSymlinks) {
                return host.getSymlinks();
            }
            return symlinks || (symlinks = ts.discoverProbableSymlinks(files, getCanonicalFileName, host.getCurrentDirectory()));
        }
    }
    ts.createProgram = createProgram;
    function updateHostForUseSourceOfProjectReferenceRedirect(host) {
        var mapOfDeclarationDirectories;
        var symlinkedDirectories;
        var symlinkedFiles;
        var originalFileExists = host.compilerHost.fileExists;
        var originalDirectoryExists = host.compilerHost.directoryExists;
        var originalGetDirectories = host.compilerHost.getDirectories;
        var originalRealpath = host.compilerHost.realpath;
        if (!host.useSourceOfProjectReferenceRedirect)
            return { onProgramCreateComplete: ts.noop, fileExists: fileExists };
        host.compilerHost.fileExists = fileExists;
        if (originalDirectoryExists) {
            // This implementation of directoryExists checks if the directory being requested is
            // directory of .d.ts file for the referenced Project.
            // If it is it returns true irrespective of whether that directory exists on host
            host.compilerHost.directoryExists = function (path) {
                if (originalDirectoryExists.call(host.compilerHost, path)) {
                    handleDirectoryCouldBeSymlink(path);
                    return true;
                }
                if (!host.getResolvedProjectReferences())
                    return false;
                if (!mapOfDeclarationDirectories) {
                    mapOfDeclarationDirectories = ts.createMap();
                    host.forEachResolvedProjectReference(function (ref) {
                        if (!ref)
                            return;
                        var out = ref.commandLine.options.outFile || ref.commandLine.options.out;
                        if (out) {
                            mapOfDeclarationDirectories.set(ts.getDirectoryPath(host.toPath(out)), true);
                        }
                        else {
                            // Set declaration's in different locations only, if they are next to source the directory present doesnt change
                            var declarationDir = ref.commandLine.options.declarationDir || ref.commandLine.options.outDir;
                            if (declarationDir) {
                                mapOfDeclarationDirectories.set(host.toPath(declarationDir), true);
                            }
                        }
                    });
                }
                return fileOrDirectoryExistsUsingSource(path, /*isFile*/ false);
            };
        }
        if (originalGetDirectories) {
            // Call getDirectories only if directory actually present on the host
            // This is needed to ensure that we arent getting directories that we fake about presence for
            host.compilerHost.getDirectories = function (path) {
                return !host.getResolvedProjectReferences() || (originalDirectoryExists && originalDirectoryExists.call(host.compilerHost, path)) ?
                    originalGetDirectories.call(host.compilerHost, path) :
                    [];
            };
        }
        // This is something we keep for life time of the host
        if (originalRealpath) {
            host.compilerHost.realpath = function (s) {
                return (symlinkedFiles === null || symlinkedFiles === void 0 ? void 0 : symlinkedFiles.get(host.toPath(s))) ||
                    originalRealpath.call(host.compilerHost, s);
            };
        }
        return { onProgramCreateComplete: onProgramCreateComplete, fileExists: fileExists };
        function onProgramCreateComplete() {
            host.compilerHost.fileExists = originalFileExists;
            host.compilerHost.directoryExists = originalDirectoryExists;
            host.compilerHost.getDirectories = originalGetDirectories;
            // DO not revert realpath as it could be used later
        }
        // This implementation of fileExists checks if the file being requested is
        // .d.ts file for the referenced Project.
        // If it is it returns true irrespective of whether that file exists on host
        function fileExists(file) {
            if (originalFileExists.call(host.compilerHost, file))
                return true;
            if (!host.getResolvedProjectReferences())
                return false;
            if (!ts.isDeclarationFileName(file))
                return false;
            // Project references go to source file instead of .d.ts file
            return fileOrDirectoryExistsUsingSource(file, /*isFile*/ true);
        }
        function fileExistsIfProjectReferenceDts(file) {
            var source = host.getSourceOfProjectReferenceRedirect(file);
            return source !== undefined ?
                ts.isString(source) ? originalFileExists.call(host.compilerHost, source) : true :
                undefined;
        }
        function directoryExistsIfProjectReferenceDeclDir(dir) {
            var dirPath = host.toPath(dir);
            var dirPathWithTrailingDirectorySeparator = "" + dirPath + ts.directorySeparator;
            return ts.forEachKey(mapOfDeclarationDirectories, function (declDirPath) { return dirPath === declDirPath ||
                // Any parent directory of declaration dir
                ts.startsWith(declDirPath, dirPathWithTrailingDirectorySeparator) ||
                // Any directory inside declaration dir
                ts.startsWith(dirPath, declDirPath + "/"); });
        }
        function handleDirectoryCouldBeSymlink(directory) {
            if (!host.getResolvedProjectReferences())
                return;
            // Because we already watch node_modules, handle symlinks in there
            if (!originalRealpath || !ts.stringContains(directory, ts.nodeModulesPathPart))
                return;
            if (!symlinkedDirectories)
                symlinkedDirectories = ts.createMap();
            var directoryPath = ts.ensureTrailingDirectorySeparator(host.toPath(directory));
            if (symlinkedDirectories.has(directoryPath))
                return;
            var real = ts.normalizePath(originalRealpath.call(host.compilerHost, directory));
            var realPath;
            if (real === directory ||
                (realPath = ts.ensureTrailingDirectorySeparator(host.toPath(real))) === directoryPath) {
                // not symlinked
                symlinkedDirectories.set(directoryPath, false);
                return;
            }
            symlinkedDirectories.set(directoryPath, {
                real: ts.ensureTrailingDirectorySeparator(real),
                realPath: realPath
            });
        }
        function fileOrDirectoryExistsUsingSource(fileOrDirectory, isFile) {
            var fileOrDirectoryExistsUsingSource = isFile ?
                function (file) { return fileExistsIfProjectReferenceDts(file); } :
                function (dir) { return directoryExistsIfProjectReferenceDeclDir(dir); };
            // Check current directory or file
            var result = fileOrDirectoryExistsUsingSource(fileOrDirectory);
            if (result !== undefined)
                return result;
            if (!symlinkedDirectories)
                return false;
            var fileOrDirectoryPath = host.toPath(fileOrDirectory);
            if (!ts.stringContains(fileOrDirectoryPath, ts.nodeModulesPathPart))
                return false;
            if (isFile && symlinkedFiles && symlinkedFiles.has(fileOrDirectoryPath))
                return true;
            // If it contains node_modules check if its one of the symlinked path we know of
            return ts.firstDefinedIterator(symlinkedDirectories.entries(), function (_a) {
                var directoryPath = _a[0], symlinkedDirectory = _a[1];
                if (!symlinkedDirectory || !ts.startsWith(fileOrDirectoryPath, directoryPath))
                    return undefined;
                var result = fileOrDirectoryExistsUsingSource(fileOrDirectoryPath.replace(directoryPath, symlinkedDirectory.realPath));
                if (isFile && result) {
                    if (!symlinkedFiles)
                        symlinkedFiles = ts.createMap();
                    // Store the real path for the file'
                    var absolutePath = ts.getNormalizedAbsolutePath(fileOrDirectory, host.compilerHost.getCurrentDirectory());
                    symlinkedFiles.set(fileOrDirectoryPath, "" + symlinkedDirectory.real + absolutePath.replace(new RegExp(directoryPath, "i"), ""));
                }
                return result;
            }) || false;
        }
    }
    /*@internal*/
    function handleNoEmitOptions(program, sourceFile, cancellationToken) {
        var options = program.getCompilerOptions();
        if (options.noEmit) {
            return { diagnostics: ts.emptyArray, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true };
        }
        // If the noEmitOnError flag is set, then check if we have any errors so far.  If so,
        // immediately bail out.  Note that we pass 'undefined' for 'sourceFile' so that we
        // get any preEmit diagnostics, not just the ones
        if (!options.noEmitOnError)
            return undefined;
        var diagnostics = __spreadArrays(program.getOptionsDiagnostics(cancellationToken), program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken));
        if (diagnostics.length === 0 && ts.getEmitDeclarations(program.getCompilerOptions())) {
            diagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken);
        }
        return diagnostics.length > 0 ?
            { diagnostics: diagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true } :
            undefined;
    }
    ts.handleNoEmitOptions = handleNoEmitOptions;
    /* @internal */
    function parseConfigHostFromCompilerHostLike(host, directoryStructureHost) {
        if (directoryStructureHost === void 0) { directoryStructureHost = host; }
        return {
            fileExists: function (f) { return directoryStructureHost.fileExists(f); },
            readDirectory: function (root, extensions, excludes, includes, depth) {
                ts.Debug.assertIsDefined(directoryStructureHost.readDirectory, "'CompilerHost.readDirectory' must be implemented to correctly process 'projectReferences'");
                return directoryStructureHost.readDirectory(root, extensions, excludes, includes, depth);
            },
            readFile: function (f) { return directoryStructureHost.readFile(f); },
            useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
            getCurrentDirectory: function () { return host.getCurrentDirectory(); },
            onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic || ts.returnUndefined,
            trace: host.trace ? function (s) { return host.trace(s); } : undefined
        };
    }
    ts.parseConfigHostFromCompilerHostLike = parseConfigHostFromCompilerHostLike;
    /* @internal */
    function createPrependNodes(projectReferences, getCommandLine, readFile) {
        if (!projectReferences)
            return ts.emptyArray;
        var nodes;
        for (var i = 0; i < projectReferences.length; i++) {
            var ref = projectReferences[i];
            var resolvedRefOpts = getCommandLine(ref, i);
            if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
                var out = resolvedRefOpts.options.outFile || resolvedRefOpts.options.out;
                // Upstream project didn't have outFile set -- skip (error will have been issued earlier)
                if (!out)
                    continue;
                var _a = ts.getOutputPathsForBundle(resolvedRefOpts.options, /*forceDtsPaths*/ true), jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath, declarationMapPath = _a.declarationMapPath, buildInfoPath = _a.buildInfoPath;
                var node = ts.createInputFiles(readFile, jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath);
                (nodes || (nodes = [])).push(node);
            }
        }
        return nodes || ts.emptyArray;
    }
    ts.createPrependNodes = createPrependNodes;
    function resolveProjectReferencePath(hostOrRef, ref) {
        var passedInRef = ref ? ref : hostOrRef;
        return ts.resolveConfigFileProjectName(passedInRef.path);
    }
    ts.resolveProjectReferencePath = resolveProjectReferencePath;
    /* @internal */
    /**
     * Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
     * The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
     * This returns a diagnostic even if the module will be an untyped module.
     */
    function getResolutionDiagnostic(options, _a) {
        var extension = _a.extension;
        switch (extension) {
            case ".ts" /* Ts */:
            case ".d.ts" /* Dts */:
                // These are always allowed.
                return undefined;
            case ".tsx" /* Tsx */:
                return needJsx();
            case ".jsx" /* Jsx */:
                return needJsx() || needAllowJs();
            case ".js" /* Js */:
                return needAllowJs();
            case ".json" /* Json */:
                return needResolveJsonModule();
        }
        function needJsx() {
            return options.jsx ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
        }
        function needAllowJs() {
            return options.allowJs || !ts.getStrictOptionValue(options, "noImplicitAny") ? undefined : ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
        }
        function needResolveJsonModule() {
            return options.resolveJsonModule ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_resolveJsonModule_is_not_used;
        }
    }
    ts.getResolutionDiagnostic = getResolutionDiagnostic;
    function getModuleNames(_a) {
        var imports = _a.imports, moduleAugmentations = _a.moduleAugmentations;
        var res = imports.map(function (i) { return i.text; });
        for (var _i = 0, moduleAugmentations_1 = moduleAugmentations; _i < moduleAugmentations_1.length; _i++) {
            var aug = moduleAugmentations_1[_i];
            if (aug.kind === 10 /* StringLiteral */) {
                res.push(aug.text);
            }
            // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`.
        }
        return res;
    }
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers, forceDtsEmit) {
        var outputFiles = [];
        var _a = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers, forceDtsEmit), emitSkipped = _a.emitSkipped, diagnostics = _a.diagnostics, exportedModulesFromDeclarationEmit = _a.exportedModulesFromDeclarationEmit;
        return { outputFiles: outputFiles, emitSkipped: emitSkipped, diagnostics: diagnostics, exportedModulesFromDeclarationEmit: exportedModulesFromDeclarationEmit };
        function writeFile(fileName, text, writeByteOrderMark) {
            outputFiles.push({ name: fileName, writeByteOrderMark: writeByteOrderMark, text: text });
        }
    }
    ts.getFileEmitOutput = getFileEmitOutput;
    var BuilderState;
    (function (BuilderState) {
        /**
         * Get the referencedFile from the imported module symbol
         */
        function getReferencedFileFromImportedModuleSymbol(symbol) {
            if (symbol.declarations && symbol.declarations[0]) {
                var declarationSourceFile = ts.getSourceFileOfNode(symbol.declarations[0]);
                return declarationSourceFile && declarationSourceFile.resolvedPath;
            }
        }
        /**
         * Get the referencedFile from the import name node from file
         */
        function getReferencedFileFromImportLiteral(checker, importName) {
            var symbol = checker.getSymbolAtLocation(importName);
            return symbol && getReferencedFileFromImportedModuleSymbol(symbol);
        }
        /**
         * Gets the path to reference file from file name, it could be resolvedPath if present otherwise path
         */
        function getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName) {
            return ts.toPath(program.getProjectReferenceRedirect(fileName) || fileName, sourceFileDirectory, getCanonicalFileName);
        }
        /**
         * Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true
         */
        function getReferencedFiles(program, sourceFile, getCanonicalFileName) {
            var referencedFiles;
            // We need to use a set here since the code can contain the same import twice,
            // but that will only be one dependency.
            // To avoid invernal conversion, the key of the referencedFiles map must be of type Path
            if (sourceFile.imports && sourceFile.imports.length > 0) {
                var checker = program.getTypeChecker();
                for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) {
                    var importName = _a[_i];
                    var declarationSourceFilePath = getReferencedFileFromImportLiteral(checker, importName);
                    if (declarationSourceFilePath) {
                        addReferencedFile(declarationSourceFilePath);
                    }
                }
            }
            var sourceFileDirectory = ts.getDirectoryPath(sourceFile.resolvedPath);
            // Handle triple slash references
            if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) {
                for (var _b = 0, _c = sourceFile.referencedFiles; _b < _c.length; _b++) {
                    var referencedFile = _c[_b];
                    var referencedPath = getReferencedFileFromFileName(program, referencedFile.fileName, sourceFileDirectory, getCanonicalFileName);
                    addReferencedFile(referencedPath);
                }
            }
            // Handle type reference directives
            if (sourceFile.resolvedTypeReferenceDirectiveNames) {
                sourceFile.resolvedTypeReferenceDirectiveNames.forEach(function (resolvedTypeReferenceDirective) {
                    if (!resolvedTypeReferenceDirective) {
                        return;
                    }
                    var fileName = resolvedTypeReferenceDirective.resolvedFileName; // TODO: GH#18217
                    var typeFilePath = getReferencedFileFromFileName(program, fileName, sourceFileDirectory, getCanonicalFileName);
                    addReferencedFile(typeFilePath);
                });
            }
            // Add module augmentation as references
            if (sourceFile.moduleAugmentations.length) {
                var checker = program.getTypeChecker();
                for (var _d = 0, _e = sourceFile.moduleAugmentations; _d < _e.length; _d++) {
                    var moduleName = _e[_d];
                    if (!ts.isStringLiteral(moduleName)) {
                        continue;
                    }
                    var symbol = checker.getSymbolAtLocation(moduleName);
                    if (!symbol) {
                        continue;
                    }
                    // Add any file other than our own as reference
                    addReferenceFromAmbientModule(symbol);
                }
            }
            // From ambient modules
            for (var _f = 0, _g = program.getTypeChecker().getAmbientModules(); _f < _g.length; _f++) {
                var ambientModule = _g[_f];
                if (ambientModule.declarations.length > 1) {
                    addReferenceFromAmbientModule(ambientModule);
                }
            }
            return referencedFiles;
            function addReferenceFromAmbientModule(symbol) {
                // Add any file other than our own as reference
                for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) {
                    var declaration = _a[_i];
                    var declarationSourceFile = ts.getSourceFileOfNode(declaration);
                    if (declarationSourceFile &&
                        declarationSourceFile !== sourceFile) {
                        addReferencedFile(declarationSourceFile.resolvedPath);
                    }
                }
            }
            function addReferencedFile(referencedPath) {
                if (!referencedFiles) {
                    referencedFiles = ts.createMap();
                }
                referencedFiles.set(referencedPath, true);
            }
        }
        /**
         * Returns true if oldState is reusable, that is the emitKind = module/non module has not changed
         */
        function canReuseOldState(newReferencedMap, oldState) {
            return oldState && !oldState.referencedMap === !newReferencedMap;
        }
        BuilderState.canReuseOldState = canReuseOldState;
        /**
         * Creates the state of file references and signature for the new program from oldState if it is safe
         */
        function create(newProgram, getCanonicalFileName, oldState) {
            var fileInfos = ts.createMap();
            var referencedMap = newProgram.getCompilerOptions().module !== ts.ModuleKind.None ? ts.createMap() : undefined;
            var exportedModulesMap = referencedMap ? ts.createMap() : undefined;
            var hasCalledUpdateShapeSignature = ts.createMap();
            var useOldState = canReuseOldState(referencedMap, oldState);
            // Create the reference map, and set the file infos
            for (var _i = 0, _a = newProgram.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                var version_1 = ts.Debug.checkDefined(sourceFile.version, "Program intended to be used with Builder should have source files with versions set");
                var oldInfo = useOldState ? oldState.fileInfos.get(sourceFile.resolvedPath) : undefined;
                if (referencedMap) {
                    var newReferences = getReferencedFiles(newProgram, sourceFile, getCanonicalFileName);
                    if (newReferences) {
                        referencedMap.set(sourceFile.resolvedPath, newReferences);
                    }
                    // Copy old visible to outside files map
                    if (useOldState) {
                        var exportedModules = oldState.exportedModulesMap.get(sourceFile.resolvedPath);
                        if (exportedModules) {
                            exportedModulesMap.set(sourceFile.resolvedPath, exportedModules);
                        }
                    }
                }
                fileInfos.set(sourceFile.resolvedPath, { version: version_1, signature: oldInfo && oldInfo.signature, affectsGlobalScope: isFileAffectingGlobalScope(sourceFile) });
            }
            return {
                fileInfos: fileInfos,
                referencedMap: referencedMap,
                exportedModulesMap: exportedModulesMap,
                hasCalledUpdateShapeSignature: hasCalledUpdateShapeSignature
            };
        }
        BuilderState.create = create;
        /**
         * Releases needed properties
         */
        function releaseCache(state) {
            state.allFilesExcludingDefaultLibraryFile = undefined;
            state.allFileNames = undefined;
        }
        BuilderState.releaseCache = releaseCache;
        /**
         * Creates a clone of the state
         */
        function clone(state) {
            var fileInfos = ts.createMap();
            state.fileInfos.forEach(function (value, key) {
                fileInfos.set(key, __assign({}, value));
            });
            // Dont need to backup allFiles info since its cache anyway
            return {
                fileInfos: fileInfos,
                referencedMap: cloneMapOrUndefined(state.referencedMap),
                exportedModulesMap: cloneMapOrUndefined(state.exportedModulesMap),
                hasCalledUpdateShapeSignature: ts.cloneMap(state.hasCalledUpdateShapeSignature),
            };
        }
        BuilderState.clone = clone;
        /**
         * Gets the files affected by the path from the program
         */
        function getFilesAffectedBy(state, programOfThisState, path, cancellationToken, computeHash, cacheToUpdateSignature, exportedModulesMapCache) {
            // Since the operation could be cancelled, the signatures are always stored in the cache
            // They will be committed once it is safe to use them
            // eg when calling this api from tsserver, if there is no cancellation of the operation
            // In the other cases the affected files signatures are committed only after the iteration through the result is complete
            var signatureCache = cacheToUpdateSignature || ts.createMap();
            var sourceFile = programOfThisState.getSourceFileByPath(path);
            if (!sourceFile) {
                return ts.emptyArray;
            }
            if (!updateShapeSignature(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache)) {
                return [sourceFile];
            }
            var result = (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, signatureCache, cancellationToken, computeHash, exportedModulesMapCache);
            if (!cacheToUpdateSignature) {
                // Commit all the signatures in the signature cache
                updateSignaturesFromCache(state, signatureCache);
            }
            return result;
        }
        BuilderState.getFilesAffectedBy = getFilesAffectedBy;
        /**
         * Updates the signatures from the cache into state's fileinfo signatures
         * This should be called whenever it is safe to commit the state of the builder
         */
        function updateSignaturesFromCache(state, signatureCache) {
            signatureCache.forEach(function (signature, path) { return updateSignatureOfFile(state, signature, path); });
        }
        BuilderState.updateSignaturesFromCache = updateSignaturesFromCache;
        function updateSignatureOfFile(state, signature, path) {
            state.fileInfos.get(path).signature = signature;
            state.hasCalledUpdateShapeSignature.set(path, true);
        }
        BuilderState.updateSignatureOfFile = updateSignatureOfFile;
        /**
         * Returns if the shape of the signature has changed since last emit
         */
        function updateShapeSignature(state, programOfThisState, sourceFile, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache) {
            ts.Debug.assert(!!sourceFile);
            ts.Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state");
            // If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
            if (state.hasCalledUpdateShapeSignature.has(sourceFile.resolvedPath) || cacheToUpdateSignature.has(sourceFile.resolvedPath)) {
                return false;
            }
            var info = state.fileInfos.get(sourceFile.resolvedPath);
            if (!info)
                return ts.Debug.fail();
            var prevSignature = info.signature;
            var latestSignature;
            if (sourceFile.isDeclarationFile) {
                latestSignature = sourceFile.version;
                if (exportedModulesMapCache && latestSignature !== prevSignature) {
                    // All the references in this file are exported
                    var references = state.referencedMap ? state.referencedMap.get(sourceFile.resolvedPath) : undefined;
                    exportedModulesMapCache.set(sourceFile.resolvedPath, references || false);
                }
            }
            else {
                var emitOutput_1 = getFileEmitOutput(programOfThisState, sourceFile, 
                /*emitOnlyDtsFiles*/ true, cancellationToken, 
                /*customTransformers*/ undefined, 
                /*forceDtsEmit*/ true);
                var firstDts_1 = emitOutput_1.outputFiles &&
                    programOfThisState.getCompilerOptions().declarationMap ?
                    emitOutput_1.outputFiles.length > 1 ? emitOutput_1.outputFiles[1] : undefined :
                    emitOutput_1.outputFiles.length > 0 ? emitOutput_1.outputFiles[0] : undefined;
                if (firstDts_1) {
                    ts.Debug.assert(ts.fileExtensionIs(firstDts_1.name, ".d.ts" /* Dts */), "File extension for signature expected to be dts", function () { return "Found: " + ts.getAnyExtensionFromPath(firstDts_1.name) + " for " + firstDts_1.name + ":: All output files: " + JSON.stringify(emitOutput_1.outputFiles.map(function (f) { return f.name; })); });
                    latestSignature = computeHash(firstDts_1.text);
                    if (exportedModulesMapCache && latestSignature !== prevSignature) {
                        updateExportedModules(sourceFile, emitOutput_1.exportedModulesFromDeclarationEmit, exportedModulesMapCache);
                    }
                }
                else {
                    latestSignature = prevSignature; // TODO: GH#18217
                }
            }
            cacheToUpdateSignature.set(sourceFile.resolvedPath, latestSignature);
            return !prevSignature || latestSignature !== prevSignature;
        }
        BuilderState.updateShapeSignature = updateShapeSignature;
        /**
         * Coverts the declaration emit result into exported modules map
         */
        function updateExportedModules(sourceFile, exportedModulesFromDeclarationEmit, exportedModulesMapCache) {
            if (!exportedModulesFromDeclarationEmit) {
                exportedModulesMapCache.set(sourceFile.resolvedPath, false);
                return;
            }
            var exportedModules;
            exportedModulesFromDeclarationEmit.forEach(function (symbol) { return addExportedModule(getReferencedFileFromImportedModuleSymbol(symbol)); });
            exportedModulesMapCache.set(sourceFile.resolvedPath, exportedModules || false);
            function addExportedModule(exportedModulePath) {
                if (exportedModulePath) {
                    if (!exportedModules) {
                        exportedModules = ts.createMap();
                    }
                    exportedModules.set(exportedModulePath, true);
                }
            }
        }
        /**
         * Updates the exported modules from cache into state's exported modules map
         * This should be called whenever it is safe to commit the state of the builder
         */
        function updateExportedFilesMapFromCache(state, exportedModulesMapCache) {
            if (exportedModulesMapCache) {
                ts.Debug.assert(!!state.exportedModulesMap);
                exportedModulesMapCache.forEach(function (exportedModules, path) {
                    if (exportedModules) {
                        state.exportedModulesMap.set(path, exportedModules);
                    }
                    else {
                        state.exportedModulesMap.delete(path);
                    }
                });
            }
        }
        BuilderState.updateExportedFilesMapFromCache = updateExportedFilesMapFromCache;
        /**
         * Get all the dependencies of the sourceFile
         */
        function getAllDependencies(state, programOfThisState, sourceFile) {
            var compilerOptions = programOfThisState.getCompilerOptions();
            // With --out or --outFile all outputs go into single file, all files depend on each other
            if (compilerOptions.outFile || compilerOptions.out) {
                return getAllFileNames(state, programOfThisState);
            }
            // If this is non module emit, or its a global file, it depends on all the source files
            if (!state.referencedMap || isFileAffectingGlobalScope(sourceFile)) {
                return getAllFileNames(state, programOfThisState);
            }
            // Get the references, traversing deep from the referenceMap
            var seenMap = ts.createMap();
            var queue = [sourceFile.resolvedPath];
            while (queue.length) {
                var path = queue.pop();
                if (!seenMap.has(path)) {
                    seenMap.set(path, true);
                    var references = state.referencedMap.get(path);
                    if (references) {
                        var iterator = references.keys();
                        for (var iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) {
                            queue.push(iterResult.value);
                        }
                    }
                }
            }
            return ts.arrayFrom(ts.mapDefinedIterator(seenMap.keys(), function (path) {
                var file = programOfThisState.getSourceFileByPath(path);
                return file ? file.fileName : path;
            }));
        }
        BuilderState.getAllDependencies = getAllDependencies;
        /**
         * Gets the names of all files from the program
         */
        function getAllFileNames(state, programOfThisState) {
            if (!state.allFileNames) {
                var sourceFiles = programOfThisState.getSourceFiles();
                state.allFileNames = sourceFiles === ts.emptyArray ? ts.emptyArray : sourceFiles.map(function (file) { return file.fileName; });
            }
            return state.allFileNames;
        }
        /**
         * Gets the files referenced by the the file path
         */
        function getReferencedByPaths(state, referencedFilePath) {
            return ts.arrayFrom(ts.mapDefinedIterator(state.referencedMap.entries(), function (_a) {
                var filePath = _a[0], referencesInFile = _a[1];
                return referencesInFile.has(referencedFilePath) ? filePath : undefined;
            }));
        }
        BuilderState.getReferencedByPaths = getReferencedByPaths;
        /**
         * For script files that contains only ambient external modules, although they are not actually external module files,
         * they can only be consumed via importing elements from them. Regular script files cannot consume them. Therefore,
         * there are no point to rebuild all script files if these special files have changed. However, if any statement
         * in the file is not ambient external module, we treat it as a regular script file.
         */
        function containsOnlyAmbientModules(sourceFile) {
            for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
                var statement = _a[_i];
                if (!ts.isModuleWithStringLiteralName(statement)) {
                    return false;
                }
            }
            return true;
        }
        /**
         * Return true if file contains anything that augments to global scope we need to build them as if
         * they are global files as well as module
         */
        function containsGlobalScopeAugmentation(sourceFile) {
            return ts.some(sourceFile.moduleAugmentations, function (augmentation) { return ts.isGlobalScopeAugmentation(augmentation.parent); });
        }
        /**
         * Return true if the file will invalidate all files because it affectes global scope
         */
        function isFileAffectingGlobalScope(sourceFile) {
            return containsGlobalScopeAugmentation(sourceFile) ||
                !ts.isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile);
        }
        /**
         * Gets all files of the program excluding the default library file
         */
        function getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, firstSourceFile) {
            // Use cached result
            if (state.allFilesExcludingDefaultLibraryFile) {
                return state.allFilesExcludingDefaultLibraryFile;
            }
            var result;
            if (firstSourceFile)
                addSourceFile(firstSourceFile);
            for (var _i = 0, _a = programOfThisState.getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile = _a[_i];
                if (sourceFile !== firstSourceFile) {
                    addSourceFile(sourceFile);
                }
            }
            state.allFilesExcludingDefaultLibraryFile = result || ts.emptyArray;
            return state.allFilesExcludingDefaultLibraryFile;
            function addSourceFile(sourceFile) {
                if (!programOfThisState.isSourceFileDefaultLibrary(sourceFile)) {
                    (result || (result = [])).push(sourceFile);
                }
            }
        }
        BuilderState.getAllFilesExcludingDefaultLibraryFile = getAllFilesExcludingDefaultLibraryFile;
        /**
         * When program emits non modular code, gets the files affected by the sourceFile whose shape has changed
         */
        function getFilesAffectedByUpdatedShapeWhenNonModuleEmit(state, programOfThisState, sourceFileWithUpdatedShape) {
            var compilerOptions = programOfThisState.getCompilerOptions();
            // If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
            // so returning the file itself is good enough.
            if (compilerOptions && (compilerOptions.out || compilerOptions.outFile)) {
                return [sourceFileWithUpdatedShape];
            }
            return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
        }
        /**
         * When program emits modular code, gets the files affected by the sourceFile whose shape has changed
         */
        function getFilesAffectedByUpdatedShapeWhenModuleEmit(state, programOfThisState, sourceFileWithUpdatedShape, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache) {
            if (isFileAffectingGlobalScope(sourceFileWithUpdatedShape)) {
                return getAllFilesExcludingDefaultLibraryFile(state, programOfThisState, sourceFileWithUpdatedShape);
            }
            var compilerOptions = programOfThisState.getCompilerOptions();
            if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) {
                return [sourceFileWithUpdatedShape];
            }
            // Now we need to if each file in the referencedBy list has a shape change as well.
            // Because if so, its own referencedBy files need to be saved as well to make the
            // emitting result consistent with files on disk.
            var seenFileNamesMap = ts.createMap();
            // Start with the paths this file was referenced by
            seenFileNamesMap.set(sourceFileWithUpdatedShape.resolvedPath, sourceFileWithUpdatedShape);
            var queue = getReferencedByPaths(state, sourceFileWithUpdatedShape.resolvedPath);
            while (queue.length > 0) {
                var currentPath = queue.pop();
                if (!seenFileNamesMap.has(currentPath)) {
                    var currentSourceFile = programOfThisState.getSourceFileByPath(currentPath);
                    seenFileNamesMap.set(currentPath, currentSourceFile);
                    if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash, exportedModulesMapCache)) { // TODO: GH#18217
                        queue.push.apply(// TODO: GH#18217
                        queue, getReferencedByPaths(state, currentSourceFile.resolvedPath));
                    }
                }
            }
            // Return array of values that needs emit
            // Return array of values that needs emit
            return ts.arrayFrom(ts.mapDefinedIterator(seenFileNamesMap.values(), function (value) { return value; }));
        }
    })(BuilderState = ts.BuilderState || (ts.BuilderState = {}));
    function cloneMapOrUndefined(map) {
        return map ? ts.cloneMap(map) : undefined;
    }
    ts.cloneMapOrUndefined = cloneMapOrUndefined;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var BuilderFileEmit;
    (function (BuilderFileEmit) {
        BuilderFileEmit[BuilderFileEmit["DtsOnly"] = 0] = "DtsOnly";
        BuilderFileEmit[BuilderFileEmit["Full"] = 1] = "Full";
    })(BuilderFileEmit = ts.BuilderFileEmit || (ts.BuilderFileEmit = {}));
    function hasSameKeys(map1, map2) {
        // Has same size and every key is present in both maps
        return map1 === map2 || map1 !== undefined && map2 !== undefined && map1.size === map2.size && !ts.forEachKey(map1, function (key) { return !map2.has(key); });
    }
    /**
     * Create the state so that we can iterate on changedFiles/affected files
     */
    function createBuilderProgramState(newProgram, getCanonicalFileName, oldState) {
        var state = ts.BuilderState.create(newProgram, getCanonicalFileName, oldState);
        state.program = newProgram;
        var compilerOptions = newProgram.getCompilerOptions();
        state.compilerOptions = compilerOptions;
        // With --out or --outFile, any change affects all semantic diagnostics so no need to cache them
        if (!compilerOptions.outFile && !compilerOptions.out) {
            state.semanticDiagnosticsPerFile = ts.createMap();
        }
        state.changedFilesSet = ts.createMap();
        var useOldState = ts.BuilderState.canReuseOldState(state.referencedMap, oldState);
        var oldCompilerOptions = useOldState ? oldState.compilerOptions : undefined;
        var canCopySemanticDiagnostics = useOldState && oldState.semanticDiagnosticsPerFile && !!state.semanticDiagnosticsPerFile &&
            !ts.compilerOptionsAffectSemanticDiagnostics(compilerOptions, oldCompilerOptions);
        if (useOldState) {
            // Verify the sanity of old state
            if (!oldState.currentChangedFilePath) {
                var affectedSignatures = oldState.currentAffectedFilesSignatures;
                ts.Debug.assert(!oldState.affectedFiles && (!affectedSignatures || !affectedSignatures.size), "Cannot reuse if only few affected files of currentChangedFile were iterated");
            }
            var changedFilesSet = oldState.changedFilesSet;
            if (canCopySemanticDiagnostics) {
                ts.Debug.assert(!changedFilesSet || !ts.forEachKey(changedFilesSet, function (path) { return oldState.semanticDiagnosticsPerFile.has(path); }), "Semantic diagnostics shouldnt be available for changed files");
            }
            // Copy old state's changed files set
            if (changedFilesSet) {
                ts.copyEntries(changedFilesSet, state.changedFilesSet);
            }
            if (!compilerOptions.outFile && !compilerOptions.out && oldState.affectedFilesPendingEmit) {
                state.affectedFilesPendingEmit = oldState.affectedFilesPendingEmit.slice();
                state.affectedFilesPendingEmitKind = ts.cloneMapOrUndefined(oldState.affectedFilesPendingEmitKind);
                state.affectedFilesPendingEmitIndex = oldState.affectedFilesPendingEmitIndex;
                state.seenAffectedFiles = ts.createMap();
            }
        }
        // Update changed files and copy semantic diagnostics if we can
        var referencedMap = state.referencedMap;
        var oldReferencedMap = useOldState ? oldState.referencedMap : undefined;
        var copyDeclarationFileDiagnostics = canCopySemanticDiagnostics && !compilerOptions.skipLibCheck === !oldCompilerOptions.skipLibCheck;
        var copyLibFileDiagnostics = copyDeclarationFileDiagnostics && !compilerOptions.skipDefaultLibCheck === !oldCompilerOptions.skipDefaultLibCheck;
        state.fileInfos.forEach(function (info, sourceFilePath) {
            var oldInfo;
            var newReferences;
            // if not using old state, every file is changed
            if (!useOldState ||
                // File wasnt present in old state
                !(oldInfo = oldState.fileInfos.get(sourceFilePath)) ||
                // versions dont match
                oldInfo.version !== info.version ||
                // Referenced files changed
                !hasSameKeys(newReferences = referencedMap && referencedMap.get(sourceFilePath), oldReferencedMap && oldReferencedMap.get(sourceFilePath)) ||
                // Referenced file was deleted in the new program
                newReferences && ts.forEachKey(newReferences, function (path) { return !state.fileInfos.has(path) && oldState.fileInfos.has(path); })) {
                // Register file as changed file and do not copy semantic diagnostics, since all changed files need to be re-evaluated
                state.changedFilesSet.set(sourceFilePath, true);
            }
            else if (canCopySemanticDiagnostics) {
                var sourceFile = newProgram.getSourceFileByPath(sourceFilePath);
                if (sourceFile.isDeclarationFile && !copyDeclarationFileDiagnostics) {
                    return;
                }
                if (sourceFile.hasNoDefaultLib && !copyLibFileDiagnostics) {
                    return;
                }
                // Unchanged file copy diagnostics
                var diagnostics = oldState.semanticDiagnosticsPerFile.get(sourceFilePath);
                if (diagnostics) {
                    state.semanticDiagnosticsPerFile.set(sourceFilePath, oldState.hasReusableDiagnostic ? convertToDiagnostics(diagnostics, newProgram, getCanonicalFileName) : diagnostics);
                    if (!state.semanticDiagnosticsFromOldState) {
                        state.semanticDiagnosticsFromOldState = ts.createMap();
                    }
                    state.semanticDiagnosticsFromOldState.set(sourceFilePath, true);
                }
            }
        });
        // If the global file is removed, add all files as changed
        if (useOldState && ts.forEachEntry(oldState.fileInfos, function (info, sourceFilePath) { return info.affectsGlobalScope && !state.fileInfos.has(sourceFilePath); })) {
            ts.BuilderState.getAllFilesExcludingDefaultLibraryFile(state, newProgram, /*firstSourceFile*/ undefined)
                .forEach(function (file) { return state.changedFilesSet.set(file.resolvedPath, true); });
        }
        else if (oldCompilerOptions && ts.compilerOptionsAffectEmit(compilerOptions, oldCompilerOptions)) {
            // Add all files to affectedFilesPendingEmit since emit changed
            newProgram.getSourceFiles().forEach(function (f) { return addToAffectedFilesPendingEmit(state, f.resolvedPath, 1 /* Full */); });
            ts.Debug.assert(!state.seenAffectedFiles || !state.seenAffectedFiles.size);
            state.seenAffectedFiles = state.seenAffectedFiles || ts.createMap();
        }
        state.emittedBuildInfo = !state.changedFilesSet.size && !state.affectedFilesPendingEmit;
        return state;
    }
    function convertToDiagnostics(diagnostics, newProgram, getCanonicalFileName) {
        if (!diagnostics.length)
            return ts.emptyArray;
        var buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(ts.getTsBuildInfoEmitOutputFilePath(newProgram.getCompilerOptions()), newProgram.getCurrentDirectory()));
        return diagnostics.map(function (diagnostic) {
            var result = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath);
            result.reportsUnnecessary = diagnostic.reportsUnnecessary;
            result.source = diagnostic.source;
            var relatedInformation = diagnostic.relatedInformation;
            result.relatedInformation = relatedInformation ?
                relatedInformation.length ?
                    relatedInformation.map(function (r) { return convertToDiagnosticRelatedInformation(r, newProgram, toPath); }) :
                    ts.emptyArray :
                undefined;
            return result;
        });
        function toPath(path) {
            return ts.toPath(path, buildInfoDirectory, getCanonicalFileName);
        }
    }
    function convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPath) {
        var file = diagnostic.file;
        return __assign(__assign({}, diagnostic), { file: file ? newProgram.getSourceFileByPath(toPath(file)) : undefined });
    }
    /**
     * Releases program and other related not needed properties
     */
    function releaseCache(state) {
        ts.BuilderState.releaseCache(state);
        state.program = undefined;
    }
    /**
     * Creates a clone of the state
     */
    function cloneBuilderProgramState(state) {
        var newState = ts.BuilderState.clone(state);
        newState.semanticDiagnosticsPerFile = ts.cloneMapOrUndefined(state.semanticDiagnosticsPerFile);
        newState.changedFilesSet = ts.cloneMap(state.changedFilesSet);
        newState.affectedFiles = state.affectedFiles;
        newState.affectedFilesIndex = state.affectedFilesIndex;
        newState.currentChangedFilePath = state.currentChangedFilePath;
        newState.currentAffectedFilesSignatures = ts.cloneMapOrUndefined(state.currentAffectedFilesSignatures);
        newState.currentAffectedFilesExportedModulesMap = ts.cloneMapOrUndefined(state.currentAffectedFilesExportedModulesMap);
        newState.seenAffectedFiles = ts.cloneMapOrUndefined(state.seenAffectedFiles);
        newState.cleanedDiagnosticsOfLibFiles = state.cleanedDiagnosticsOfLibFiles;
        newState.semanticDiagnosticsFromOldState = ts.cloneMapOrUndefined(state.semanticDiagnosticsFromOldState);
        newState.program = state.program;
        newState.compilerOptions = state.compilerOptions;
        newState.affectedFilesPendingEmit = state.affectedFilesPendingEmit && state.affectedFilesPendingEmit.slice();
        newState.affectedFilesPendingEmitKind = ts.cloneMapOrUndefined(state.affectedFilesPendingEmitKind);
        newState.affectedFilesPendingEmitIndex = state.affectedFilesPendingEmitIndex;
        newState.seenEmittedFiles = ts.cloneMapOrUndefined(state.seenEmittedFiles);
        newState.programEmitComplete = state.programEmitComplete;
        return newState;
    }
    /**
     * Verifies that source file is ok to be used in calls that arent handled by next
     */
    function assertSourceFileOkWithoutNextAffectedCall(state, sourceFile) {
        ts.Debug.assert(!sourceFile || !state.affectedFiles || state.affectedFiles[state.affectedFilesIndex - 1] !== sourceFile || !state.semanticDiagnosticsPerFile.has(sourceFile.resolvedPath));
    }
    /**
     * This function returns the next affected file to be processed.
     * Note that until doneAffected is called it would keep reporting same result
     * This is to allow the callers to be able to actually remove affected file only when the operation is complete
     * eg. if during diagnostics check cancellation token ends up cancelling the request, the affected file should be retained
     */
    function getNextAffectedFile(state, cancellationToken, computeHash) {
        while (true) {
            var affectedFiles = state.affectedFiles;
            if (affectedFiles) {
                var seenAffectedFiles = state.seenAffectedFiles;
                var affectedFilesIndex = state.affectedFilesIndex; // TODO: GH#18217
                while (affectedFilesIndex < affectedFiles.length) {
                    var affectedFile = affectedFiles[affectedFilesIndex];
                    if (!seenAffectedFiles.has(affectedFile.resolvedPath)) {
                        // Set the next affected file as seen and remove the cached semantic diagnostics
                        state.affectedFilesIndex = affectedFilesIndex;
                        handleDtsMayChangeOfAffectedFile(state, affectedFile, cancellationToken, computeHash);
                        return affectedFile;
                    }
                    affectedFilesIndex++;
                }
                // Remove the changed file from the change set
                state.changedFilesSet.delete(state.currentChangedFilePath);
                state.currentChangedFilePath = undefined;
                // Commit the changes in file signature
                ts.BuilderState.updateSignaturesFromCache(state, state.currentAffectedFilesSignatures);
                state.currentAffectedFilesSignatures.clear();
                ts.BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap);
                state.affectedFiles = undefined;
            }
            // Get next changed file
            var nextKey = state.changedFilesSet.keys().next();
            if (nextKey.done) {
                // Done
                return undefined;
            }
            // With --out or --outFile all outputs go into single file
            // so operations are performed directly on program, return program
            var program = ts.Debug.checkDefined(state.program);
            var compilerOptions = program.getCompilerOptions();
            if (compilerOptions.outFile || compilerOptions.out) {
                ts.Debug.assert(!state.semanticDiagnosticsPerFile);
                return program;
            }
            // Get next batch of affected files
            state.currentAffectedFilesSignatures = state.currentAffectedFilesSignatures || ts.createMap();
            if (state.exportedModulesMap) {
                state.currentAffectedFilesExportedModulesMap = state.currentAffectedFilesExportedModulesMap || ts.createMap();
            }
            state.affectedFiles = ts.BuilderState.getFilesAffectedBy(state, program, nextKey.value, cancellationToken, computeHash, state.currentAffectedFilesSignatures, state.currentAffectedFilesExportedModulesMap);
            state.currentChangedFilePath = nextKey.value;
            state.affectedFilesIndex = 0;
            state.seenAffectedFiles = state.seenAffectedFiles || ts.createMap();
        }
    }
    /**
     * Returns next file to be emitted from files that retrieved semantic diagnostics but did not emit yet
     */
    function getNextAffectedFilePendingEmit(state) {
        var affectedFilesPendingEmit = state.affectedFilesPendingEmit;
        if (affectedFilesPendingEmit) {
            var seenEmittedFiles = state.seenEmittedFiles || (state.seenEmittedFiles = ts.createMap());
            for (var i = state.affectedFilesPendingEmitIndex; i < affectedFilesPendingEmit.length; i++) {
                var affectedFile = ts.Debug.checkDefined(state.program).getSourceFileByPath(affectedFilesPendingEmit[i]);
                if (affectedFile) {
                    var seenKind = seenEmittedFiles.get(affectedFile.resolvedPath);
                    var emitKind = ts.Debug.checkDefined(ts.Debug.checkDefined(state.affectedFilesPendingEmitKind).get(affectedFile.resolvedPath));
                    if (seenKind === undefined || seenKind < emitKind) {
                        // emit this file
                        state.affectedFilesPendingEmitIndex = i;
                        return { affectedFile: affectedFile, emitKind: emitKind };
                    }
                }
            }
            state.affectedFilesPendingEmit = undefined;
            state.affectedFilesPendingEmitKind = undefined;
            state.affectedFilesPendingEmitIndex = undefined;
        }
        return undefined;
    }
    /**
     *  Handles semantic diagnostics and dts emit for affectedFile and files, that are referencing modules that export entities from affected file
     *  This is because even though js emit doesnt change, dts emit / type used can change resulting in need for dts emit and js change
     */
    function handleDtsMayChangeOfAffectedFile(state, affectedFile, cancellationToken, computeHash) {
        removeSemanticDiagnosticsOf(state, affectedFile.resolvedPath);
        // If affected files is everything except default library, then nothing more to do
        if (state.allFilesExcludingDefaultLibraryFile === state.affectedFiles) {
            if (!state.cleanedDiagnosticsOfLibFiles) {
                state.cleanedDiagnosticsOfLibFiles = true;
                var program_1 = ts.Debug.checkDefined(state.program);
                var options_2 = program_1.getCompilerOptions();
                ts.forEach(program_1.getSourceFiles(), function (f) {
                    return program_1.isSourceFileDefaultLibrary(f) &&
                        !ts.skipTypeChecking(f, options_2, program_1) &&
                        removeSemanticDiagnosticsOf(state, f.resolvedPath);
                });
            }
            return;
        }
        if (!state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) {
            forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, function (state, path) { return handleDtsMayChangeOf(state, path, cancellationToken, computeHash); });
        }
    }
    /**
     * Handle the dts may change, so they need to be added to pending emit if dts emit is enabled,
     * Also we need to make sure signature is updated for these files
     */
    function handleDtsMayChangeOf(state, path, cancellationToken, computeHash) {
        removeSemanticDiagnosticsOf(state, path);
        if (!state.changedFilesSet.has(path)) {
            var program = ts.Debug.checkDefined(state.program);
            var sourceFile = program.getSourceFileByPath(path);
            if (sourceFile) {
                // Even though the js emit doesnt change and we are already handling dts emit and semantic diagnostics
                // we need to update the signature to reflect correctness of the signature(which is output d.ts emit) of this file
                // This ensures that we dont later during incremental builds considering wrong signature.
                // Eg where this also is needed to ensure that .tsbuildinfo generated by incremental build should be same as if it was first fresh build
                ts.BuilderState.updateShapeSignature(state, program, sourceFile, ts.Debug.checkDefined(state.currentAffectedFilesSignatures), cancellationToken, computeHash, state.currentAffectedFilesExportedModulesMap);
                // If not dts emit, nothing more to do
                if (ts.getEmitDeclarations(state.compilerOptions)) {
                    addToAffectedFilesPendingEmit(state, path, 0 /* DtsOnly */);
                }
            }
        }
        return false;
    }
    /**
     * Removes semantic diagnostics for path and
     * returns true if there are no more semantic diagnostics from the old state
     */
    function removeSemanticDiagnosticsOf(state, path) {
        if (!state.semanticDiagnosticsFromOldState) {
            return true;
        }
        state.semanticDiagnosticsFromOldState.delete(path);
        state.semanticDiagnosticsPerFile.delete(path);
        return !state.semanticDiagnosticsFromOldState.size;
    }
    function isChangedSignagure(state, path) {
        var newSignature = ts.Debug.checkDefined(state.currentAffectedFilesSignatures).get(path);
        var oldSignagure = ts.Debug.checkDefined(state.fileInfos.get(path)).signature;
        return newSignature !== oldSignagure;
    }
    /**
     * Iterate on referencing modules that export entities from affected file
     */
    function forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, fn) {
        // If there was change in signature (dts output) for the changed file,
        // then only we need to handle pending file emit
        if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) {
            return;
        }
        if (!isChangedSignagure(state, affectedFile.resolvedPath))
            return;
        // Since isolated modules dont change js files, files affected by change in signature is itself
        // But we need to cleanup semantic diagnostics and queue dts emit for affected files
        if (state.compilerOptions.isolatedModules) {
            var seenFileNamesMap = ts.createMap();
            seenFileNamesMap.set(affectedFile.resolvedPath, true);
            var queue = ts.BuilderState.getReferencedByPaths(state, affectedFile.resolvedPath);
            while (queue.length > 0) {
                var currentPath = queue.pop();
                if (!seenFileNamesMap.has(currentPath)) {
                    seenFileNamesMap.set(currentPath, true);
                    var result = fn(state, currentPath);
                    if (result && isChangedSignagure(state, currentPath)) {
                        var currentSourceFile = ts.Debug.checkDefined(state.program).getSourceFileByPath(currentPath);
                        queue.push.apply(queue, ts.BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath));
                    }
                }
            }
        }
        ts.Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
        var seenFileAndExportsOfFile = ts.createMap();
        // Go through exported modules from cache first
        // If exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.currentAffectedFilesExportedModulesMap, function (exportedModules, exportedFromPath) {
            return exportedModules &&
                exportedModules.has(affectedFile.resolvedPath) &&
                forEachFilesReferencingPath(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return;
        }
        // If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
        ts.forEachEntry(state.exportedModulesMap, function (exportedModules, exportedFromPath) {
            return !state.currentAffectedFilesExportedModulesMap.has(exportedFromPath) && // If we already iterated this through cache, ignore it
                exportedModules.has(affectedFile.resolvedPath) &&
                forEachFilesReferencingPath(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        });
    }
    /**
     * Iterate on files referencing referencedPath
     */
    function forEachFilesReferencingPath(state, referencedPath, seenFileAndExportsOfFile, fn) {
        return ts.forEachEntry(state.referencedMap, function (referencesInFile, filePath) {
            return referencesInFile.has(referencedPath) && forEachFileAndExportsOfFile(state, filePath, seenFileAndExportsOfFile, fn);
        });
    }
    /**
     * fn on file and iterate on anything that exports this file
     */
    function forEachFileAndExportsOfFile(state, filePath, seenFileAndExportsOfFile, fn) {
        if (!ts.addToSeen(seenFileAndExportsOfFile, filePath)) {
            return false;
        }
        if (fn(state, filePath)) {
            // If there are no more diagnostics from old cache, done
            return true;
        }
        ts.Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
        // Go through exported modules from cache first
        // If exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.currentAffectedFilesExportedModulesMap, function (exportedModules, exportedFromPath) {
            return exportedModules &&
                exportedModules.has(filePath) &&
                forEachFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return true;
        }
        // If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
        if (ts.forEachEntry(state.exportedModulesMap, function (exportedModules, exportedFromPath) {
            return !state.currentAffectedFilesExportedModulesMap.has(exportedFromPath) && // If we already iterated this through cache, ignore it
                exportedModules.has(filePath) &&
                forEachFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, fn);
        })) {
            return true;
        }
        // Remove diagnostics of files that import this file (without going to exports of referencing files)
        return !!ts.forEachEntry(state.referencedMap, function (referencesInFile, referencingFilePath) {
            return referencesInFile.has(filePath) &&
                !seenFileAndExportsOfFile.has(referencingFilePath) && // Not already removed diagnostic file
                fn(state, referencingFilePath);
        } // Dont add to seen since this is not yet done with the export removal
        );
    }
    /**
     * This is called after completing operation on the next affected file.
     * The operations here are postponed to ensure that cancellation during the iteration is handled correctly
     */
    function doneWithAffectedFile(state, affected, emitKind, isPendingEmit, isBuildInfoEmit) {
        if (isBuildInfoEmit) {
            state.emittedBuildInfo = true;
        }
        else if (affected === state.program) {
            state.changedFilesSet.clear();
            state.programEmitComplete = true;
        }
        else {
            state.seenAffectedFiles.set(affected.resolvedPath, true);
            if (emitKind !== undefined) {
                (state.seenEmittedFiles || (state.seenEmittedFiles = ts.createMap())).set(affected.resolvedPath, emitKind);
            }
            if (isPendingEmit) {
                state.affectedFilesPendingEmitIndex++;
            }
            else {
                state.affectedFilesIndex++;
            }
        }
    }
    /**
     * Returns the result with affected file
     */
    function toAffectedFileResult(state, result, affected) {
        doneWithAffectedFile(state, affected);
        return { result: result, affected: affected };
    }
    /**
     * Returns the result with affected file
     */
    function toAffectedFileEmitResult(state, result, affected, emitKind, isPendingEmit, isBuildInfoEmit) {
        doneWithAffectedFile(state, affected, emitKind, isPendingEmit, isBuildInfoEmit);
        return { result: result, affected: affected };
    }
    /**
     * Gets semantic diagnostics for the file which are
     * bindAndCheckDiagnostics (from cache) and program diagnostics
     */
    function getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken) {
        return ts.concatenate(getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken), ts.Debug.checkDefined(state.program).getProgramDiagnostics(sourceFile));
    }
    /**
     * Gets the binder and checker diagnostics either from cache if present, or otherwise from program and caches it
     * Note that it is assumed that when asked about binder and checker diagnostics, the file has been taken out of affected files/changed file set
     */
    function getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken) {
        var path = sourceFile.resolvedPath;
        if (state.semanticDiagnosticsPerFile) {
            var cachedDiagnostics = state.semanticDiagnosticsPerFile.get(path);
            // Report the bind and check diagnostics from the cache if we already have those diagnostics present
            if (cachedDiagnostics) {
                return cachedDiagnostics;
            }
        }
        // Diagnostics werent cached, get them from program, and cache the result
        var diagnostics = ts.Debug.checkDefined(state.program).getBindAndCheckDiagnostics(sourceFile, cancellationToken);
        if (state.semanticDiagnosticsPerFile) {
            state.semanticDiagnosticsPerFile.set(path, diagnostics);
        }
        return diagnostics;
    }
    /**
     * Gets the program information to be emitted in buildInfo so that we can use it to create new program
     */
    function getProgramBuildInfo(state, getCanonicalFileName) {
        if (state.compilerOptions.outFile || state.compilerOptions.out)
            return undefined;
        var currentDirectory = ts.Debug.checkDefined(state.program).getCurrentDirectory();
        var buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(ts.getTsBuildInfoEmitOutputFilePath(state.compilerOptions), currentDirectory));
        var fileInfos = {};
        state.fileInfos.forEach(function (value, key) {
            var signature = state.currentAffectedFilesSignatures && state.currentAffectedFilesSignatures.get(key);
            fileInfos[relativeToBuildInfo(key)] = signature === undefined ? value : { version: value.version, signature: signature, affectsGlobalScope: value.affectsGlobalScope };
        });
        var result = {
            fileInfos: fileInfos,
            options: convertToReusableCompilerOptions(state.compilerOptions, relativeToBuildInfoEnsuringAbsolutePath)
        };
        if (state.referencedMap) {
            var referencedMap = {};
            for (var _i = 0, _a = ts.arrayFrom(state.referencedMap.keys()).sort(ts.compareStringsCaseSensitive); _i < _a.length; _i++) {
                var key = _a[_i];
                referencedMap[relativeToBuildInfo(key)] = ts.arrayFrom(state.referencedMap.get(key).keys(), relativeToBuildInfo).sort(ts.compareStringsCaseSensitive);
            }
            result.referencedMap = referencedMap;
        }
        if (state.exportedModulesMap) {
            var exportedModulesMap = {};
            for (var _b = 0, _c = ts.arrayFrom(state.exportedModulesMap.keys()).sort(ts.compareStringsCaseSensitive); _b < _c.length; _b++) {
                var key = _c[_b];
                var newValue = state.currentAffectedFilesExportedModulesMap && state.currentAffectedFilesExportedModulesMap.get(key);
                // Not in temporary cache, use existing value
                if (newValue === undefined)
                    exportedModulesMap[relativeToBuildInfo(key)] = ts.arrayFrom(state.exportedModulesMap.get(key).keys(), relativeToBuildInfo).sort(ts.compareStringsCaseSensitive);
                // Value in cache and has updated value map, use that
                else if (newValue)
                    exportedModulesMap[relativeToBuildInfo(key)] = ts.arrayFrom(newValue.keys(), relativeToBuildInfo).sort(ts.compareStringsCaseSensitive);
            }
            result.exportedModulesMap = exportedModulesMap;
        }
        if (state.semanticDiagnosticsPerFile) {
            var semanticDiagnosticsPerFile = [];
            for (var _d = 0, _e = ts.arrayFrom(state.semanticDiagnosticsPerFile.keys()).sort(ts.compareStringsCaseSensitive); _d < _e.length; _d++) {
                var key = _e[_d];
                var value = state.semanticDiagnosticsPerFile.get(key);
                semanticDiagnosticsPerFile.push(value.length ?
                    [
                        relativeToBuildInfo(key),
                        state.hasReusableDiagnostic ?
                            value :
                            convertToReusableDiagnostics(value, relativeToBuildInfo)
                    ] :
                    relativeToBuildInfo(key));
            }
            result.semanticDiagnosticsPerFile = semanticDiagnosticsPerFile;
        }
        return result;
        function relativeToBuildInfoEnsuringAbsolutePath(path) {
            return relativeToBuildInfo(ts.getNormalizedAbsolutePath(path, currentDirectory));
        }
        function relativeToBuildInfo(path) {
            return ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(buildInfoDirectory, path, getCanonicalFileName));
        }
    }
    function convertToReusableCompilerOptions(options, relativeToBuildInfo) {
        var result = {};
        var optionsNameMap = ts.getOptionsNameMap().optionsNameMap;
        for (var name in options) {
            if (ts.hasProperty(options, name)) {
                result[name] = convertToReusableCompilerOptionValue(optionsNameMap.get(name.toLowerCase()), options[name], relativeToBuildInfo);
            }
        }
        if (result.configFilePath) {
            result.configFilePath = relativeToBuildInfo(result.configFilePath);
        }
        return result;
    }
    function convertToReusableCompilerOptionValue(option, value, relativeToBuildInfo) {
        if (option) {
            if (option.type === "list") {
                var values = value;
                if (option.element.isFilePath && values.length) {
                    return values.map(relativeToBuildInfo);
                }
            }
            else if (option.isFilePath) {
                return relativeToBuildInfo(value);
            }
        }
        return value;
    }
    function convertToReusableDiagnostics(diagnostics, relativeToBuildInfo) {
        ts.Debug.assert(!!diagnostics.length);
        return diagnostics.map(function (diagnostic) {
            var result = convertToReusableDiagnosticRelatedInformation(diagnostic, relativeToBuildInfo);
            result.reportsUnnecessary = diagnostic.reportsUnnecessary;
            result.source = diagnostic.source;
            var relatedInformation = diagnostic.relatedInformation;
            result.relatedInformation = relatedInformation ?
                relatedInformation.length ?
                    relatedInformation.map(function (r) { return convertToReusableDiagnosticRelatedInformation(r, relativeToBuildInfo); }) :
                    ts.emptyArray :
                undefined;
            return result;
        });
    }
    function convertToReusableDiagnosticRelatedInformation(diagnostic, relativeToBuildInfo) {
        var file = diagnostic.file;
        return __assign(__assign({}, diagnostic), { file: file ? relativeToBuildInfo(file.resolvedPath) : undefined });
    }
    var BuilderProgramKind;
    (function (BuilderProgramKind) {
        BuilderProgramKind[BuilderProgramKind["SemanticDiagnosticsBuilderProgram"] = 0] = "SemanticDiagnosticsBuilderProgram";
        BuilderProgramKind[BuilderProgramKind["EmitAndSemanticDiagnosticsBuilderProgram"] = 1] = "EmitAndSemanticDiagnosticsBuilderProgram";
    })(BuilderProgramKind = ts.BuilderProgramKind || (ts.BuilderProgramKind = {}));
    function getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        var host;
        var newProgram;
        var oldProgram;
        if (newProgramOrRootNames === undefined) {
            ts.Debug.assert(hostOrOptions === undefined);
            host = oldProgramOrHost;
            oldProgram = configFileParsingDiagnosticsOrOldProgram;
            ts.Debug.assert(!!oldProgram);
            newProgram = oldProgram.getProgram();
        }
        else if (ts.isArray(newProgramOrRootNames)) {
            oldProgram = configFileParsingDiagnosticsOrOldProgram;
            newProgram = ts.createProgram({
                rootNames: newProgramOrRootNames,
                options: hostOrOptions,
                host: oldProgramOrHost,
                oldProgram: oldProgram && oldProgram.getProgramOrUndefined(),
                configFileParsingDiagnostics: configFileParsingDiagnostics,
                projectReferences: projectReferences
            });
            host = oldProgramOrHost;
        }
        else {
            newProgram = newProgramOrRootNames;
            host = hostOrOptions;
            oldProgram = oldProgramOrHost;
            configFileParsingDiagnostics = configFileParsingDiagnosticsOrOldProgram;
        }
        return { host: host, newProgram: newProgram, oldProgram: oldProgram, configFileParsingDiagnostics: configFileParsingDiagnostics || ts.emptyArray };
    }
    ts.getBuilderCreationParameters = getBuilderCreationParameters;
    function createBuilderProgram(kind, _a) {
        var newProgram = _a.newProgram, host = _a.host, oldProgram = _a.oldProgram, configFileParsingDiagnostics = _a.configFileParsingDiagnostics;
        // Return same program if underlying program doesnt change
        var oldState = oldProgram && oldProgram.getState();
        if (oldState && newProgram === oldState.program && configFileParsingDiagnostics === newProgram.getConfigFileParsingDiagnostics()) {
            newProgram = undefined; // TODO: GH#18217
            oldState = undefined;
            return oldProgram;
        }
        /**
         * Create the canonical file name for identity
         */
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        /**
         * Computing hash to for signature verification
         */
        var computeHash = host.createHash || ts.generateDjb2Hash;
        var state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState);
        var backupState;
        newProgram.getProgramBuildInfo = function () { return getProgramBuildInfo(state, getCanonicalFileName); };
        // To ensure that we arent storing any references to old program or new program without state
        newProgram = undefined; // TODO: GH#18217
        oldProgram = undefined;
        oldState = undefined;
        var builderProgram = createRedirectedBuilderProgram(state, configFileParsingDiagnostics);
        builderProgram.getState = function () { return state; };
        builderProgram.backupState = function () {
            ts.Debug.assert(backupState === undefined);
            backupState = cloneBuilderProgramState(state);
        };
        builderProgram.restoreState = function () {
            state = ts.Debug.checkDefined(backupState);
            backupState = undefined;
        };
        builderProgram.getAllDependencies = function (sourceFile) { return ts.BuilderState.getAllDependencies(state, ts.Debug.checkDefined(state.program), sourceFile); };
        builderProgram.getSemanticDiagnostics = getSemanticDiagnostics;
        builderProgram.emit = emit;
        builderProgram.releaseProgram = function () {
            releaseCache(state);
            backupState = undefined;
        };
        if (kind === BuilderProgramKind.SemanticDiagnosticsBuilderProgram) {
            builderProgram.getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
        }
        else if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
            builderProgram.getSemanticDiagnosticsOfNextAffectedFile = getSemanticDiagnosticsOfNextAffectedFile;
            builderProgram.emitNextAffectedFile = emitNextAffectedFile;
        }
        else {
            ts.notImplemented();
        }
        return builderProgram;
        /**
         * Emits the next affected file's emit result (EmitResult and sourceFiles emitted) or returns undefined if iteration is complete
         * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
         * in that order would be used to write the files
         */
        function emitNextAffectedFile(writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
            var affected = getNextAffectedFile(state, cancellationToken, computeHash);
            var emitKind = 1 /* Full */;
            var isPendingEmitFile = false;
            if (!affected) {
                if (!state.compilerOptions.out && !state.compilerOptions.outFile) {
                    var pendingAffectedFile = getNextAffectedFilePendingEmit(state);
                    if (!pendingAffectedFile) {
                        if (state.emittedBuildInfo) {
                            return undefined;
                        }
                        var affected_1 = ts.Debug.checkDefined(state.program);
                        return toAffectedFileEmitResult(state, 
                        // When whole program is affected, do emit only once (eg when --out or --outFile is specified)
                        // Otherwise just affected file
                        affected_1.emitBuildInfo(writeFile || ts.maybeBind(host, host.writeFile), cancellationToken), affected_1, 1 /* Full */, 
                        /*isPendingEmitFile*/ false, 
                        /*isBuildInfoEmit*/ true);
                    }
                    (affected = pendingAffectedFile.affectedFile, emitKind = pendingAffectedFile.emitKind);
                    isPendingEmitFile = true;
                }
                else {
                    var program = ts.Debug.checkDefined(state.program);
                    if (state.programEmitComplete)
                        return undefined;
                    affected = program;
                }
            }
            return toAffectedFileEmitResult(state, 
            // When whole program is affected, do emit only once (eg when --out or --outFile is specified)
            // Otherwise just affected file
            ts.Debug.checkDefined(state.program).emit(affected === state.program ? undefined : affected, writeFile || ts.maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles || emitKind === 0 /* DtsOnly */, customTransformers), affected, emitKind, isPendingEmitFile);
        }
        /**
         * Emits the JavaScript and declaration files.
         * When targetSource file is specified, emits the files corresponding to that source file,
         * otherwise for the whole program.
         * In case of EmitAndSemanticDiagnosticsBuilderProgram, when targetSourceFile is specified,
         * it is assumed that that file is handled from affected file list. If targetSourceFile is not specified,
         * it will only emit all the affected files instead of whole program
         *
         * The first of writeFile if provided, writeFile of BuilderProgramHost if provided, writeFile of compiler host
         * in that order would be used to write the files
         */
        function emit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
            if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
                assertSourceFileOkWithoutNextAffectedCall(state, targetSourceFile);
                var result = ts.handleNoEmitOptions(builderProgram, targetSourceFile, cancellationToken);
                if (result)
                    return result;
                if (!targetSourceFile) {
                    // Emit and report any errors we ran into.
                    var sourceMaps = [];
                    var emitSkipped = false;
                    var diagnostics = void 0;
                    var emittedFiles = [];
                    var affectedEmitResult = void 0;
                    while (affectedEmitResult = emitNextAffectedFile(writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers)) {
                        emitSkipped = emitSkipped || affectedEmitResult.result.emitSkipped;
                        diagnostics = ts.addRange(diagnostics, affectedEmitResult.result.diagnostics);
                        emittedFiles = ts.addRange(emittedFiles, affectedEmitResult.result.emittedFiles);
                        sourceMaps = ts.addRange(sourceMaps, affectedEmitResult.result.sourceMaps);
                    }
                    return {
                        emitSkipped: emitSkipped,
                        diagnostics: diagnostics || ts.emptyArray,
                        emittedFiles: emittedFiles,
                        sourceMaps: sourceMaps
                    };
                }
            }
            return ts.Debug.checkDefined(state.program).emit(targetSourceFile, writeFile || ts.maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
        }
        /**
         * Return the semantic diagnostics for the next affected file or undefined if iteration is complete
         * If provided ignoreSourceFile would be called before getting the diagnostics and would ignore the sourceFile if the returned value was true
         */
        function getSemanticDiagnosticsOfNextAffectedFile(cancellationToken, ignoreSourceFile) {
            while (true) {
                var affected = getNextAffectedFile(state, cancellationToken, computeHash);
                if (!affected) {
                    // Done
                    return undefined;
                }
                else if (affected === state.program) {
                    // When whole program is affected, get all semantic diagnostics (eg when --out or --outFile is specified)
                    return toAffectedFileResult(state, state.program.getSemanticDiagnostics(/*targetSourceFile*/ undefined, cancellationToken), affected);
                }
                // Add file to affected file pending emit to handle for later emit time
                if (kind === BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram) {
                    addToAffectedFilesPendingEmit(state, affected.resolvedPath, 1 /* Full */);
                }
                // Get diagnostics for the affected file if its not ignored
                if (ignoreSourceFile && ignoreSourceFile(affected)) {
                    // Get next affected file
                    doneWithAffectedFile(state, affected);
                    continue;
                }
                return toAffectedFileResult(state, getSemanticDiagnosticsOfFile(state, affected, cancellationToken), affected);
            }
        }
        /**
         * Gets the semantic diagnostics from the program corresponding to this state of file (if provided) or whole program
         * The semantic diagnostics are cached and managed here
         * Note that it is assumed that when asked about semantic diagnostics through this API,
         * the file has been taken out of affected files so it is safe to use cache or get from program and cache the diagnostics
         * In case of SemanticDiagnosticsBuilderProgram if the source file is not provided,
         * it will iterate through all the affected files, to ensure that cache stays valid and yet provide a way to get all semantic diagnostics
         */
        function getSemanticDiagnostics(sourceFile, cancellationToken) {
            assertSourceFileOkWithoutNextAffectedCall(state, sourceFile);
            var compilerOptions = ts.Debug.checkDefined(state.program).getCompilerOptions();
            if (compilerOptions.outFile || compilerOptions.out) {
                ts.Debug.assert(!state.semanticDiagnosticsPerFile);
                // We dont need to cache the diagnostics just return them from program
                return ts.Debug.checkDefined(state.program).getSemanticDiagnostics(sourceFile, cancellationToken);
            }
            if (sourceFile) {
                return getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken);
            }
            // When semantic builder asks for diagnostics of the whole program,
            // ensure that all the affected files are handled
            // eslint-disable-next-line no-empty
            while (getSemanticDiagnosticsOfNextAffectedFile(cancellationToken)) {
            }
            var diagnostics;
            for (var _i = 0, _a = ts.Debug.checkDefined(state.program).getSourceFiles(); _i < _a.length; _i++) {
                var sourceFile_1 = _a[_i];
                diagnostics = ts.addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile_1, cancellationToken));
            }
            return diagnostics || ts.emptyArray;
        }
    }
    ts.createBuilderProgram = createBuilderProgram;
    function addToAffectedFilesPendingEmit(state, affectedFilePendingEmit, kind) {
        if (!state.affectedFilesPendingEmit)
            state.affectedFilesPendingEmit = [];
        if (!state.affectedFilesPendingEmitKind)
            state.affectedFilesPendingEmitKind = ts.createMap();
        var existingKind = state.affectedFilesPendingEmitKind.get(affectedFilePendingEmit);
        state.affectedFilesPendingEmit.push(affectedFilePendingEmit);
        state.affectedFilesPendingEmitKind.set(affectedFilePendingEmit, existingKind || kind);
        // affectedFilesPendingEmitIndex === undefined
        // - means the emit state.affectedFilesPendingEmit was undefined before adding current affected files
        //   so start from 0 as array would be affectedFilesPendingEmit
        // else, continue to iterate from existing index, the current set is appended to existing files
        if (state.affectedFilesPendingEmitIndex === undefined) {
            state.affectedFilesPendingEmitIndex = 0;
        }
    }
    function getMapOfReferencedSet(mapLike, toPath) {
        if (!mapLike)
            return undefined;
        var map = ts.createMap();
        // Copies keys/values from template. Note that for..in will not throw if
        // template is undefined, and instead will just exit the loop.
        for (var key in mapLike) {
            if (ts.hasProperty(mapLike, key)) {
                map.set(toPath(key), ts.arrayToSet(mapLike[key], toPath));
            }
        }
        return map;
    }
    function createBuildProgramUsingProgramBuildInfo(program, buildInfoPath, host) {
        var buildInfoDirectory = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        var fileInfos = ts.createMap();
        for (var key in program.fileInfos) {
            if (ts.hasProperty(program.fileInfos, key)) {
                fileInfos.set(toPath(key), program.fileInfos[key]);
            }
        }
        var state = {
            fileInfos: fileInfos,
            compilerOptions: ts.convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath),
            referencedMap: getMapOfReferencedSet(program.referencedMap, toPath),
            exportedModulesMap: getMapOfReferencedSet(program.exportedModulesMap, toPath),
            semanticDiagnosticsPerFile: program.semanticDiagnosticsPerFile && ts.arrayToMap(program.semanticDiagnosticsPerFile, function (value) { return toPath(ts.isString(value) ? value : value[0]); }, function (value) { return ts.isString(value) ? ts.emptyArray : value[1]; }),
            hasReusableDiagnostic: true
        };
        return {
            getState: function () { return state; },
            backupState: ts.noop,
            restoreState: ts.noop,
            getProgram: ts.notImplemented,
            getProgramOrUndefined: ts.returnUndefined,
            releaseProgram: ts.noop,
            getCompilerOptions: function () { return state.compilerOptions; },
            getSourceFile: ts.notImplemented,
            getSourceFiles: ts.notImplemented,
            getOptionsDiagnostics: ts.notImplemented,
            getGlobalDiagnostics: ts.notImplemented,
            getConfigFileParsingDiagnostics: ts.notImplemented,
            getSyntacticDiagnostics: ts.notImplemented,
            getDeclarationDiagnostics: ts.notImplemented,
            getSemanticDiagnostics: ts.notImplemented,
            emit: ts.notImplemented,
            getAllDependencies: ts.notImplemented,
            getCurrentDirectory: ts.notImplemented,
            emitNextAffectedFile: ts.notImplemented,
            getSemanticDiagnosticsOfNextAffectedFile: ts.notImplemented,
            close: ts.noop,
        };
        function toPath(path) {
            return ts.toPath(path, buildInfoDirectory, getCanonicalFileName);
        }
        function toAbsolutePath(path) {
            return ts.getNormalizedAbsolutePath(path, buildInfoDirectory);
        }
    }
    ts.createBuildProgramUsingProgramBuildInfo = createBuildProgramUsingProgramBuildInfo;
    function createRedirectedBuilderProgram(state, configFileParsingDiagnostics) {
        return {
            getState: ts.notImplemented,
            backupState: ts.noop,
            restoreState: ts.noop,
            getProgram: getProgram,
            getProgramOrUndefined: function () { return state.program; },
            releaseProgram: function () { return state.program = undefined; },
            getCompilerOptions: function () { return state.compilerOptions; },
            getSourceFile: function (fileName) { return getProgram().getSourceFile(fileName); },
            getSourceFiles: function () { return getProgram().getSourceFiles(); },
            getOptionsDiagnostics: function (cancellationToken) { return getProgram().getOptionsDiagnostics(cancellationToken); },
            getGlobalDiagnostics: function (cancellationToken) { return getProgram().getGlobalDiagnostics(cancellationToken); },
            getConfigFileParsingDiagnostics: function () { return configFileParsingDiagnostics; },
            getSyntacticDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getSyntacticDiagnostics(sourceFile, cancellationToken); },
            getDeclarationDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getDeclarationDiagnostics(sourceFile, cancellationToken); },
            getSemanticDiagnostics: function (sourceFile, cancellationToken) { return getProgram().getSemanticDiagnostics(sourceFile, cancellationToken); },
            emit: function (sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers) { return getProgram().emit(sourceFile, writeFile, cancellationToken, emitOnlyDts, customTransformers); },
            getAllDependencies: ts.notImplemented,
            getCurrentDirectory: function () { return getProgram().getCurrentDirectory(); },
            close: ts.noop,
        };
        function getProgram() {
            return ts.Debug.checkDefined(state.program);
        }
    }
    ts.createRedirectedBuilderProgram = createRedirectedBuilderProgram;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        return ts.createBuilderProgram(ts.BuilderProgramKind.SemanticDiagnosticsBuilderProgram, ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
    }
    ts.createSemanticDiagnosticsBuilderProgram = createSemanticDiagnosticsBuilderProgram;
    function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        return ts.createBuilderProgram(ts.BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
    }
    ts.createEmitAndSemanticDiagnosticsBuilderProgram = createEmitAndSemanticDiagnosticsBuilderProgram;
    function createAbstractBuilder(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences) {
        var _a = ts.getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences), newProgram = _a.newProgram, newConfigFileParsingDiagnostics = _a.configFileParsingDiagnostics;
        return ts.createRedirectedBuilderProgram({ program: newProgram, compilerOptions: newProgram.getCompilerOptions() }, newConfigFileParsingDiagnostics);
    }
    ts.createAbstractBuilder = createAbstractBuilder;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    function removeIgnoredPath(path) {
        // Consider whole staging folder as if node_modules changed.
        if (ts.endsWith(path, "/node_modules/.staging")) {
            return ts.removeSuffix(path, "/.staging");
        }
        return ts.some(ts.ignoredPaths, function (searchPath) { return ts.stringContains(path, searchPath); }) ?
            undefined :
            path;
    }
    ts.removeIgnoredPath = removeIgnoredPath;
    /**
     * Filter out paths like
     * "/", "/user", "/user/username", "/user/username/folderAtRoot",
     * "c:/", "c:/users", "c:/users/username", "c:/users/username/folderAtRoot", "c:/folderAtRoot"
     * @param dirPath
     */
    function canWatchDirectory(dirPath) {
        var rootLength = ts.getRootLength(dirPath);
        if (dirPath.length === rootLength) {
            // Ignore "/", "c:/"
            return false;
        }
        var nextDirectorySeparator = dirPath.indexOf(ts.directorySeparator, rootLength);
        if (nextDirectorySeparator === -1) {
            // ignore "/user", "c:/users" or "c:/folderAtRoot"
            return false;
        }
        var pathPartForUserCheck = dirPath.substring(rootLength, nextDirectorySeparator + 1);
        var isNonDirectorySeparatorRoot = rootLength > 1 || dirPath.charCodeAt(0) !== 47 /* slash */;
        if (isNonDirectorySeparatorRoot &&
            dirPath.search(/[a-zA-Z]:/) !== 0 && // Non dos style paths
            pathPartForUserCheck.search(/[a-zA-z]\$\//) === 0) { // Dos style nextPart
            nextDirectorySeparator = dirPath.indexOf(ts.directorySeparator, nextDirectorySeparator + 1);
            if (nextDirectorySeparator === -1) {
                // ignore "//vda1cs4850/c$/folderAtRoot"
                return false;
            }
            pathPartForUserCheck = dirPath.substring(rootLength + pathPartForUserCheck.length, nextDirectorySeparator + 1);
        }
        if (isNonDirectorySeparatorRoot &&
            pathPartForUserCheck.search(/users\//i) !== 0) {
            // Paths like c:/folderAtRoot/subFolder are allowed
            return true;
        }
        for (var searchIndex = nextDirectorySeparator + 1, searchLevels = 2; searchLevels > 0; searchLevels--) {
            searchIndex = dirPath.indexOf(ts.directorySeparator, searchIndex) + 1;
            if (searchIndex === 0) {
                // Folder isnt at expected minimum levels
                return false;
            }
        }
        return true;
    }
    ts.canWatchDirectory = canWatchDirectory;
    function createResolutionCache(resolutionHost, rootDirForResolution, logChangesWhenResolvingModule) {
        var filesWithChangedSetOfUnresolvedImports;
        var filesWithInvalidatedResolutions;
        var filesWithInvalidatedNonRelativeUnresolvedImports;
        var nonRelativeExternalModuleResolutions = ts.createMultiMap();
        var resolutionsWithFailedLookups = [];
        var resolvedFileToResolution = ts.createMultiMap();
        var getCurrentDirectory = ts.memoize(function () { return resolutionHost.getCurrentDirectory(); }); // TODO: GH#18217
        var cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
        // The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file.
        // The key in the map is source file's path.
        // The values are Map of resolutions with key being name lookedup.
        var resolvedModuleNames = ts.createMap();
        var perDirectoryResolvedModuleNames = ts.createCacheWithRedirects();
        var nonRelativeModuleNameCache = ts.createCacheWithRedirects();
        var moduleResolutionCache = ts.createModuleResolutionCacheWithMaps(perDirectoryResolvedModuleNames, nonRelativeModuleNameCache, getCurrentDirectory(), resolutionHost.getCanonicalFileName);
        var resolvedTypeReferenceDirectives = ts.createMap();
        var perDirectoryResolvedTypeReferenceDirectives = ts.createCacheWithRedirects();
        /**
         * These are the extensions that failed lookup files will have by default,
         * any other extension of failed lookup will be store that path in custom failed lookup path
         * This helps in not having to comb through all resolutions when files are added/removed
         * Note that .d.ts file also has .d.ts extension hence will be part of default extensions
         */
        var failedLookupDefaultExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".js" /* Js */, ".jsx" /* Jsx */, ".json" /* Json */];
        var customFailedLookupPaths = ts.createMap();
        var directoryWatchesOfFailedLookups = ts.createMap();
        var rootDir = rootDirForResolution && ts.removeTrailingDirectorySeparator(ts.getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory()));
        var rootPath = (rootDir && resolutionHost.toPath(rootDir)); // TODO: GH#18217
        var rootSplitLength = rootPath !== undefined ? rootPath.split(ts.directorySeparator).length : 0;
        // TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames
        var typeRootsWatches = ts.createMap();
        return {
            startRecordingFilesWithChangedResolutions: startRecordingFilesWithChangedResolutions,
            finishRecordingFilesWithChangedResolutions: finishRecordingFilesWithChangedResolutions,
            // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
            // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
            startCachingPerDirectoryResolution: clearPerDirectoryResolutions,
            finishCachingPerDirectoryResolution: finishCachingPerDirectoryResolution,
            resolveModuleNames: resolveModuleNames,
            getResolvedModuleWithFailedLookupLocationsFromCache: getResolvedModuleWithFailedLookupLocationsFromCache,
            resolveTypeReferenceDirectives: resolveTypeReferenceDirectives,
            removeResolutionsFromProjectReferenceRedirects: removeResolutionsFromProjectReferenceRedirects,
            removeResolutionsOfFile: removeResolutionsOfFile,
            invalidateResolutionOfFile: invalidateResolutionOfFile,
            setFilesWithInvalidatedNonRelativeUnresolvedImports: setFilesWithInvalidatedNonRelativeUnresolvedImports,
            createHasInvalidatedResolution: createHasInvalidatedResolution,
            updateTypeRootsWatch: updateTypeRootsWatch,
            closeTypeRootsWatch: closeTypeRootsWatch,
            clear: clear
        };
        function getResolvedModule(resolution) {
            return resolution.resolvedModule;
        }
        function getResolvedTypeReferenceDirective(resolution) {
            return resolution.resolvedTypeReferenceDirective;
        }
        function isInDirectoryPath(dir, file) {
            if (dir === undefined || file.length <= dir.length) {
                return false;
            }
            return ts.startsWith(file, dir) && file[dir.length] === ts.directorySeparator;
        }
        function clear() {
            ts.clearMap(directoryWatchesOfFailedLookups, ts.closeFileWatcherOf);
            customFailedLookupPaths.clear();
            nonRelativeExternalModuleResolutions.clear();
            closeTypeRootsWatch();
            resolvedModuleNames.clear();
            resolvedTypeReferenceDirectives.clear();
            resolvedFileToResolution.clear();
            resolutionsWithFailedLookups.length = 0;
            // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
            // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
            clearPerDirectoryResolutions();
        }
        function startRecordingFilesWithChangedResolutions() {
            filesWithChangedSetOfUnresolvedImports = [];
        }
        function finishRecordingFilesWithChangedResolutions() {
            var collected = filesWithChangedSetOfUnresolvedImports;
            filesWithChangedSetOfUnresolvedImports = undefined;
            return collected;
        }
        function isFileWithInvalidatedNonRelativeUnresolvedImports(path) {
            if (!filesWithInvalidatedNonRelativeUnresolvedImports) {
                return false;
            }
            // Invalidated if file has unresolved imports
            var value = filesWithInvalidatedNonRelativeUnresolvedImports.get(path);
            return !!value && !!value.length;
        }
        function createHasInvalidatedResolution(forceAllFilesAsInvalidated) {
            if (forceAllFilesAsInvalidated) {
                // Any file asked would have invalidated resolution
                filesWithInvalidatedResolutions = undefined;
                return ts.returnTrue;
            }
            var collected = filesWithInvalidatedResolutions;
            filesWithInvalidatedResolutions = undefined;
            return function (path) { return (!!collected && collected.has(path)) ||
                isFileWithInvalidatedNonRelativeUnresolvedImports(path); };
        }
        function clearPerDirectoryResolutions() {
            perDirectoryResolvedModuleNames.clear();
            nonRelativeModuleNameCache.clear();
            perDirectoryResolvedTypeReferenceDirectives.clear();
            nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
            nonRelativeExternalModuleResolutions.clear();
        }
        function finishCachingPerDirectoryResolution() {
            filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
            clearPerDirectoryResolutions();
            directoryWatchesOfFailedLookups.forEach(function (watcher, path) {
                if (watcher.refCount === 0) {
                    directoryWatchesOfFailedLookups.delete(path);
                    watcher.watcher.close();
                }
            });
        }
        function resolveModuleName(moduleName, containingFile, compilerOptions, host, redirectedReference) {
            var _a;
            var primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference);
            // return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts
            if (!resolutionHost.getGlobalCache) {
                return primaryResult;
            }
            // otherwise try to load typings from @types
            var globalCache = resolutionHost.getGlobalCache();
            if (globalCache !== undefined && !ts.isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && ts.extensionIsTS(primaryResult.resolvedModule.extension))) {
                // create different collection of failed lookup locations for second pass
                // if it will fail and we've already found something during the first pass - we don't want to pollute its results
                var _b = ts.loadModuleFromGlobalCache(ts.Debug.checkDefined(resolutionHost.globalCacheResolutionModuleName)(moduleName), resolutionHost.projectName, compilerOptions, host, globalCache), resolvedModule = _b.resolvedModule, failedLookupLocations = _b.failedLookupLocations;
                if (resolvedModule) {
                    // Modify existing resolution so its saved in the directory cache as well
                    primaryResult.resolvedModule = resolvedModule;
                    (_a = primaryResult.failedLookupLocations).push.apply(_a, failedLookupLocations);
                    return primaryResult;
                }
            }
            // Default return the result from the first pass
            return primaryResult;
        }
        function resolveNamesWithLocalCache(_a) {
            var _b;
            var names = _a.names, containingFile = _a.containingFile, redirectedReference = _a.redirectedReference, cache = _a.cache, perDirectoryCacheWithRedirects = _a.perDirectoryCacheWithRedirects, loader = _a.loader, getResolutionWithResolvedFileName = _a.getResolutionWithResolvedFileName, shouldRetryResolution = _a.shouldRetryResolution, reusedNames = _a.reusedNames, logChanges = _a.logChanges;
            var path = resolutionHost.toPath(containingFile);
            var resolutionsInFile = cache.get(path) || cache.set(path, ts.createMap()).get(path);
            var dirPath = ts.getDirectoryPath(path);
            var perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
            var perDirectoryResolution = perDirectoryCache.get(dirPath);
            if (!perDirectoryResolution) {
                perDirectoryResolution = ts.createMap();
                perDirectoryCache.set(dirPath, perDirectoryResolution);
            }
            var resolvedModules = [];
            var compilerOptions = resolutionHost.getCompilationSettings();
            var hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path);
            // All the resolutions in this file are invalidated if this file wasnt resolved using same redirect
            var program = resolutionHost.getCurrentProgram();
            var oldRedirect = program && program.getResolvedProjectReferenceToRedirect(containingFile);
            var unmatchedRedirects = oldRedirect ?
                !redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path :
                !!redirectedReference;
            var seenNamesInFile = ts.createMap();
            for (var _i = 0, names_3 = names; _i < names_3.length; _i++) {
                var name = names_3[_i];
                var resolution = resolutionsInFile.get(name);
                // Resolution is valid if it is present and not invalidated
                if (!seenNamesInFile.has(name) &&
                    unmatchedRedirects || !resolution || resolution.isInvalidated ||
                    // If the name is unresolved import that was invalidated, recalculate
                    (hasInvalidatedNonRelativeUnresolvedImport && !ts.isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) {
                    var existingResolution = resolution;
                    var resolutionInDirectory = perDirectoryResolution.get(name);
                    if (resolutionInDirectory) {
                        resolution = resolutionInDirectory;
                    }
                    else {
                        resolution = loader(name, containingFile, compilerOptions, ((_b = resolutionHost.getCompilerHost) === null || _b === void 0 ? void 0 : _b.call(resolutionHost)) || resolutionHost, redirectedReference);
                        perDirectoryResolution.set(name, resolution);
                    }
                    resolutionsInFile.set(name, resolution);
                    watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, path, getResolutionWithResolvedFileName);
                    if (existingResolution) {
                        stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolutionWithResolvedFileName);
                    }
                    if (logChanges && filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) {
                        filesWithChangedSetOfUnresolvedImports.push(path);
                        // reset log changes to avoid recording the same file multiple times
                        logChanges = false;
                    }
                }
                ts.Debug.assert(resolution !== undefined && !resolution.isInvalidated);
                seenNamesInFile.set(name, true);
                resolvedModules.push(getResolutionWithResolvedFileName(resolution));
            }
            // Stop watching and remove the unused name
            resolutionsInFile.forEach(function (resolution, name) {
                if (!seenNamesInFile.has(name) && !ts.contains(reusedNames, name)) {
                    stopWatchFailedLookupLocationOfResolution(resolution, path, getResolutionWithResolvedFileName);
                    resolutionsInFile.delete(name);
                }
            });
            return resolvedModules;
            function resolutionIsEqualTo(oldResolution, newResolution) {
                if (oldResolution === newResolution) {
                    return true;
                }
                if (!oldResolution || !newResolution) {
                    return false;
                }
                var oldResult = getResolutionWithResolvedFileName(oldResolution);
                var newResult = getResolutionWithResolvedFileName(newResolution);
                if (oldResult === newResult) {
                    return true;
                }
                if (!oldResult || !newResult) {
                    return false;
                }
                return oldResult.resolvedFileName === newResult.resolvedFileName;
            }
        }
        function resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference) {
            return resolveNamesWithLocalCache({
                names: typeDirectiveNames,
                containingFile: containingFile,
                redirectedReference: redirectedReference,
                cache: resolvedTypeReferenceDirectives,
                perDirectoryCacheWithRedirects: perDirectoryResolvedTypeReferenceDirectives,
                loader: ts.resolveTypeReferenceDirective,
                getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective,
                shouldRetryResolution: function (resolution) { return resolution.resolvedTypeReferenceDirective === undefined; },
            });
        }
        function resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference) {
            return resolveNamesWithLocalCache({
                names: moduleNames,
                containingFile: containingFile,
                redirectedReference: redirectedReference,
                cache: resolvedModuleNames,
                perDirectoryCacheWithRedirects: perDirectoryResolvedModuleNames,
                loader: resolveModuleName,
                getResolutionWithResolvedFileName: getResolvedModule,
                shouldRetryResolution: function (resolution) { return !resolution.resolvedModule || !ts.resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension); },
                reusedNames: reusedNames,
                logChanges: logChangesWhenResolvingModule
            });
        }
        function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName, containingFile) {
            var cache = resolvedModuleNames.get(resolutionHost.toPath(containingFile));
            return cache && cache.get(moduleName);
        }
        function isNodeModulesAtTypesDirectory(dirPath) {
            return ts.endsWith(dirPath, "/node_modules/@types");
        }
        function getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath) {
            if (isInDirectoryPath(rootPath, failedLookupLocationPath)) {
                // Ensure failed look up is normalized path
                failedLookupLocation = ts.isRootedDiskPath(failedLookupLocation) ? ts.normalizePath(failedLookupLocation) : ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory());
                var failedLookupPathSplit = failedLookupLocationPath.split(ts.directorySeparator);
                var failedLookupSplit = failedLookupLocation.split(ts.directorySeparator);
                ts.Debug.assert(failedLookupSplit.length === failedLookupPathSplit.length, "FailedLookup: " + failedLookupLocation + " failedLookupLocationPath: " + failedLookupLocationPath);
                if (failedLookupPathSplit.length > rootSplitLength + 1) {
                    // Instead of watching root, watch directory in root to avoid watching excluded directories not needed for module resolution
                    return {
                        dir: failedLookupSplit.slice(0, rootSplitLength + 1).join(ts.directorySeparator),
                        dirPath: failedLookupPathSplit.slice(0, rootSplitLength + 1).join(ts.directorySeparator)
                    };
                }
                else {
                    // Always watch root directory non recursively
                    return {
                        dir: rootDir,
                        dirPath: rootPath,
                        nonRecursive: false
                    };
                }
            }
            return getDirectoryToWatchFromFailedLookupLocationDirectory(ts.getDirectoryPath(ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory())), ts.getDirectoryPath(failedLookupLocationPath));
        }
        function getDirectoryToWatchFromFailedLookupLocationDirectory(dir, dirPath) {
            // If directory path contains node module, get the most parent node_modules directory for watching
            while (ts.pathContainsNodeModules(dirPath)) {
                dir = ts.getDirectoryPath(dir);
                dirPath = ts.getDirectoryPath(dirPath);
            }
            // If the directory is node_modules use it to watch, always watch it recursively
            if (ts.isNodeModulesDirectory(dirPath)) {
                return canWatchDirectory(ts.getDirectoryPath(dirPath)) ? { dir: dir, dirPath: dirPath } : undefined;
            }
            var nonRecursive = true;
            // Use some ancestor of the root directory
            var subDirectoryPath, subDirectory;
            if (rootPath !== undefined) {
                while (!isInDirectoryPath(dirPath, rootPath)) {
                    var parentPath = ts.getDirectoryPath(dirPath);
                    if (parentPath === dirPath) {
                        break;
                    }
                    nonRecursive = false;
                    subDirectoryPath = dirPath;
                    subDirectory = dir;
                    dirPath = parentPath;
                    dir = ts.getDirectoryPath(dir);
                }
            }
            return canWatchDirectory(dirPath) ? { dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath, nonRecursive: nonRecursive } : undefined;
        }
        function isPathWithDefaultFailedLookupExtension(path) {
            return ts.fileExtensionIsOneOf(path, failedLookupDefaultExtensions);
        }
        function watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution, filePath, getResolutionWithResolvedFileName) {
            if (resolution.refCount) {
                resolution.refCount++;
                ts.Debug.assertDefined(resolution.files);
            }
            else {
                resolution.refCount = 1;
                ts.Debug.assert(resolution.files === undefined);
                if (ts.isExternalModuleNameRelative(name)) {
                    watchFailedLookupLocationOfResolution(resolution);
                }
                else {
                    nonRelativeExternalModuleResolutions.add(name, resolution);
                }
                var resolved = getResolutionWithResolvedFileName(resolution);
                if (resolved && resolved.resolvedFileName) {
                    resolvedFileToResolution.add(resolutionHost.toPath(resolved.resolvedFileName), resolution);
                }
            }
            (resolution.files || (resolution.files = [])).push(filePath);
        }
        function watchFailedLookupLocationOfResolution(resolution) {
            ts.Debug.assert(!!resolution.refCount);
            var failedLookupLocations = resolution.failedLookupLocations;
            if (!failedLookupLocations.length)
                return;
            resolutionsWithFailedLookups.push(resolution);
            var setAtRoot = false;
            for (var _i = 0, failedLookupLocations_1 = failedLookupLocations; _i < failedLookupLocations_1.length; _i++) {
                var failedLookupLocation = failedLookupLocations_1[_i];
                var failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
                var toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
                if (toWatch) {
                    var dir = toWatch.dir, dirPath = toWatch.dirPath, nonRecursive = toWatch.nonRecursive;
                    // If the failed lookup location path is not one of the supported extensions,
                    // store it in the custom path
                    if (!isPathWithDefaultFailedLookupExtension(failedLookupLocationPath)) {
                        var refCount = customFailedLookupPaths.get(failedLookupLocationPath) || 0;
                        customFailedLookupPaths.set(failedLookupLocationPath, refCount + 1);
                    }
                    if (dirPath === rootPath) {
                        ts.Debug.assert(!nonRecursive);
                        setAtRoot = true;
                    }
                    else {
                        setDirectoryWatcher(dir, dirPath, nonRecursive);
                    }
                }
            }
            if (setAtRoot) {
                // This is always non recursive
                setDirectoryWatcher(rootDir, rootPath, /*nonRecursive*/ true); // TODO: GH#18217
            }
        }
        function watchFailedLookupLocationOfNonRelativeModuleResolutions(resolutions, name) {
            var program = resolutionHost.getCurrentProgram();
            if (!program || !program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(name)) {
                resolutions.forEach(watchFailedLookupLocationOfResolution);
            }
        }
        function setDirectoryWatcher(dir, dirPath, nonRecursive) {
            var dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
            if (dirWatcher) {
                ts.Debug.assert(!!nonRecursive === !!dirWatcher.nonRecursive);
                dirWatcher.refCount++;
            }
            else {
                directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath, nonRecursive), refCount: 1, nonRecursive: nonRecursive });
            }
        }
        function stopWatchFailedLookupLocationOfResolution(resolution, filePath, getResolutionWithResolvedFileName) {
            ts.unorderedRemoveItem(ts.Debug.assertDefined(resolution.files), filePath);
            resolution.refCount--;
            if (resolution.refCount) {
                return;
            }
            var resolved = getResolutionWithResolvedFileName(resolution);
            if (resolved && resolved.resolvedFileName) {
                resolvedFileToResolution.remove(resolutionHost.toPath(resolved.resolvedFileName), resolution);
            }
            if (!ts.unorderedRemoveItem(resolutionsWithFailedLookups, resolution)) {
                // If not watching failed lookups, it wont be there in resolutionsWithFailedLookups
                return;
            }
            var failedLookupLocations = resolution.failedLookupLocations;
            var removeAtRoot = false;
            for (var _i = 0, failedLookupLocations_2 = failedLookupLocations; _i < failedLookupLocations_2.length; _i++) {
                var failedLookupLocation = failedLookupLocations_2[_i];
                var failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
                var toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
                if (toWatch) {
                    var dirPath = toWatch.dirPath;
                    var refCount = customFailedLookupPaths.get(failedLookupLocationPath);
                    if (refCount) {
                        if (refCount === 1) {
                            customFailedLookupPaths.delete(failedLookupLocationPath);
                        }
                        else {
                            ts.Debug.assert(refCount > 1);
                            customFailedLookupPaths.set(failedLookupLocationPath, refCount - 1);
                        }
                    }
                    if (dirPath === rootPath) {
                        removeAtRoot = true;
                    }
                    else {
                        removeDirectoryWatcher(dirPath);
                    }
                }
            }
            if (removeAtRoot) {
                removeDirectoryWatcher(rootPath);
            }
        }
        function removeDirectoryWatcher(dirPath) {
            var dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
            // Do not close the watcher yet since it might be needed by other failed lookup locations.
            dirWatcher.refCount--;
        }
        function createDirectoryWatcher(directory, dirPath, nonRecursive) {
            return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, function (fileOrDirectory) {
                var fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
                if (cachedDirectoryStructureHost) {
                    // Since the file existence changed, update the sourceFiles cache
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                if (invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
                    resolutionHost.onInvalidatedResolution();
                }
            }, nonRecursive ? 0 /* None */ : 1 /* Recursive */);
        }
        function removeResolutionsOfFileFromCache(cache, filePath, getResolutionWithResolvedFileName) {
            // Deleted file, stop watching failed lookups for all the resolutions in the file
            var resolutions = cache.get(filePath);
            if (resolutions) {
                resolutions.forEach(function (resolution) { return stopWatchFailedLookupLocationOfResolution(resolution, filePath, getResolutionWithResolvedFileName); });
                cache.delete(filePath);
            }
        }
        function removeResolutionsFromProjectReferenceRedirects(filePath) {
            if (!ts.fileExtensionIs(filePath, ".json" /* Json */)) {
                return;
            }
            var program = resolutionHost.getCurrentProgram();
            if (!program) {
                return;
            }
            // If this file is input file for the referenced project, get it
            var resolvedProjectReference = program.getResolvedProjectReferenceByPath(filePath);
            if (!resolvedProjectReference) {
                return;
            }
            // filePath is for the projectReference and the containing file is from this project reference, invalidate the resolution
            resolvedProjectReference.commandLine.fileNames.forEach(function (f) { return removeResolutionsOfFile(resolutionHost.toPath(f)); });
        }
        function removeResolutionsOfFile(filePath) {
            removeResolutionsOfFileFromCache(resolvedModuleNames, filePath, getResolvedModule);
            removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath, getResolvedTypeReferenceDirective);
        }
        function invalidateResolution(resolution) {
            resolution.isInvalidated = true;
            var changedInAutoTypeReferenced = false;
            for (var _i = 0, _a = ts.Debug.assertDefined(resolution.files); _i < _a.length; _i++) {
                var containingFilePath = _a[_i];
                (filesWithInvalidatedResolutions || (filesWithInvalidatedResolutions = ts.createMap())).set(containingFilePath, true);
                // When its a file with inferred types resolution, invalidate type reference directive resolution
                changedInAutoTypeReferenced = changedInAutoTypeReferenced || containingFilePath.endsWith(ts.inferredTypesContainingFile);
            }
            if (changedInAutoTypeReferenced) {
                resolutionHost.onChangedAutomaticTypeDirectiveNames();
            }
        }
        function invalidateResolutionOfFile(filePath) {
            removeResolutionsOfFile(filePath);
            // Resolution is invalidated if the resulting file name is same as the deleted file path
            ts.forEach(resolvedFileToResolution.get(filePath), invalidateResolution);
        }
        function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap) {
            ts.Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined);
            filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
        }
        function invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, isCreatingWatchedDirectory) {
            var isChangedFailedLookupLocation;
            if (isCreatingWatchedDirectory) {
                // Watching directory is created
                // Invalidate any resolution has failed lookup in this directory
                isChangedFailedLookupLocation = function (location) { return isInDirectoryPath(fileOrDirectoryPath, resolutionHost.toPath(location)); };
            }
            else {
                // If something to do with folder/file starting with "." in node_modules folder, skip it
                var updatedPath = removeIgnoredPath(fileOrDirectoryPath);
                if (!updatedPath)
                    return false;
                fileOrDirectoryPath = updatedPath;
                // prevent saving an open file from over-eagerly triggering invalidation
                if (resolutionHost.fileIsOpen(fileOrDirectoryPath)) {
                    return false;
                }
                // Some file or directory in the watching directory is created
                // Return early if it does not have any of the watching extension or not the custom failed lookup path
                var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath);
                if (isNodeModulesAtTypesDirectory(fileOrDirectoryPath) || ts.isNodeModulesDirectory(fileOrDirectoryPath) ||
                    isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || ts.isNodeModulesDirectory(dirOfFileOrDirectory)) {
                    // Invalidate any resolution from this directory
                    isChangedFailedLookupLocation = function (location) {
                        var locationPath = resolutionHost.toPath(location);
                        return locationPath === fileOrDirectoryPath || ts.startsWith(resolutionHost.toPath(location), fileOrDirectoryPath);
                    };
                }
                else {
                    if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) {
                        return false;
                    }
                    // Ignore emits from the program
                    if (ts.isEmittedFileOfProgram(resolutionHost.getCurrentProgram(), fileOrDirectoryPath)) {
                        return false;
                    }
                    // Resolution need to be invalidated if failed lookup location is same as the file or directory getting created
                    isChangedFailedLookupLocation = function (location) { return resolutionHost.toPath(location) === fileOrDirectoryPath; };
                }
            }
            var invalidated = false;
            // Resolution is invalidated if the resulting file name is same as the deleted file path
            for (var _i = 0, resolutionsWithFailedLookups_1 = resolutionsWithFailedLookups; _i < resolutionsWithFailedLookups_1.length; _i++) {
                var resolution = resolutionsWithFailedLookups_1[_i];
                if (resolution.failedLookupLocations.some(isChangedFailedLookupLocation)) {
                    invalidateResolution(resolution);
                    invalidated = true;
                }
            }
            return invalidated;
        }
        function closeTypeRootsWatch() {
            ts.clearMap(typeRootsWatches, ts.closeFileWatcher);
        }
        function getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot, typeRootPath) {
            if (isInDirectoryPath(rootPath, typeRootPath)) {
                return rootPath;
            }
            var toWatch = getDirectoryToWatchFromFailedLookupLocationDirectory(typeRoot, typeRootPath);
            return toWatch && directoryWatchesOfFailedLookups.has(toWatch.dirPath) ? toWatch.dirPath : undefined;
        }
        function createTypeRootsWatch(typeRootPath, typeRoot) {
            // Create new watch and recursive info
            return resolutionHost.watchTypeRootsDirectory(typeRoot, function (fileOrDirectory) {
                var fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
                if (cachedDirectoryStructureHost) {
                    // Since the file existence changed, update the sourceFiles cache
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                // For now just recompile
                // We could potentially store more data here about whether it was/would be really be used or not
                // and with that determine to trigger compilation but for now this is enough
                resolutionHost.onChangedAutomaticTypeDirectiveNames();
                // Since directory watchers invoked are flaky, the failed lookup location events might not be triggered
                // So handle to failed lookup locations here as well to ensure we are invalidating resolutions
                var dirPath = getDirectoryToWatchFailedLookupLocationFromTypeRoot(typeRoot, typeRootPath);
                if (dirPath && invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
                    resolutionHost.onInvalidatedResolution();
                }
            }, 1 /* Recursive */);
        }
        /**
         * Watches the types that would get added as part of getAutomaticTypeDirectiveNames
         * To be called when compiler options change
         */
        function updateTypeRootsWatch() {
            var options = resolutionHost.getCompilationSettings();
            if (options.types) {
                // No need to do any watch since resolution cache is going to handle the failed lookups
                // for the types added by this
                closeTypeRootsWatch();
                return;
            }
            // we need to assume the directories exist to ensure that we can get all the type root directories that get included
            // But filter directories that are at root level to say directory doesnt exist, so that we arent watching them
            var typeRoots = ts.getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory: getCurrentDirectory });
            if (typeRoots) {
                ts.mutateMap(typeRootsWatches, ts.arrayToMap(typeRoots, function (tr) { return resolutionHost.toPath(tr); }), {
                    createNewValue: createTypeRootsWatch,
                    onDeleteValue: ts.closeFileWatcher
                });
            }
            else {
                closeTypeRootsWatch();
            }
        }
        /**
         * Use this function to return if directory exists to get type roots to watch
         * If we return directory exists then only the paths will be added to type roots
         * Hence return true for all directories except root directories which are filtered from watching
         */
        function directoryExistsForTypeRootWatch(nodeTypesDirectory) {
            var dir = ts.getDirectoryPath(ts.getDirectoryPath(nodeTypesDirectory));
            var dirPath = resolutionHost.toPath(dir);
            return dirPath === rootPath || canWatchDirectory(dirPath);
        }
    }
    ts.createResolutionCache = createResolutionCache;
})(ts || (ts = {}));
// Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers.
/* @internal */
var ts;
(function (ts) {
    var moduleSpecifiers;
    (function (moduleSpecifiers) {
        var RelativePreference;
        (function (RelativePreference) {
            RelativePreference[RelativePreference["Relative"] = 0] = "Relative";
            RelativePreference[RelativePreference["NonRelative"] = 1] = "NonRelative";
            RelativePreference[RelativePreference["Auto"] = 2] = "Auto";
        })(RelativePreference || (RelativePreference = {}));
        // See UserPreferences#importPathEnding
        var Ending;
        (function (Ending) {
            Ending[Ending["Minimal"] = 0] = "Minimal";
            Ending[Ending["Index"] = 1] = "Index";
            Ending[Ending["JsExtension"] = 2] = "JsExtension";
        })(Ending || (Ending = {}));
        function getPreferences(_a, compilerOptions, importingSourceFile) {
            var importModuleSpecifierPreference = _a.importModuleSpecifierPreference, importModuleSpecifierEnding = _a.importModuleSpecifierEnding;
            return {
                relativePreference: importModuleSpecifierPreference === "relative" ? 0 /* Relative */ : importModuleSpecifierPreference === "non-relative" ? 1 /* NonRelative */ : 2 /* Auto */,
                ending: getEnding(),
            };
            function getEnding() {
                switch (importModuleSpecifierEnding) {
                    case "minimal": return 0 /* Minimal */;
                    case "index": return 1 /* Index */;
                    case "js": return 2 /* JsExtension */;
                    default: return usesJsExtensionOnImports(importingSourceFile) ? 2 /* JsExtension */
                        : ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeJs ? 1 /* Index */ : 0 /* Minimal */;
                }
            }
        }
        function getPreferencesForUpdate(compilerOptions, oldImportSpecifier) {
            return {
                relativePreference: ts.isExternalModuleNameRelative(oldImportSpecifier) ? 0 /* Relative */ : 1 /* NonRelative */,
                ending: ts.hasJSFileExtension(oldImportSpecifier) ?
                    2 /* JsExtension */ :
                    ts.getEmitModuleResolutionKind(compilerOptions) !== ts.ModuleResolutionKind.NodeJs || ts.endsWith(oldImportSpecifier, "index") ? 1 /* Index */ : 0 /* Minimal */,
            };
        }
        function updateModuleSpecifier(compilerOptions, importingSourceFileName, toFileName, host, oldImportSpecifier) {
            var res = getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, getPreferencesForUpdate(compilerOptions, oldImportSpecifier));
            if (res === oldImportSpecifier)
                return undefined;
            return res;
        }
        moduleSpecifiers.updateModuleSpecifier = updateModuleSpecifier;
        // Note: importingSourceFile is just for usesJsExtensionOnImports
        function getModuleSpecifier(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, preferences) {
            if (preferences === void 0) { preferences = {}; }
            return getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, getPreferences(preferences, compilerOptions, importingSourceFile));
        }
        moduleSpecifiers.getModuleSpecifier = getModuleSpecifier;
        function getNodeModulesPackageName(compilerOptions, importingSourceFileName, nodeModulesFileName, host) {
            var info = getInfo(importingSourceFileName, host);
            var modulePaths = getAllModulePaths(importingSourceFileName, nodeModulesFileName, host);
            return ts.firstDefined(modulePaths, function (moduleFileName) { return tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions, /*packageNameOnly*/ true); });
        }
        moduleSpecifiers.getNodeModulesPackageName = getNodeModulesPackageName;
        function getModuleSpecifierWorker(compilerOptions, importingSourceFileName, toFileName, host, preferences) {
            var info = getInfo(importingSourceFileName, host);
            var modulePaths = getAllModulePaths(importingSourceFileName, toFileName, host);
            return ts.firstDefined(modulePaths, function (moduleFileName) { return tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions); }) ||
                getLocalModuleSpecifier(toFileName, info, compilerOptions, preferences);
        }
        /** Returns an import for each symlink and for the realpath. */
        function getModuleSpecifiers(moduleSymbol, compilerOptions, importingSourceFile, host, userPreferences) {
            var ambient = tryGetModuleNameFromAmbientModule(moduleSymbol);
            if (ambient)
                return [ambient];
            var info = getInfo(importingSourceFile.path, host);
            var moduleSourceFile = ts.getSourceFileOfNode(moduleSymbol.valueDeclaration || ts.getNonAugmentationDeclaration(moduleSymbol));
            var modulePaths = getAllModulePaths(importingSourceFile.path, moduleSourceFile.originalFileName, host);
            var preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
            var global = ts.mapDefined(modulePaths, function (moduleFileName) { return tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions); });
            return global.length ? global : modulePaths.map(function (moduleFileName) { return getLocalModuleSpecifier(moduleFileName, info, compilerOptions, preferences); });
        }
        moduleSpecifiers.getModuleSpecifiers = getModuleSpecifiers;
        // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path
        function getInfo(importingSourceFileName, host) {
            var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true);
            var sourceDirectory = ts.getDirectoryPath(importingSourceFileName);
            return { getCanonicalFileName: getCanonicalFileName, sourceDirectory: sourceDirectory };
        }
        function getLocalModuleSpecifier(moduleFileName, _a, compilerOptions, _b) {
            var getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory;
            var ending = _b.ending, relativePreference = _b.relativePreference;
            var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths, rootDirs = compilerOptions.rootDirs;
            var relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) ||
                removeExtensionAndIndexPostFix(ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
            if (!baseUrl || relativePreference === 0 /* Relative */) {
                return relativePath;
            }
            var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
            if (!relativeToBaseUrl) {
                return relativePath;
            }
            var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions);
            var fromPaths = paths && tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
            var nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths;
            if (relativePreference === 1 /* NonRelative */) {
                return nonRelative;
            }
            if (relativePreference !== 2 /* Auto */)
                ts.Debug.assertNever(relativePreference);
            // Prefer a relative import over a baseUrl import if it has fewer components.
            return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative;
        }
        function countPathComponents(path) {
            var count = 0;
            for (var i = ts.startsWith(path, "./") ? 2 : 0; i < path.length; i++) {
                if (path.charCodeAt(i) === 47 /* slash */)
                    count++;
            }
            return count;
        }
        moduleSpecifiers.countPathComponents = countPathComponents;
        function usesJsExtensionOnImports(_a) {
            var imports = _a.imports;
            return ts.firstDefined(imports, function (_a) {
                var text = _a.text;
                return ts.pathIsRelative(text) ? ts.hasJSFileExtension(text) : undefined;
            }) || false;
        }
        function numberOfDirectorySeparators(str) {
            var match = str.match(/\//g);
            return match ? match.length : 0;
        }
        function comparePathsByNumberOfDirectorySeparators(a, b) {
            return ts.compareValues(numberOfDirectorySeparators(a), numberOfDirectorySeparators(b));
        }
        function forEachFileNameOfModule(importingFileName, importedFileName, host, preferSymlinks, cb) {
            var getCanonicalFileName = ts.hostGetCanonicalFileName(host);
            var cwd = host.getCurrentDirectory();
            var referenceRedirect = host.isSourceOfProjectReferenceRedirect(importedFileName) ? host.getProjectReferenceRedirect(importedFileName) : undefined;
            var redirects = host.redirectTargetsMap.get(ts.toPath(importedFileName, cwd, getCanonicalFileName)) || ts.emptyArray;
            var importedFileNames = __spreadArrays((referenceRedirect ? [referenceRedirect] : ts.emptyArray), [importedFileName], redirects);
            var targets = importedFileNames.map(function (f) { return ts.getNormalizedAbsolutePath(f, cwd); });
            if (!preferSymlinks) {
                var result_12 = ts.forEach(targets, cb);
                if (result_12)
                    return result_12;
            }
            var links = host.getProbableSymlinks
                ? host.getProbableSymlinks(host.getSourceFiles())
                : ts.discoverProbableSymlinks(host.getSourceFiles(), getCanonicalFileName, cwd);
            var compareStrings = (!host.useCaseSensitiveFileNames || host.useCaseSensitiveFileNames()) ? ts.compareStringsCaseSensitive : ts.compareStringsCaseInsensitive;
            var result = ts.forEachEntry(links, function (resolved, path) {
                if (ts.startsWithDirectory(importingFileName, resolved, getCanonicalFileName)) {
                    return undefined; // Don't want to a package to globally import from itself
                }
                var target = ts.find(targets, function (t) { return compareStrings(t.slice(0, resolved.length + 1), resolved + "/") === 0 /* EqualTo */; });
                if (target === undefined)
                    return undefined;
                var relative = ts.getRelativePathFromDirectory(resolved, target, getCanonicalFileName);
                var option = ts.resolvePath(path, relative);
                if (!host.fileExists || host.fileExists(option)) {
                    var result_13 = cb(option);
                    if (result_13)
                        return result_13;
                }
            });
            return result ||
                (preferSymlinks ? ts.forEach(targets, cb) : undefined);
        }
        moduleSpecifiers.forEachFileNameOfModule = forEachFileNameOfModule;
        /**
         * Looks for existing imports that use symlinks to this module.
         * Symlinks will be returned first so they are preferred over the real path.
         */
        function getAllModulePaths(importingFileName, importedFileName, host) {
            var cwd = host.getCurrentDirectory();
            var getCanonicalFileName = ts.hostGetCanonicalFileName(host);
            var allFileNames = ts.createMap();
            var importedFileFromNodeModules = false;
            forEachFileNameOfModule(importingFileName, importedFileName, host, 
            /*preferSymlinks*/ true, function (path) {
                // dont return value, so we collect everything
                allFileNames.set(path, getCanonicalFileName(path));
                importedFileFromNodeModules = importedFileFromNodeModules || ts.pathContainsNodeModules(path);
            });
            // Sort by paths closest to importing file Name directory
            var sortedPaths = [];
            var _loop_20 = function (directory) {
                var directoryStart = ts.ensureTrailingDirectorySeparator(directory);
                var pathsInDirectory;
                allFileNames.forEach(function (canonicalFileName, fileName) {
                    if (ts.startsWith(canonicalFileName, directoryStart)) {
                        // If the importedFile is from node modules, use only paths in node_modules folder as option
                        if (!importedFileFromNodeModules || ts.pathContainsNodeModules(fileName)) {
                            (pathsInDirectory || (pathsInDirectory = [])).push(fileName);
                        }
                        allFileNames.delete(fileName);
                    }
                });
                if (pathsInDirectory) {
                    if (pathsInDirectory.length > 1) {
                        pathsInDirectory.sort(comparePathsByNumberOfDirectorySeparators);
                    }
                    sortedPaths.push.apply(sortedPaths, pathsInDirectory);
                }
                var newDirectory = ts.getDirectoryPath(directory);
                if (newDirectory === directory)
                    return out_directory_1 = directory, "break";
                directory = newDirectory;
                out_directory_1 = directory;
            };
            var out_directory_1;
            for (var directory = ts.getDirectoryPath(ts.toPath(importingFileName, cwd, getCanonicalFileName)); allFileNames.size !== 0;) {
                var state_8 = _loop_20(directory);
                directory = out_directory_1;
                if (state_8 === "break")
                    break;
            }
            if (allFileNames.size) {
                var remainingPaths = ts.arrayFrom(allFileNames.values());
                if (remainingPaths.length > 1)
                    remainingPaths.sort(comparePathsByNumberOfDirectorySeparators);
                sortedPaths.push.apply(sortedPaths, remainingPaths);
            }
            return sortedPaths;
        }
        function tryGetModuleNameFromAmbientModule(moduleSymbol) {
            var decl = ts.find(moduleSymbol.declarations, function (d) { return ts.isNonGlobalAmbientModule(d) && (!ts.isExternalModuleAugmentation(d) || !ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(d.name))); });
            if (decl) {
                return decl.name.text;
            }
        }
        function tryGetModuleNameFromPaths(relativeToBaseUrlWithIndex, relativeToBaseUrl, paths) {
            for (var key in paths) {
                for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) {
                    var patternText_1 = _a[_i];
                    var pattern = ts.removeFileExtension(ts.normalizePath(patternText_1));
                    var indexOfStar = pattern.indexOf("*");
                    if (indexOfStar !== -1) {
                        var prefix = pattern.substr(0, indexOfStar);
                        var suffix = pattern.substr(indexOfStar + 1);
                        if (relativeToBaseUrl.length >= prefix.length + suffix.length &&
                            ts.startsWith(relativeToBaseUrl, prefix) &&
                            ts.endsWith(relativeToBaseUrl, suffix) ||
                            !suffix && relativeToBaseUrl === ts.removeTrailingDirectorySeparator(prefix)) {
                            var matchedStar = relativeToBaseUrl.substr(prefix.length, relativeToBaseUrl.length - suffix.length);
                            return key.replace("*", matchedStar);
                        }
                    }
                    else if (pattern === relativeToBaseUrl || pattern === relativeToBaseUrlWithIndex) {
                        return key;
                    }
                }
            }
        }
        function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName, ending, compilerOptions) {
            var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName);
            if (normalizedTargetPath === undefined) {
                return undefined;
            }
            var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName);
            var relativePath = normalizedSourcePath !== undefined ? ts.ensurePathIsNonModuleName(ts.getRelativePathFromDirectory(normalizedSourcePath, normalizedTargetPath, getCanonicalFileName)) : normalizedTargetPath;
            return ts.getEmitModuleResolutionKind(compilerOptions) === ts.ModuleResolutionKind.NodeJs
                ? removeExtensionAndIndexPostFix(relativePath, ending, compilerOptions)
                : ts.removeFileExtension(relativePath);
        }
        function tryGetModuleNameAsNodeModule(moduleFileName, _a, host, options, packageNameOnly) {
            var getCanonicalFileName = _a.getCanonicalFileName, sourceDirectory = _a.sourceDirectory;
            if (!host.fileExists || !host.readFile) {
                return undefined;
            }
            var parts = getNodeModulePathParts(moduleFileName);
            if (!parts) {
                return undefined;
            }
            // Simplify the full file path to something that can be resolved by Node.
            var moduleSpecifier = moduleFileName;
            if (!packageNameOnly) {
                var packageRootIndex = parts.packageRootIndex;
                var moduleFileNameForExtensionless = void 0;
                while (true) {
                    // If the module could be imported by a directory name, use that directory's name
                    var _b = tryDirectoryWithPackageJson(packageRootIndex), moduleFileToTry = _b.moduleFileToTry, packageRootPath = _b.packageRootPath;
                    if (packageRootPath) {
                        moduleSpecifier = packageRootPath;
                        break;
                    }
                    if (!moduleFileNameForExtensionless)
                        moduleFileNameForExtensionless = moduleFileToTry;
                    // try with next level of directory
                    packageRootIndex = moduleFileName.indexOf(ts.directorySeparator, packageRootIndex + 1);
                    if (packageRootIndex === -1) {
                        moduleSpecifier = getExtensionlessFileName(moduleFileNameForExtensionless);
                        break;
                    }
                }
            }
            var globalTypingsCacheLocation = host.getGlobalTypingsCacheLocation && host.getGlobalTypingsCacheLocation();
            // Get a path that's relative to node_modules or the importing file's path
            // if node_modules folder is in this folder or any of its parent folders, no need to keep it.
            var pathToTopLevelNodeModules = getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex));
            if (!(ts.startsWith(sourceDirectory, pathToTopLevelNodeModules) || globalTypingsCacheLocation && ts.startsWith(getCanonicalFileName(globalTypingsCacheLocation), pathToTopLevelNodeModules))) {
                return undefined;
            }
            // If the module was found in @types, get the actual Node package name
            var nodeModulesDirectoryName = moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1);
            var packageName = ts.getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
            // For classic resolution, only allow importing from node_modules/@types, not other node_modules
            return ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs && packageName === nodeModulesDirectoryName ? undefined : packageName;
            function tryDirectoryWithPackageJson(packageRootIndex) {
                var packageRootPath = moduleFileName.substring(0, packageRootIndex);
                var packageJsonPath = ts.combinePaths(packageRootPath, "package.json");
                var moduleFileToTry = moduleFileName;
                if (host.fileExists(packageJsonPath)) {
                    var packageJsonContent = JSON.parse(host.readFile(packageJsonPath));
                    var versionPaths = packageJsonContent.typesVersions
                        ? ts.getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
                        : undefined;
                    if (versionPaths) {
                        var subModuleName = moduleFileName.slice(packageRootPath.length + 1);
                        var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(subModuleName), removeExtensionAndIndexPostFix(subModuleName, 0 /* Minimal */, options), versionPaths.paths);
                        if (fromPaths !== undefined) {
                            moduleFileToTry = ts.combinePaths(packageRootPath, fromPaths);
                        }
                    }
                    // If the file is the main module, it can be imported by the package name
                    var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main;
                    if (ts.isString(mainFileRelative)) {
                        var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName);
                        if (ts.removeFileExtension(mainExportFile) === ts.removeFileExtension(getCanonicalFileName(moduleFileToTry))) {
                            return { packageRootPath: packageRootPath, moduleFileToTry: moduleFileToTry };
                        }
                    }
                }
                return { moduleFileToTry: moduleFileToTry };
            }
            function getExtensionlessFileName(path) {
                // We still have a file name - remove the extension
                var fullModulePathWithoutExtension = ts.removeFileExtension(path);
                // If the file is /index, it can be imported by its directory name
                // IFF there is not _also_ a file by the same name
                if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index" && !tryGetAnyFileFromPath(host, fullModulePathWithoutExtension.substring(0, parts.fileNameIndex))) {
                    return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex);
                }
                return fullModulePathWithoutExtension;
            }
        }
        function tryGetAnyFileFromPath(host, path) {
            if (!host.fileExists)
                return;
            // We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory
            var extensions = ts.getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: 6 /* JSON */ }]);
            for (var _i = 0, extensions_3 = extensions; _i < extensions_3.length; _i++) {
                var e = extensions_3[_i];
                var fullPath = path + e;
                if (host.fileExists(fullPath)) {
                    return fullPath;
                }
            }
        }
        function getNodeModulePathParts(fullPath) {
            // If fullPath can't be valid module file within node_modules, returns undefined.
            // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js
            // Returns indices:                       ^            ^                                                      ^             ^
            var topLevelNodeModulesIndex = 0;
            var topLevelPackageNameIndex = 0;
            var packageRootIndex = 0;
            var fileNameIndex = 0;
            var States;
            (function (States) {
                States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules";
                States[States["NodeModules"] = 1] = "NodeModules";
                States[States["Scope"] = 2] = "Scope";
                States[States["PackageContent"] = 3] = "PackageContent";
            })(States || (States = {}));
            var partStart = 0;
            var partEnd = 0;
            var state = 0 /* BeforeNodeModules */;
            while (partEnd >= 0) {
                partStart = partEnd;
                partEnd = fullPath.indexOf("/", partStart + 1);
                switch (state) {
                    case 0 /* BeforeNodeModules */:
                        if (fullPath.indexOf(ts.nodeModulesPathPart, partStart) === partStart) {
                            topLevelNodeModulesIndex = partStart;
                            topLevelPackageNameIndex = partEnd;
                            state = 1 /* NodeModules */;
                        }
                        break;
                    case 1 /* NodeModules */:
                    case 2 /* Scope */:
                        if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") {
                            state = 2 /* Scope */;
                        }
                        else {
                            packageRootIndex = partEnd;
                            state = 3 /* PackageContent */;
                        }
                        break;
                    case 3 /* PackageContent */:
                        if (fullPath.indexOf(ts.nodeModulesPathPart, partStart) === partStart) {
                            state = 1 /* NodeModules */;
                        }
                        else {
                            state = 3 /* PackageContent */;
                        }
                        break;
                }
            }
            fileNameIndex = partStart;
            return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined;
        }
        function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) {
            return ts.firstDefined(rootDirs, function (rootDir) {
                var relativePath = getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); // TODO: GH#18217
                return isPathRelativeToParent(relativePath) ? undefined : relativePath;
            });
        }
        function removeExtensionAndIndexPostFix(fileName, ending, options) {
            if (ts.fileExtensionIs(fileName, ".json" /* Json */))
                return fileName;
            var noExtension = ts.removeFileExtension(fileName);
            switch (ending) {
                case 0 /* Minimal */:
                    return ts.removeSuffix(noExtension, "/index");
                case 1 /* Index */:
                    return noExtension;
                case 2 /* JsExtension */:
                    return noExtension + getJSExtensionForFile(fileName, options);
                default:
                    return ts.Debug.assertNever(ending);
            }
        }
        function getJSExtensionForFile(fileName, options) {
            var ext = ts.extensionFromPath(fileName);
            switch (ext) {
                case ".ts" /* Ts */:
                case ".d.ts" /* Dts */:
                    return ".js" /* Js */;
                case ".tsx" /* Tsx */:
                    return options.jsx === 1 /* Preserve */ ? ".jsx" /* Jsx */ : ".js" /* Js */;
                case ".js" /* Js */:
                case ".jsx" /* Jsx */:
                case ".json" /* Json */:
                    return ext;
                case ".tsbuildinfo" /* TsBuildInfo */:
                    return ts.Debug.fail("Extension " + ".tsbuildinfo" /* TsBuildInfo */ + " is unsupported:: FileName:: " + fileName);
                default:
                    return ts.Debug.assertNever(ext);
            }
        }
        function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) {
            var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
            return ts.isRootedDiskPath(relativePath) ? undefined : relativePath;
        }
        function isPathRelativeToParent(path) {
            return ts.startsWith(path, "..");
        }
    })(moduleSpecifiers = ts.moduleSpecifiers || (ts.moduleSpecifiers = {}));
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var sysFormatDiagnosticsHost = ts.sys ? {
        getCurrentDirectory: function () { return ts.sys.getCurrentDirectory(); },
        getNewLine: function () { return ts.sys.newLine; },
        getCanonicalFileName: ts.createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames)
    } : undefined; // TODO: GH#18217
    /**
     * Create a function that reports error by writing to the system and handles the formating of the diagnostic
     */
    function createDiagnosticReporter(system, pretty) {
        var host = system === ts.sys ? sysFormatDiagnosticsHost : {
            getCurrentDirectory: function () { return system.getCurrentDirectory(); },
            getNewLine: function () { return system.newLine; },
            getCanonicalFileName: ts.createGetCanonicalFileName(system.useCaseSensitiveFileNames),
        };
        if (!pretty) {
            return function (diagnostic) { return system.write(ts.formatDiagnostic(diagnostic, host)); };
        }
        var diagnostics = new Array(1);
        return function (diagnostic) {
            diagnostics[0] = diagnostic;
            system.write(ts.formatDiagnosticsWithColorAndContext(diagnostics, host) + host.getNewLine());
            diagnostics[0] = undefined; // TODO: GH#18217
        };
    }
    ts.createDiagnosticReporter = createDiagnosticReporter;
    /**
     * @returns Whether the screen was cleared.
     */
    function clearScreenIfNotWatchingForFileChanges(system, diagnostic, options) {
        if (system.clearScreen &&
            !options.preserveWatchOutput &&
            !options.extendedDiagnostics &&
            !options.diagnostics &&
            ts.contains(ts.screenStartingMessageCodes, diagnostic.code)) {
            system.clearScreen();
            return true;
        }
        return false;
    }
    ts.screenStartingMessageCodes = [
        ts.Diagnostics.Starting_compilation_in_watch_mode.code,
        ts.Diagnostics.File_change_detected_Starting_incremental_compilation.code,
    ];
    function getPlainDiagnosticFollowingNewLines(diagnostic, newLine) {
        return ts.contains(ts.screenStartingMessageCodes, diagnostic.code)
            ? newLine + newLine
            : newLine;
    }
    /**
     * Get locale specific time based on whether we are in test mode
     */
    function getLocaleTimeString(system) {
        return !system.now ?
            new Date().toLocaleTimeString() :
            system.now().toLocaleTimeString("en-US", { timeZone: "UTC" });
    }
    ts.getLocaleTimeString = getLocaleTimeString;
    /**
     * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
     */
    function createWatchStatusReporter(system, pretty) {
        return pretty ?
            function (diagnostic, newLine, options) {
                clearScreenIfNotWatchingForFileChanges(system, diagnostic, options);
                var output = "[" + ts.formatColorAndReset(getLocaleTimeString(system), ts.ForegroundColorEscapeSequences.Grey) + "] ";
                output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + (newLine + newLine);
                system.write(output);
            } :
            function (diagnostic, newLine, options) {
                var output = "";
                if (!clearScreenIfNotWatchingForFileChanges(system, diagnostic, options)) {
                    output += newLine;
                }
                output += getLocaleTimeString(system) + " - ";
                output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + getPlainDiagnosticFollowingNewLines(diagnostic, newLine);
                system.write(output);
            };
    }
    ts.createWatchStatusReporter = createWatchStatusReporter;
    /** Parses config file using System interface */
    function parseConfigFileWithSystem(configFileName, optionsToExtend, watchOptionsToExtend, system, reportDiagnostic) {
        var host = system;
        host.onUnRecoverableConfigFileDiagnostic = function (diagnostic) { return reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic); };
        var result = ts.getParsedCommandLineOfConfigFile(configFileName, optionsToExtend, host, /*extendedConfigCache*/ undefined, watchOptionsToExtend);
        host.onUnRecoverableConfigFileDiagnostic = undefined; // TODO: GH#18217
        return result;
    }
    ts.parseConfigFileWithSystem = parseConfigFileWithSystem;
    function getErrorCountForSummary(diagnostics) {
        return ts.countWhere(diagnostics, function (diagnostic) { return diagnostic.category === ts.DiagnosticCategory.Error; });
    }
    ts.getErrorCountForSummary = getErrorCountForSummary;
    function getWatchErrorSummaryDiagnosticMessage(errorCount) {
        return errorCount === 1 ?
            ts.Diagnostics.Found_1_error_Watching_for_file_changes :
            ts.Diagnostics.Found_0_errors_Watching_for_file_changes;
    }
    ts.getWatchErrorSummaryDiagnosticMessage = getWatchErrorSummaryDiagnosticMessage;
    function getErrorSummaryText(errorCount, newLine) {
        if (errorCount === 0)
            return "";
        var d = ts.createCompilerDiagnostic(errorCount === 1 ? ts.Diagnostics.Found_1_error : ts.Diagnostics.Found_0_errors, errorCount);
        return "" + newLine + ts.flattenDiagnosticMessageText(d.messageText, newLine) + newLine + newLine;
    }
    ts.getErrorSummaryText = getErrorSummaryText;
    function listFiles(program, writeFileName) {
        if (program.getCompilerOptions().listFiles || program.getCompilerOptions().listFilesOnly) {
            ts.forEach(program.getSourceFiles(), function (file) {
                writeFileName(file.fileName);
            });
        }
    }
    ts.listFiles = listFiles;
    /**
     * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
     */
    function emitFilesAndReportErrors(program, reportDiagnostic, writeFileName, reportSummary, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
        var isListFilesOnly = !!program.getCompilerOptions().listFilesOnly;
        // First get and report any syntactic errors.
        var allDiagnostics = program.getConfigFileParsingDiagnostics().slice();
        var configFileParsingDiagnosticsLength = allDiagnostics.length;
        ts.addRange(allDiagnostics, program.getSyntacticDiagnostics(/*sourceFile*/ undefined, cancellationToken));
        // If we didn't have any syntactic errors, then also try getting the global and
        // semantic errors.
        if (allDiagnostics.length === configFileParsingDiagnosticsLength) {
            ts.addRange(allDiagnostics, program.getOptionsDiagnostics(cancellationToken));
            if (!isListFilesOnly) {
                ts.addRange(allDiagnostics, program.getGlobalDiagnostics(cancellationToken));
                if (allDiagnostics.length === configFileParsingDiagnosticsLength) {
                    ts.addRange(allDiagnostics, program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken));
                }
            }
        }
        // Emit and report any errors we ran into.
        var emitResult = isListFilesOnly
            ? { emitSkipped: true, diagnostics: ts.emptyArray }
            : program.emit(/*targetSourceFile*/ undefined, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
        var emittedFiles = emitResult.emittedFiles, emitDiagnostics = emitResult.diagnostics;
        ts.addRange(allDiagnostics, emitDiagnostics);
        var diagnostics = ts.sortAndDeduplicateDiagnostics(allDiagnostics);
        diagnostics.forEach(reportDiagnostic);
        if (writeFileName) {
            var currentDir_1 = program.getCurrentDirectory();
            ts.forEach(emittedFiles, function (file) {
                var filepath = ts.getNormalizedAbsolutePath(file, currentDir_1);
                writeFileName("TSFILE: " + filepath);
            });
            listFiles(program, writeFileName);
        }
        if (reportSummary) {
            reportSummary(getErrorCountForSummary(diagnostics));
        }
        return {
            emitResult: emitResult,
            diagnostics: diagnostics,
        };
    }
    ts.emitFilesAndReportErrors = emitFilesAndReportErrors;
    function emitFilesAndReportErrorsAndGetExitStatus(program, reportDiagnostic, writeFileName, reportSummary, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
        var _a = emitFilesAndReportErrors(program, reportDiagnostic, writeFileName, reportSummary, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers), emitResult = _a.emitResult, diagnostics = _a.diagnostics;
        if (emitResult.emitSkipped && diagnostics.length > 0) {
            // If the emitter didn't emit anything, then pass that value along.
            return ts.ExitStatus.DiagnosticsPresent_OutputsSkipped;
        }
        else if (diagnostics.length > 0) {
            // The emitter emitted something, inform the caller if that happened in the presence
            // of diagnostics or not.
            return ts.ExitStatus.DiagnosticsPresent_OutputsGenerated;
        }
        return ts.ExitStatus.Success;
    }
    ts.emitFilesAndReportErrorsAndGetExitStatus = emitFilesAndReportErrorsAndGetExitStatus;
    ts.noopFileWatcher = { close: ts.noop };
    function createWatchHost(system, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system);
        return {
            onWatchStatusChange: onWatchStatusChange,
            watchFile: ts.maybeBind(system, system.watchFile) || (function () { return ts.noopFileWatcher; }),
            watchDirectory: ts.maybeBind(system, system.watchDirectory) || (function () { return ts.noopFileWatcher; }),
            setTimeout: ts.maybeBind(system, system.setTimeout) || ts.noop,
            clearTimeout: ts.maybeBind(system, system.clearTimeout) || ts.noop
        };
    }
    ts.createWatchHost = createWatchHost;
    ts.WatchType = {
        ConfigFile: "Config file",
        SourceFile: "Source file",
        MissingFile: "Missing file",
        WildcardDirectory: "Wild card directory",
        FailedLookupLocations: "Failed Lookup Locations",
        TypeRoots: "Type roots"
    };
    function createWatchFactory(host, options) {
        var watchLogLevel = host.trace ? options.extendedDiagnostics ? ts.WatchLogLevel.Verbose : options.diagnostics ? ts.WatchLogLevel.TriggerOnly : ts.WatchLogLevel.None : ts.WatchLogLevel.None;
        var writeLog = watchLogLevel !== ts.WatchLogLevel.None ? (function (s) { return host.trace(s); }) : ts.noop;
        var result = ts.getWatchFactory(watchLogLevel, writeLog);
        result.writeLog = writeLog;
        return result;
    }
    ts.createWatchFactory = createWatchFactory;
    function createCompilerHostFromProgramHost(host, getCompilerOptions, directoryStructureHost) {
        if (directoryStructureHost === void 0) { directoryStructureHost = host; }
        var useCaseSensitiveFileNames = host.useCaseSensitiveFileNames();
        var hostGetNewLine = ts.memoize(function () { return host.getNewLine(); });
        return {
            getSourceFile: function (fileName, languageVersion, onError) {
                var text;
                try {
                    ts.performance.mark("beforeIORead");
                    text = host.readFile(fileName, getCompilerOptions().charset);
                    ts.performance.mark("afterIORead");
                    ts.performance.measure("I/O Read", "beforeIORead", "afterIORead");
                }
                catch (e) {
                    if (onError) {
                        onError(e.message);
                    }
                    text = "";
                }
                return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion) : undefined;
            },
            getDefaultLibLocation: ts.maybeBind(host, host.getDefaultLibLocation),
            getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); },
            writeFile: writeFile,
            getCurrentDirectory: ts.memoize(function () { return host.getCurrentDirectory(); }),
            useCaseSensitiveFileNames: function () { return useCaseSensitiveFileNames; },
            getCanonicalFileName: ts.createGetCanonicalFileName(useCaseSensitiveFileNames),
            getNewLine: function () { return ts.getNewLineCharacter(getCompilerOptions(), hostGetNewLine); },
            fileExists: function (f) { return host.fileExists(f); },
            readFile: function (f) { return host.readFile(f); },
            trace: ts.maybeBind(host, host.trace),
            directoryExists: ts.maybeBind(directoryStructureHost, directoryStructureHost.directoryExists),
            getDirectories: ts.maybeBind(directoryStructureHost, directoryStructureHost.getDirectories),
            realpath: ts.maybeBind(host, host.realpath),
            getEnvironmentVariable: ts.maybeBind(host, host.getEnvironmentVariable) || (function () { return ""; }),
            createHash: ts.maybeBind(host, host.createHash),
            readDirectory: ts.maybeBind(host, host.readDirectory),
        };
        function writeFile(fileName, text, writeByteOrderMark, onError) {
            try {
                ts.performance.mark("beforeIOWrite");
                // NOTE: If patchWriteFileEnsuringDirectory has been called,
                // the host.writeFile will do its own directory creation and
                // the ensureDirectoriesExist call will always be redundant.
                ts.writeFileEnsuringDirectories(fileName, text, writeByteOrderMark, function (path, data, writeByteOrderMark) { return host.writeFile(path, data, writeByteOrderMark); }, function (path) { return host.createDirectory(path); }, function (path) { return host.directoryExists(path); });
                ts.performance.mark("afterIOWrite");
                ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
            }
            catch (e) {
                if (onError) {
                    onError(e.message);
                }
            }
        }
    }
    ts.createCompilerHostFromProgramHost = createCompilerHostFromProgramHost;
    function setGetSourceFileAsHashVersioned(compilerHost, host) {
        var originalGetSourceFile = compilerHost.getSourceFile;
        var computeHash = host.createHash || ts.generateDjb2Hash;
        compilerHost.getSourceFile = function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            var result = originalGetSourceFile.call.apply(originalGetSourceFile, __spreadArrays([compilerHost], args));
            if (result) {
                result.version = computeHash.call(host, result.text);
            }
            return result;
        };
    }
    ts.setGetSourceFileAsHashVersioned = setGetSourceFileAsHashVersioned;
    /**
     * Creates the watch compiler host that can be extended with config file or root file names and options host
     */
    function createProgramHost(system, createProgram) {
        var getDefaultLibLocation = ts.memoize(function () { return ts.getDirectoryPath(ts.normalizePath(system.getExecutingFilePath())); });
        return {
            useCaseSensitiveFileNames: function () { return system.useCaseSensitiveFileNames; },
            getNewLine: function () { return system.newLine; },
            getCurrentDirectory: ts.memoize(function () { return system.getCurrentDirectory(); }),
            getDefaultLibLocation: getDefaultLibLocation,
            getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); },
            fileExists: function (path) { return system.fileExists(path); },
            readFile: function (path, encoding) { return system.readFile(path, encoding); },
            directoryExists: function (path) { return system.directoryExists(path); },
            getDirectories: function (path) { return system.getDirectories(path); },
            readDirectory: function (path, extensions, exclude, include, depth) { return system.readDirectory(path, extensions, exclude, include, depth); },
            realpath: ts.maybeBind(system, system.realpath),
            getEnvironmentVariable: ts.maybeBind(system, system.getEnvironmentVariable),
            trace: function (s) { return system.write(s + system.newLine); },
            createDirectory: function (path) { return system.createDirectory(path); },
            writeFile: function (path, data, writeByteOrderMark) { return system.writeFile(path, data, writeByteOrderMark); },
            createHash: ts.maybeBind(system, system.createHash),
            createProgram: createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram
        };
    }
    ts.createProgramHost = createProgramHost;
    /**
     * Creates the watch compiler host that can be extended with config file or root file names and options host
     */
    function createWatchCompilerHost(system, createProgram, reportDiagnostic, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var writeFileName = function (s) { return system.write(s + system.newLine); };
        var result = createProgramHost(system, createProgram);
        ts.copyProperties(result, createWatchHost(system, reportWatchStatus));
        result.afterProgramCreate = function (builderProgram) {
            var compilerOptions = builderProgram.getCompilerOptions();
            var newLine = ts.getNewLineCharacter(compilerOptions, function () { return system.newLine; });
            emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName, function (errorCount) { return result.onWatchStatusChange(ts.createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(errorCount), errorCount), newLine, compilerOptions, errorCount); });
        };
        return result;
    }
    /**
     * Report error and exit
     */
    function reportUnrecoverableDiagnostic(system, reportDiagnostic, diagnostic) {
        reportDiagnostic(diagnostic);
        system.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped);
    }
    /**
     * Creates the watch compiler host from system for config file in watch mode
     */
    function createWatchCompilerHostOfConfigFile(_a) {
        var configFileName = _a.configFileName, optionsToExtend = _a.optionsToExtend, watchOptionsToExtend = _a.watchOptionsToExtend, extraFileExtensions = _a.extraFileExtensions, system = _a.system, createProgram = _a.createProgram, reportDiagnostic = _a.reportDiagnostic, reportWatchStatus = _a.reportWatchStatus;
        var diagnosticReporter = reportDiagnostic || createDiagnosticReporter(system);
        var host = createWatchCompilerHost(system, createProgram, diagnosticReporter, reportWatchStatus);
        host.onUnRecoverableConfigFileDiagnostic = function (diagnostic) { return reportUnrecoverableDiagnostic(system, diagnosticReporter, diagnostic); };
        host.configFileName = configFileName;
        host.optionsToExtend = optionsToExtend;
        host.watchOptionsToExtend = watchOptionsToExtend;
        host.extraFileExtensions = extraFileExtensions;
        return host;
    }
    ts.createWatchCompilerHostOfConfigFile = createWatchCompilerHostOfConfigFile;
    /**
     * Creates the watch compiler host from system for compiling root files and options in watch mode
     */
    function createWatchCompilerHostOfFilesAndCompilerOptions(_a) {
        var rootFiles = _a.rootFiles, options = _a.options, watchOptions = _a.watchOptions, projectReferences = _a.projectReferences, system = _a.system, createProgram = _a.createProgram, reportDiagnostic = _a.reportDiagnostic, reportWatchStatus = _a.reportWatchStatus;
        var host = createWatchCompilerHost(system, createProgram, reportDiagnostic || createDiagnosticReporter(system), reportWatchStatus);
        host.rootFiles = rootFiles;
        host.options = options;
        host.watchOptions = watchOptions;
        host.projectReferences = projectReferences;
        return host;
    }
    ts.createWatchCompilerHostOfFilesAndCompilerOptions = createWatchCompilerHostOfFilesAndCompilerOptions;
    function performIncrementalCompilation(input) {
        var system = input.system || ts.sys;
        var host = input.host || (input.host = ts.createIncrementalCompilerHost(input.options, system));
        var builderProgram = ts.createIncrementalProgram(input);
        var exitStatus = emitFilesAndReportErrorsAndGetExitStatus(builderProgram, input.reportDiagnostic || createDiagnosticReporter(system), function (s) { return host.trace && host.trace(s); }, input.reportErrorSummary || input.options.pretty ? function (errorCount) { return system.write(getErrorSummaryText(errorCount, system.newLine)); } : undefined);
        if (input.afterProgramEmitAndDiagnostics)
            input.afterProgramEmitAndDiagnostics(builderProgram);
        return exitStatus;
    }
    ts.performIncrementalCompilation = performIncrementalCompilation;
})(ts || (ts = {}));
var ts;
(function (ts) {
    function readBuilderProgram(compilerOptions, host) {
        if (compilerOptions.out || compilerOptions.outFile)
            return undefined;
        var buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(compilerOptions);
        if (!buildInfoPath)
            return undefined;
        var content = host.readFile(buildInfoPath);
        if (!content)
            return undefined;
        var buildInfo = ts.getBuildInfo(content);
        if (buildInfo.version !== ts.version)
            return undefined;
        if (!buildInfo.program)
            return undefined;
        return ts.createBuildProgramUsingProgramBuildInfo(buildInfo.program, buildInfoPath, host);
    }
    ts.readBuilderProgram = readBuilderProgram;
    function createIncrementalCompilerHost(options, system) {
        if (system === void 0) { system = ts.sys; }
        var host = ts.createCompilerHostWorker(options, /*setParentNodes*/ undefined, system);
        host.createHash = ts.maybeBind(system, system.createHash);
        ts.setGetSourceFileAsHashVersioned(host, system);
        ts.changeCompilerHostLikeToUseCache(host, function (fileName) { return ts.toPath(fileName, host.getCurrentDirectory(), host.getCanonicalFileName); });
        return host;
    }
    ts.createIncrementalCompilerHost = createIncrementalCompilerHost;
    function createIncrementalProgram(_a) {
        var rootNames = _a.rootNames, options = _a.options, configFileParsingDiagnostics = _a.configFileParsingDiagnostics, projectReferences = _a.projectReferences, host = _a.host, createProgram = _a.createProgram;
        host = host || createIncrementalCompilerHost(options);
        createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram;
        var oldProgram = readBuilderProgram(options, host);
        return createProgram(rootNames, options, host, oldProgram, configFileParsingDiagnostics, projectReferences);
    }
    ts.createIncrementalProgram = createIncrementalProgram;
    function createWatchCompilerHost(rootFilesOrConfigFileName, options, system, createProgram, reportDiagnostic, reportWatchStatus, projectReferencesOrWatchOptionsToExtend, watchOptionsOrExtraFileExtensions) {
        if (ts.isArray(rootFilesOrConfigFileName)) {
            return ts.createWatchCompilerHostOfFilesAndCompilerOptions({
                rootFiles: rootFilesOrConfigFileName,
                options: options,
                watchOptions: watchOptionsOrExtraFileExtensions,
                projectReferences: projectReferencesOrWatchOptionsToExtend,
                system: system,
                createProgram: createProgram,
                reportDiagnostic: reportDiagnostic,
                reportWatchStatus: reportWatchStatus,
            });
        }
        else {
            return ts.createWatchCompilerHostOfConfigFile({
                configFileName: rootFilesOrConfigFileName,
                optionsToExtend: options,
                watchOptionsToExtend: projectReferencesOrWatchOptionsToExtend,
                extraFileExtensions: watchOptionsOrExtraFileExtensions,
                system: system,
                createProgram: createProgram,
                reportDiagnostic: reportDiagnostic,
                reportWatchStatus: reportWatchStatus,
            });
        }
    }
    ts.createWatchCompilerHost = createWatchCompilerHost;
    function createWatchProgram(host) {
        var builderProgram;
        var reloadLevel; // level to indicate if the program needs to be reloaded from config file/just filenames etc
        var missingFilesMap; // Map of file watchers for the missing files
        var watchedWildcardDirectories; // map of watchers for the wild card directories in the config file
        var timerToUpdateProgram; // timer callback to recompile the program
        var sourceFilesCache = ts.createMap(); // Cache that stores the source file and version info
        var missingFilePathsRequestedForRelease; // These paths are held temparirly so that we can remove the entry from source file cache if the file is not tracked by missing files
        var hasChangedCompilerOptions = false; // True if the compiler options have changed between compilations
        var hasChangedAutomaticTypeDirectiveNames = false; // True if the automatic type directives have changed
        var useCaseSensitiveFileNames = host.useCaseSensitiveFileNames();
        var currentDirectory = host.getCurrentDirectory();
        var configFileName = host.configFileName, _a = host.optionsToExtend, optionsToExtendForConfigFile = _a === void 0 ? {} : _a, watchOptionsToExtend = host.watchOptionsToExtend, extraFileExtensions = host.extraFileExtensions, createProgram = host.createProgram;
        var rootFileNames = host.rootFiles, compilerOptions = host.options, watchOptions = host.watchOptions, projectReferences = host.projectReferences;
        var configFileSpecs;
        var configFileParsingDiagnostics;
        var canConfigFileJsonReportNoInputFiles = false;
        var hasChangedConfigFileParsingErrors = false;
        var cachedDirectoryStructureHost = configFileName === undefined ? undefined : ts.createCachedDirectoryStructureHost(host, currentDirectory, useCaseSensitiveFileNames);
        var directoryStructureHost = cachedDirectoryStructureHost || host;
        var parseConfigFileHost = ts.parseConfigHostFromCompilerHostLike(host, directoryStructureHost);
        // From tsc we want to get already parsed result and hence check for rootFileNames
        var newLine = updateNewLine();
        if (configFileName && host.configFileParsingResult) {
            setConfigFileParsingResult(host.configFileParsingResult);
            newLine = updateNewLine();
        }
        reportWatchDiagnostic(ts.Diagnostics.Starting_compilation_in_watch_mode);
        if (configFileName && !host.configFileParsingResult) {
            newLine = ts.getNewLineCharacter(optionsToExtendForConfigFile, function () { return host.getNewLine(); });
            ts.Debug.assert(!rootFileNames);
            parseConfigFile();
            newLine = updateNewLine();
        }
        var _b = ts.createWatchFactory(host, compilerOptions), watchFile = _b.watchFile, watchFilePath = _b.watchFilePath, watchDirectory = _b.watchDirectory, writeLog = _b.writeLog;
        var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
        writeLog("Current directory: " + currentDirectory + " CaseSensitiveFileNames: " + useCaseSensitiveFileNames);
        var configFileWatcher;
        if (configFileName) {
            configFileWatcher = watchFile(host, configFileName, scheduleProgramReload, ts.PollingInterval.High, watchOptions, ts.WatchType.ConfigFile);
        }
        var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return compilerOptions; }, directoryStructureHost);
        ts.setGetSourceFileAsHashVersioned(compilerHost, host);
        // Members for CompilerHost
        var getNewSourceFile = compilerHost.getSourceFile;
        compilerHost.getSourceFile = function (fileName) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            return getVersionedSourceFileByPath.apply(void 0, __spreadArrays([fileName, toPath(fileName)], args));
        };
        compilerHost.getSourceFileByPath = getVersionedSourceFileByPath;
        compilerHost.getNewLine = function () { return newLine; };
        compilerHost.fileExists = fileExists;
        compilerHost.onReleaseOldSourceFile = onReleaseOldSourceFile;
        // Members for ResolutionCacheHost
        compilerHost.toPath = toPath;
        compilerHost.getCompilationSettings = function () { return compilerOptions; };
        compilerHost.useSourceOfProjectReferenceRedirect = ts.maybeBind(host, host.useSourceOfProjectReferenceRedirect);
        compilerHost.watchDirectoryOfFailedLookupLocation = function (dir, cb, flags) { return watchDirectory(host, dir, cb, flags, watchOptions, ts.WatchType.FailedLookupLocations); };
        compilerHost.watchTypeRootsDirectory = function (dir, cb, flags) { return watchDirectory(host, dir, cb, flags, watchOptions, ts.WatchType.TypeRoots); };
        compilerHost.getCachedDirectoryStructureHost = function () { return cachedDirectoryStructureHost; };
        compilerHost.onInvalidatedResolution = scheduleProgramUpdate;
        compilerHost.onChangedAutomaticTypeDirectiveNames = function () {
            hasChangedAutomaticTypeDirectiveNames = true;
            scheduleProgramUpdate();
        };
        compilerHost.fileIsOpen = ts.returnFalse;
        compilerHost.getCurrentProgram = getCurrentProgram;
        compilerHost.writeLog = writeLog;
        // Cache for the module resolution
        var resolutionCache = ts.createResolutionCache(compilerHost, configFileName ?
            ts.getDirectoryPath(ts.getNormalizedAbsolutePath(configFileName, currentDirectory)) :
            currentDirectory, 
        /*logChangesWhenResolvingModule*/ false);
        // Resolve module using host module resolution strategy if provided otherwise use resolution cache to resolve module names
        compilerHost.resolveModuleNames = host.resolveModuleNames ?
            (function () {
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                return host.resolveModuleNames.apply(host, args);
            }) :
            (function (moduleNames, containingFile, reusedNames, redirectedReference) { return resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference); });
        compilerHost.resolveTypeReferenceDirectives = host.resolveTypeReferenceDirectives ?
            (function () {
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                return host.resolveTypeReferenceDirectives.apply(host, args);
            }) :
            (function (typeDirectiveNames, containingFile, redirectedReference) { return resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference); });
        var userProvidedResolution = !!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
        builderProgram = readBuilderProgram(compilerOptions, compilerHost);
        synchronizeProgram();
        // Update the wild card directory watch
        watchConfigFileWildCardDirectories();
        return configFileName ?
            { getCurrentProgram: getCurrentBuilderProgram, getProgram: updateProgram, close: close } :
            { getCurrentProgram: getCurrentBuilderProgram, getProgram: updateProgram, updateRootFileNames: updateRootFileNames, close: close };
        function close() {
            resolutionCache.clear();
            ts.clearMap(sourceFilesCache, function (value) {
                if (value && value.fileWatcher) {
                    value.fileWatcher.close();
                    value.fileWatcher = undefined;
                }
            });
            if (configFileWatcher) {
                configFileWatcher.close();
                configFileWatcher = undefined;
            }
            if (watchedWildcardDirectories) {
                ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcherOf);
                watchedWildcardDirectories = undefined;
            }
            if (missingFilesMap) {
                ts.clearMap(missingFilesMap, ts.closeFileWatcher);
                missingFilesMap = undefined;
            }
        }
        function getCurrentBuilderProgram() {
            return builderProgram;
        }
        function getCurrentProgram() {
            return builderProgram && builderProgram.getProgramOrUndefined();
        }
        function synchronizeProgram() {
            writeLog("Synchronizing program");
            var program = getCurrentBuilderProgram();
            if (hasChangedCompilerOptions) {
                newLine = updateNewLine();
                if (program && ts.changesAffectModuleResolution(program.getCompilerOptions(), compilerOptions)) {
                    resolutionCache.clear();
                }
            }
            // All resolutions are invalid if user provided resolutions
            var hasInvalidatedResolution = resolutionCache.createHasInvalidatedResolution(userProvidedResolution);
            if (ts.isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames, projectReferences)) {
                if (hasChangedConfigFileParsingErrors) {
                    builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
                    hasChangedConfigFileParsingErrors = false;
                }
            }
            else {
                createNewProgram(hasInvalidatedResolution);
            }
            if (host.afterProgramCreate && program !== builderProgram) {
                host.afterProgramCreate(builderProgram);
            }
            return builderProgram;
        }
        function createNewProgram(hasInvalidatedResolution) {
            // Compile the program
            writeLog("CreatingProgramWith::");
            writeLog("  roots: " + JSON.stringify(rootFileNames));
            writeLog("  options: " + JSON.stringify(compilerOptions));
            var needsUpdateInTypeRootWatch = hasChangedCompilerOptions || !getCurrentProgram();
            hasChangedCompilerOptions = false;
            hasChangedConfigFileParsingErrors = false;
            resolutionCache.startCachingPerDirectoryResolution();
            compilerHost.hasInvalidatedResolution = hasInvalidatedResolution;
            compilerHost.hasChangedAutomaticTypeDirectiveNames = hasChangedAutomaticTypeDirectiveNames;
            hasChangedAutomaticTypeDirectiveNames = false;
            builderProgram = createProgram(rootFileNames, compilerOptions, compilerHost, builderProgram, configFileParsingDiagnostics, projectReferences);
            resolutionCache.finishCachingPerDirectoryResolution();
            // Update watches
            ts.updateMissingFilePathsWatch(builderProgram.getProgram(), missingFilesMap || (missingFilesMap = ts.createMap()), watchMissingFilePath);
            if (needsUpdateInTypeRootWatch) {
                resolutionCache.updateTypeRootsWatch();
            }
            if (missingFilePathsRequestedForRelease) {
                // These are the paths that program creater told us as not in use any more but were missing on the disk.
                // We didnt remove the entry for them from sourceFiles cache so that we dont have to do File IO,
                // if there is already watcher for it (for missing files)
                // At this point our watches were updated, hence now we know that these paths are not tracked and need to be removed
                // so that at later time we have correct result of their presence
                for (var _i = 0, missingFilePathsRequestedForRelease_1 = missingFilePathsRequestedForRelease; _i < missingFilePathsRequestedForRelease_1.length; _i++) {
                    var missingFilePath = missingFilePathsRequestedForRelease_1[_i];
                    if (!missingFilesMap.has(missingFilePath)) {
                        sourceFilesCache.delete(missingFilePath);
                    }
                }
                missingFilePathsRequestedForRelease = undefined;
            }
        }
        function updateRootFileNames(files) {
            ts.Debug.assert(!configFileName, "Cannot update root file names with config file watch mode");
            rootFileNames = files;
            scheduleProgramUpdate();
        }
        function updateNewLine() {
            return ts.getNewLineCharacter(compilerOptions || optionsToExtendForConfigFile, function () { return host.getNewLine(); });
        }
        function toPath(fileName) {
            return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
        }
        function isFileMissingOnHost(hostSourceFile) {
            return typeof hostSourceFile === "boolean";
        }
        function isFilePresenceUnknownOnHost(hostSourceFile) {
            return typeof hostSourceFile.version === "boolean";
        }
        function fileExists(fileName) {
            var path = toPath(fileName);
            // If file is missing on host from cache, we can definitely say file doesnt exist
            // otherwise we need to ensure from the disk
            if (isFileMissingOnHost(sourceFilesCache.get(path))) {
                return false;
            }
            return directoryStructureHost.fileExists(fileName);
        }
        function getVersionedSourceFileByPath(fileName, path, languageVersion, onError, shouldCreateNewSourceFile) {
            var hostSourceFile = sourceFilesCache.get(path);
            // No source file on the host
            if (isFileMissingOnHost(hostSourceFile)) {
                return undefined;
            }
            // Create new source file if requested or the versions dont match
            if (hostSourceFile === undefined || shouldCreateNewSourceFile || isFilePresenceUnknownOnHost(hostSourceFile)) {
                var sourceFile = getNewSourceFile(fileName, languageVersion, onError);
                if (hostSourceFile) {
                    if (sourceFile) {
                        // Set the source file and create file watcher now that file was present on the disk
                        hostSourceFile.sourceFile = sourceFile;
                        hostSourceFile.version = sourceFile.version;
                        if (!hostSourceFile.fileWatcher) {
                            hostSourceFile.fileWatcher = watchFilePath(host, fileName, onSourceFileChange, ts.PollingInterval.Low, watchOptions, path, ts.WatchType.SourceFile);
                        }
                    }
                    else {
                        // There is no source file on host any more, close the watch, missing file paths will track it
                        if (hostSourceFile.fileWatcher) {
                            hostSourceFile.fileWatcher.close();
                        }
                        sourceFilesCache.set(path, false);
                    }
                }
                else {
                    if (sourceFile) {
                        var fileWatcher = watchFilePath(host, fileName, onSourceFileChange, ts.PollingInterval.Low, watchOptions, path, ts.WatchType.SourceFile);
                        sourceFilesCache.set(path, { sourceFile: sourceFile, version: sourceFile.version, fileWatcher: fileWatcher });
                    }
                    else {
                        sourceFilesCache.set(path, false);
                    }
                }
                return sourceFile;
            }
            return hostSourceFile.sourceFile;
        }
        function nextSourceFileVersion(path) {
            var hostSourceFile = sourceFilesCache.get(path);
            if (hostSourceFile !== undefined) {
                if (isFileMissingOnHost(hostSourceFile)) {
                    // The next version, lets set it as presence unknown file
                    sourceFilesCache.set(path, { version: false });
                }
                else {
                    hostSourceFile.version = false;
                }
            }
        }
        function getSourceVersion(path) {
            var hostSourceFile = sourceFilesCache.get(path);
            return !hostSourceFile || !hostSourceFile.version ? undefined : hostSourceFile.version;
        }
        function onReleaseOldSourceFile(oldSourceFile, _oldOptions, hasSourceFileByPath) {
            var hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.resolvedPath);
            // If this is the source file thats in the cache and new program doesnt need it,
            // remove the cached entry.
            // Note we arent deleting entry if file became missing in new program or
            // there was version update and new source file was created.
            if (hostSourceFileInfo !== undefined) {
                // record the missing file paths so they can be removed later if watchers arent tracking them
                if (isFileMissingOnHost(hostSourceFileInfo)) {
                    (missingFilePathsRequestedForRelease || (missingFilePathsRequestedForRelease = [])).push(oldSourceFile.path);
                }
                else if (hostSourceFileInfo.sourceFile === oldSourceFile) {
                    if (hostSourceFileInfo.fileWatcher) {
                        hostSourceFileInfo.fileWatcher.close();
                    }
                    sourceFilesCache.delete(oldSourceFile.resolvedPath);
                    if (!hasSourceFileByPath) {
                        resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
                    }
                }
            }
        }
        function reportWatchDiagnostic(message) {
            if (host.onWatchStatusChange) {
                host.onWatchStatusChange(ts.createCompilerDiagnostic(message), newLine, compilerOptions || optionsToExtendForConfigFile);
            }
        }
        // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch
        // operations (such as saving all modified files in an editor) a chance to complete before we kick
        // off a new compilation.
        function scheduleProgramUpdate() {
            if (!host.setTimeout || !host.clearTimeout) {
                return;
            }
            if (timerToUpdateProgram) {
                host.clearTimeout(timerToUpdateProgram);
            }
            writeLog("Scheduling update");
            timerToUpdateProgram = host.setTimeout(updateProgramWithWatchStatus, 250);
        }
        function scheduleProgramReload() {
            ts.Debug.assert(!!configFileName);
            reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
            scheduleProgramUpdate();
        }
        function updateProgramWithWatchStatus() {
            timerToUpdateProgram = undefined;
            reportWatchDiagnostic(ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
            updateProgram();
        }
        function updateProgram() {
            switch (reloadLevel) {
                case ts.ConfigFileProgramReloadLevel.Partial:
                    ts.perfLogger.logStartUpdateProgram("PartialConfigReload");
                    reloadFileNamesFromConfigFile();
                    break;
                case ts.ConfigFileProgramReloadLevel.Full:
                    ts.perfLogger.logStartUpdateProgram("FullConfigReload");
                    reloadConfigFile();
                    break;
                default:
                    ts.perfLogger.logStartUpdateProgram("SynchronizeProgram");
                    synchronizeProgram();
                    break;
            }
            ts.perfLogger.logStopUpdateProgram("Done");
            return getCurrentBuilderProgram();
        }
        function reloadFileNamesFromConfigFile() {
            writeLog("Reloading new file names and options");
            var result = ts.getFileNamesFromConfigSpecs(configFileSpecs, ts.getNormalizedAbsolutePath(ts.getDirectoryPath(configFileName), currentDirectory), compilerOptions, parseConfigFileHost);
            if (ts.updateErrorForNoInputFiles(result, ts.getNormalizedAbsolutePath(configFileName, currentDirectory), configFileSpecs, configFileParsingDiagnostics, canConfigFileJsonReportNoInputFiles)) {
                hasChangedConfigFileParsingErrors = true;
            }
            rootFileNames = result.fileNames;
            // Update the program
            synchronizeProgram();
        }
        function reloadConfigFile() {
            writeLog("Reloading config file: " + configFileName);
            reloadLevel = ts.ConfigFileProgramReloadLevel.None;
            if (cachedDirectoryStructureHost) {
                cachedDirectoryStructureHost.clearCache();
            }
            parseConfigFile();
            hasChangedCompilerOptions = true;
            synchronizeProgram();
            // Update the wild card directory watch
            watchConfigFileWildCardDirectories();
        }
        function parseConfigFile() {
            setConfigFileParsingResult(ts.getParsedCommandLineOfConfigFile(configFileName, optionsToExtendForConfigFile, parseConfigFileHost, /*extendedConfigCache*/ undefined, watchOptionsToExtend, extraFileExtensions)); // TODO: GH#18217
        }
        function setConfigFileParsingResult(configFileParseResult) {
            rootFileNames = configFileParseResult.fileNames;
            compilerOptions = configFileParseResult.options;
            watchOptions = configFileParseResult.watchOptions;
            configFileSpecs = configFileParseResult.configFileSpecs; // TODO: GH#18217
            projectReferences = configFileParseResult.projectReferences;
            configFileParsingDiagnostics = ts.getConfigFileParsingDiagnostics(configFileParseResult).slice();
            canConfigFileJsonReportNoInputFiles = ts.canJsonReportNoInutFiles(configFileParseResult.raw);
            hasChangedConfigFileParsingErrors = true;
        }
        function onSourceFileChange(fileName, eventKind, path) {
            updateCachedSystemWithFile(fileName, path, eventKind);
            // Update the source file cache
            if (eventKind === ts.FileWatcherEventKind.Deleted && sourceFilesCache.has(path)) {
                resolutionCache.invalidateResolutionOfFile(path);
            }
            resolutionCache.removeResolutionsFromProjectReferenceRedirects(path);
            nextSourceFileVersion(path);
            // Update the program
            scheduleProgramUpdate();
        }
        function updateCachedSystemWithFile(fileName, path, eventKind) {
            if (cachedDirectoryStructureHost) {
                cachedDirectoryStructureHost.addOrDeleteFile(fileName, path, eventKind);
            }
        }
        function watchMissingFilePath(missingFilePath) {
            return watchFilePath(host, missingFilePath, onMissingFileChange, ts.PollingInterval.Medium, watchOptions, missingFilePath, ts.WatchType.MissingFile);
        }
        function onMissingFileChange(fileName, eventKind, missingFilePath) {
            updateCachedSystemWithFile(fileName, missingFilePath, eventKind);
            if (eventKind === ts.FileWatcherEventKind.Created && missingFilesMap.has(missingFilePath)) {
                missingFilesMap.get(missingFilePath).close();
                missingFilesMap.delete(missingFilePath);
                // Delete the entry in the source files cache so that new source file is created
                nextSourceFileVersion(missingFilePath);
                // When a missing file is created, we should update the graph.
                scheduleProgramUpdate();
            }
        }
        function watchConfigFileWildCardDirectories() {
            if (configFileSpecs) {
                ts.updateWatchingWildcardDirectories(watchedWildcardDirectories || (watchedWildcardDirectories = ts.createMap()), ts.createMapFromTemplate(configFileSpecs.wildcardDirectories), watchWildcardDirectory);
            }
            else if (watchedWildcardDirectories) {
                ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcherOf);
            }
        }
        function watchWildcardDirectory(directory, flags) {
            return watchDirectory(host, directory, function (fileOrDirectory) {
                ts.Debug.assert(!!configFileName);
                var fileOrDirectoryPath = toPath(fileOrDirectory);
                // Since the file existence changed, update the sourceFiles cache
                if (cachedDirectoryStructureHost) {
                    cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
                }
                nextSourceFileVersion(fileOrDirectoryPath);
                fileOrDirectoryPath = ts.removeIgnoredPath(fileOrDirectoryPath);
                if (!fileOrDirectoryPath)
                    return;
                // If the the added or created file or directory is not supported file name, ignore the file
                // But when watched directory is added/removed, we need to reload the file list
                if (fileOrDirectoryPath !== directory && ts.hasExtension(fileOrDirectoryPath) && !ts.isSupportedSourceFileName(fileOrDirectory, compilerOptions)) {
                    writeLog("Project: " + configFileName + " Detected file add/remove of non supported extension: " + fileOrDirectory);
                    return;
                }
                // Reload is pending, do the reload
                if (reloadLevel !== ts.ConfigFileProgramReloadLevel.Full) {
                    reloadLevel = ts.ConfigFileProgramReloadLevel.Partial;
                    // Schedule Update the program
                    scheduleProgramUpdate();
                }
            }, flags, watchOptions, ts.WatchType.WildcardDirectory);
        }
    }
    ts.createWatchProgram = createWatchProgram;
})(ts || (ts = {}));
/*@internal*/
var ts;
(function (ts) {
    var UpToDateStatusType;
    (function (UpToDateStatusType) {
        UpToDateStatusType[UpToDateStatusType["Unbuildable"] = 0] = "Unbuildable";
        UpToDateStatusType[UpToDateStatusType["UpToDate"] = 1] = "UpToDate";
        /**
         * The project appears out of date because its upstream inputs are newer than its outputs,
         * but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
         * This means we can Pseudo-build (just touch timestamps), as if we had actually built this project.
         */
        UpToDateStatusType[UpToDateStatusType["UpToDateWithUpstreamTypes"] = 2] = "UpToDateWithUpstreamTypes";
        /**
         * The project appears out of date because its upstream inputs are newer than its outputs,
         * but all of its outputs are actually newer than the previous identical outputs of its (.d.ts) inputs.
         * This means we can Pseudo-build (just manipulate outputs), as if we had actually built this project.
         */
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithPrepend"] = 3] = "OutOfDateWithPrepend";
        UpToDateStatusType[UpToDateStatusType["OutputMissing"] = 4] = "OutputMissing";
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithSelf"] = 5] = "OutOfDateWithSelf";
        UpToDateStatusType[UpToDateStatusType["OutOfDateWithUpstream"] = 6] = "OutOfDateWithUpstream";
        UpToDateStatusType[UpToDateStatusType["UpstreamOutOfDate"] = 7] = "UpstreamOutOfDate";
        UpToDateStatusType[UpToDateStatusType["UpstreamBlocked"] = 8] = "UpstreamBlocked";
        UpToDateStatusType[UpToDateStatusType["ComputingUpstream"] = 9] = "ComputingUpstream";
        UpToDateStatusType[UpToDateStatusType["TsVersionOutputOfDate"] = 10] = "TsVersionOutputOfDate";
        /**
         * Projects with no outputs (i.e. "solution" files)
         */
        UpToDateStatusType[UpToDateStatusType["ContainerOnly"] = 11] = "ContainerOnly";
    })(UpToDateStatusType = ts.UpToDateStatusType || (ts.UpToDateStatusType = {}));
    function resolveConfigFileProjectName(project) {
        if (ts.fileExtensionIs(project, ".json" /* Json */)) {
            return project;
        }
        return ts.combinePaths(project, "tsconfig.json");
    }
    ts.resolveConfigFileProjectName = resolveConfigFileProjectName;
})(ts || (ts = {}));
var ts;
(function (ts) {
    var minimumDate = new Date(-8640000000000000);
    var maximumDate = new Date(8640000000000000);
    var BuildResultFlags;
    (function (BuildResultFlags) {
        BuildResultFlags[BuildResultFlags["None"] = 0] = "None";
        /**
         * No errors of any kind occurred during build
         */
        BuildResultFlags[BuildResultFlags["Success"] = 1] = "Success";
        /**
         * None of the .d.ts files emitted by this build were
         * different from the existing files on disk
         */
        BuildResultFlags[BuildResultFlags["DeclarationOutputUnchanged"] = 2] = "DeclarationOutputUnchanged";
        BuildResultFlags[BuildResultFlags["ConfigFileErrors"] = 4] = "ConfigFileErrors";
        BuildResultFlags[BuildResultFlags["SyntaxErrors"] = 8] = "SyntaxErrors";
        BuildResultFlags[BuildResultFlags["TypeErrors"] = 16] = "TypeErrors";
        BuildResultFlags[BuildResultFlags["DeclarationEmitErrors"] = 32] = "DeclarationEmitErrors";
        BuildResultFlags[BuildResultFlags["EmitErrors"] = 64] = "EmitErrors";
        BuildResultFlags[BuildResultFlags["AnyErrors"] = 124] = "AnyErrors";
    })(BuildResultFlags || (BuildResultFlags = {}));
    function createConfigFileMap() {
        return ts.createMap();
    }
    function getOrCreateValueFromConfigFileMap(configFileMap, resolved, createT) {
        var existingValue = configFileMap.get(resolved);
        var newValue;
        if (!existingValue) {
            newValue = createT();
            configFileMap.set(resolved, newValue);
        }
        return existingValue || newValue;
    }
    function getOrCreateValueMapFromConfigFileMap(configFileMap, resolved) {
        return getOrCreateValueFromConfigFileMap(configFileMap, resolved, ts.createMap);
    }
    function newer(date1, date2) {
        return date2 > date1 ? date2 : date1;
    }
    function isDeclarationFile(fileName) {
        return ts.fileExtensionIs(fileName, ".d.ts" /* Dts */);
    }
    /*@internal*/
    function isCircularBuildOrder(buildOrder) {
        return !!buildOrder && !!buildOrder.buildOrder;
    }
    ts.isCircularBuildOrder = isCircularBuildOrder;
    /*@internal*/
    function getBuildOrderFromAnyBuildOrder(anyBuildOrder) {
        return isCircularBuildOrder(anyBuildOrder) ? anyBuildOrder.buildOrder : anyBuildOrder;
    }
    ts.getBuildOrderFromAnyBuildOrder = getBuildOrderFromAnyBuildOrder;
    /**
     * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
     */
    function createBuilderStatusReporter(system, pretty) {
        return function (diagnostic) {
            var output = pretty ? "[" + ts.formatColorAndReset(ts.getLocaleTimeString(system), ts.ForegroundColorEscapeSequences.Grey) + "] " : ts.getLocaleTimeString(system) + " - ";
            output += "" + ts.flattenDiagnosticMessageText(diagnostic.messageText, system.newLine) + (system.newLine + system.newLine);
            system.write(output);
        };
    }
    ts.createBuilderStatusReporter = createBuilderStatusReporter;
    function createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus) {
        var host = ts.createProgramHost(system, createProgram);
        host.getModifiedTime = system.getModifiedTime ? function (path) { return system.getModifiedTime(path); } : ts.returnUndefined;
        host.setModifiedTime = system.setModifiedTime ? function (path, date) { return system.setModifiedTime(path, date); } : ts.noop;
        host.deleteFile = system.deleteFile ? function (path) { return system.deleteFile(path); } : ts.noop;
        host.reportDiagnostic = reportDiagnostic || ts.createDiagnosticReporter(system);
        host.reportSolutionBuilderStatus = reportSolutionBuilderStatus || createBuilderStatusReporter(system);
        host.now = ts.maybeBind(system, system.now); // For testing
        return host;
    }
    function createSolutionBuilderHost(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus, reportErrorSummary) {
        if (system === void 0) { system = ts.sys; }
        var host = createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus);
        host.reportErrorSummary = reportErrorSummary;
        return host;
    }
    ts.createSolutionBuilderHost = createSolutionBuilderHost;
    function createSolutionBuilderWithWatchHost(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus, reportWatchStatus) {
        if (system === void 0) { system = ts.sys; }
        var host = createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus);
        var watchHost = ts.createWatchHost(system, reportWatchStatus);
        ts.copyProperties(host, watchHost);
        return host;
    }
    ts.createSolutionBuilderWithWatchHost = createSolutionBuilderWithWatchHost;
    function getCompilerOptionsOfBuildOptions(buildOptions) {
        var result = {};
        ts.commonOptionsWithBuild.forEach(function (option) {
            if (ts.hasProperty(buildOptions, option.name))
                result[option.name] = buildOptions[option.name];
        });
        return result;
    }
    function createSolutionBuilder(host, rootNames, defaultOptions) {
        return createSolutionBuilderWorker(/*watch*/ false, host, rootNames, defaultOptions);
    }
    ts.createSolutionBuilder = createSolutionBuilder;
    function createSolutionBuilderWithWatch(host, rootNames, defaultOptions, baseWatchOptions) {
        return createSolutionBuilderWorker(/*watch*/ true, host, rootNames, defaultOptions, baseWatchOptions);
    }
    ts.createSolutionBuilderWithWatch = createSolutionBuilderWithWatch;
    function createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions) {
        var host = hostOrHostWithWatch;
        var hostWithWatch = hostOrHostWithWatch;
        var currentDirectory = host.getCurrentDirectory();
        var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames());
        // State of the solution
        var baseCompilerOptions = getCompilerOptionsOfBuildOptions(options);
        var compilerHost = ts.createCompilerHostFromProgramHost(host, function () { return state.projectCompilerOptions; });
        ts.setGetSourceFileAsHashVersioned(compilerHost, host);
        compilerHost.getParsedCommandLine = function (fileName) { return parseConfigFile(state, fileName, toResolvedConfigFilePath(state, fileName)); };
        compilerHost.resolveModuleNames = ts.maybeBind(host, host.resolveModuleNames);
        compilerHost.resolveTypeReferenceDirectives = ts.maybeBind(host, host.resolveTypeReferenceDirectives);
        var moduleResolutionCache = !compilerHost.resolveModuleNames ? ts.createModuleResolutionCache(currentDirectory, getCanonicalFileName) : undefined;
        if (!compilerHost.resolveModuleNames) {
            var loader_3 = function (moduleName, containingFile, redirectedReference) { return ts.resolveModuleName(moduleName, containingFile, state.projectCompilerOptions, compilerHost, moduleResolutionCache, redirectedReference).resolvedModule; };
            compilerHost.resolveModuleNames = function (moduleNames, containingFile, _reusedNames, redirectedReference) {
                return ts.loadWithLocalCache(ts.Debug.checkEachDefined(moduleNames), containingFile, redirectedReference, loader_3);
            };
        }
        var _a = ts.createWatchFactory(hostWithWatch, options), watchFile = _a.watchFile, watchFilePath = _a.watchFilePath, watchDirectory = _a.watchDirectory, writeLog = _a.writeLog;
        var state = {
            host: host,
            hostWithWatch: hostWithWatch,
            currentDirectory: currentDirectory,
            getCanonicalFileName: getCanonicalFileName,
            parseConfigFileHost: ts.parseConfigHostFromCompilerHostLike(host),
            writeFileName: host.trace ? function (s) { return host.trace(s); } : undefined,
            // State of solution
            options: options,
            baseCompilerOptions: baseCompilerOptions,
            rootNames: rootNames,
            baseWatchOptions: baseWatchOptions,
            resolvedConfigFilePaths: ts.createMap(),
            configFileCache: createConfigFileMap(),
            projectStatus: createConfigFileMap(),
            buildInfoChecked: createConfigFileMap(),
            extendedConfigCache: ts.createMap(),
            builderPrograms: createConfigFileMap(),
            diagnostics: createConfigFileMap(),
            projectPendingBuild: createConfigFileMap(),
            projectErrorsReported: createConfigFileMap(),
            compilerHost: compilerHost,
            moduleResolutionCache: moduleResolutionCache,
            // Mutable state
            buildOrder: undefined,
            readFileWithCache: function (f) { return host.readFile(f); },
            projectCompilerOptions: baseCompilerOptions,
            cache: undefined,
            allProjectBuildPending: true,
            needsSummary: true,
            watchAllProjectsPending: watch,
            currentInvalidatedProject: undefined,
            // Watch state
            watch: watch,
            allWatchedWildcardDirectories: createConfigFileMap(),
            allWatchedInputFiles: createConfigFileMap(),
            allWatchedConfigFiles: createConfigFileMap(),
            timerToBuildInvalidatedProject: undefined,
            reportFileChangeDetected: false,
            watchFile: watchFile,
            watchFilePath: watchFilePath,
            watchDirectory: watchDirectory,
            writeLog: writeLog,
        };
        return state;
    }
    function toPath(state, fileName) {
        return ts.toPath(fileName, state.currentDirectory, state.getCanonicalFileName);
    }
    function toResolvedConfigFilePath(state, fileName) {
        var resolvedConfigFilePaths = state.resolvedConfigFilePaths;
        var path = resolvedConfigFilePaths.get(fileName);
        if (path !== undefined)
            return path;
        var resolvedPath = toPath(state, fileName);
        resolvedConfigFilePaths.set(fileName, resolvedPath);
        return resolvedPath;
    }
    function isParsedCommandLine(entry) {
        return !!entry.options;
    }
    function parseConfigFile(state, configFileName, configFilePath) {
        var configFileCache = state.configFileCache;
        var value = configFileCache.get(configFilePath);
        if (value) {
            return isParsedCommandLine(value) ? value : undefined;
        }
        var diagnostic;
        var parseConfigFileHost = state.parseConfigFileHost, baseCompilerOptions = state.baseCompilerOptions, baseWatchOptions = state.baseWatchOptions, extendedConfigCache = state.extendedConfigCache, host = state.host;
        var parsed;
        if (host.getParsedCommandLine) {
            parsed = host.getParsedCommandLine(configFileName);
            if (!parsed)
                diagnostic = ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, configFileName);
        }
        else {
            parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = function (d) { return diagnostic = d; };
            parsed = ts.getParsedCommandLineOfConfigFile(configFileName, baseCompilerOptions, parseConfigFileHost, extendedConfigCache, baseWatchOptions);
            parseConfigFileHost.onUnRecoverableConfigFileDiagnostic = ts.noop;
        }
        configFileCache.set(configFilePath, parsed || diagnostic);
        return parsed;
    }
    function resolveProjectName(state, name) {
        return ts.resolveConfigFileProjectName(ts.resolvePath(state.currentDirectory, name));
    }
    function createBuildOrder(state, roots) {
        var temporaryMarks = ts.createMap();
        var permanentMarks = ts.createMap();
        var circularityReportStack = [];
        var buildOrder;
        var circularDiagnostics;
        for (var _i = 0, roots_1 = roots; _i < roots_1.length; _i++) {
            var root = roots_1[_i];
            visit(root);
        }
        return circularDiagnostics ?
            { buildOrder: buildOrder || ts.emptyArray, circularDiagnostics: circularDiagnostics } :
            buildOrder || ts.emptyArray;
        function visit(configFileName, inCircularContext) {
            var projPath = toResolvedConfigFilePath(state, configFileName);
            // Already visited
            if (permanentMarks.has(projPath))
                return;
            // Circular
            if (temporaryMarks.has(projPath)) {
                if (!inCircularContext) {
                    (circularDiagnostics || (circularDiagnostics = [])).push(ts.createCompilerDiagnostic(ts.Diagnostics.Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0, circularityReportStack.join("\r\n")));
                }
                return;
            }
            temporaryMarks.set(projPath, true);
            circularityReportStack.push(configFileName);
            var parsed = parseConfigFile(state, configFileName, projPath);
            if (parsed && parsed.projectReferences) {
                for (var _i = 0, _a = parsed.projectReferences; _i < _a.length; _i++) {
                    var ref = _a[_i];
                    var resolvedRefPath = resolveProjectName(state, ref.path);
                    visit(resolvedRefPath, inCircularContext || ref.circular);
                }
            }
            circularityReportStack.pop();
            permanentMarks.set(projPath, true);
            (buildOrder || (buildOrder = [])).push(configFileName);
        }
    }
    function getBuildOrder(state) {
        return state.buildOrder || createStateBuildOrder(state);
    }
    function createStateBuildOrder(state) {
        var buildOrder = createBuildOrder(state, state.rootNames.map(function (f) { return resolveProjectName(state, f); }));
        // Clear all to ResolvedConfigFilePaths cache to start fresh
        state.resolvedConfigFilePaths.clear();
        var currentProjects = ts.arrayToSet(getBuildOrderFromAnyBuildOrder(buildOrder), function (resolved) { return toResolvedConfigFilePath(state, resolved); });
        var noopOnDelete = { onDeleteValue: ts.noop };
        // Config file cache
        ts.mutateMapSkippingNewValues(state.configFileCache, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.projectStatus, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.buildInfoChecked, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.builderPrograms, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.diagnostics, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.projectPendingBuild, currentProjects, noopOnDelete);
        ts.mutateMapSkippingNewValues(state.projectErrorsReported, currentProjects, noopOnDelete);
        // Remove watches for the program no longer in the solution
        if (state.watch) {
            ts.mutateMapSkippingNewValues(state.allWatchedConfigFiles, currentProjects, { onDeleteValue: ts.closeFileWatcher });
            ts.mutateMapSkippingNewValues(state.allWatchedWildcardDirectories, currentProjects, { onDeleteValue: function (existingMap) { return existingMap.forEach(ts.closeFileWatcherOf); } });
            ts.mutateMapSkippingNewValues(state.allWatchedInputFiles, currentProjects, { onDeleteValue: function (existingMap) { return existingMap.forEach(ts.closeFileWatcher); } });
        }
        return state.buildOrder = buildOrder;
    }
    function getBuildOrderFor(state, project, onlyReferences) {
        var resolvedProject = project && resolveProjectName(state, project);
        var buildOrderFromState = getBuildOrder(state);
        if (isCircularBuildOrder(buildOrderFromState))
            return buildOrderFromState;
        if (resolvedProject) {
            var projectPath_1 = toResolvedConfigFilePath(state, resolvedProject);
            var projectIndex = ts.findIndex(buildOrderFromState, function (configFileName) { return toResolvedConfigFilePath(state, configFileName) === projectPath_1; });
            if (projectIndex === -1)
                return undefined;
        }
        var buildOrder = resolvedProject ? createBuildOrder(state, [resolvedProject]) : buildOrderFromState;
        ts.Debug.assert(!isCircularBuildOrder(buildOrder));
        ts.Debug.assert(!onlyReferences || resolvedProject !== undefined);
        ts.Debug.assert(!onlyReferences || buildOrder[buildOrder.length - 1] === resolvedProject);
        return onlyReferences ? buildOrder.slice(0, buildOrder.length - 1) : buildOrder;
    }
    function enableCache(state) {
        if (state.cache) {
            disableCache(state);
        }
        var compilerHost = state.compilerHost, host = state.host;
        var originalReadFileWithCache = state.readFileWithCache;
        var originalGetSourceFile = compilerHost.getSourceFile;
        var _a = ts.changeCompilerHostLikeToUseCache(host, function (fileName) { return toPath(state, fileName); }, function () {
            var args = [];
            for (var _i = 0; _i < arguments.length; _i++) {
                args[_i] = arguments[_i];
            }
            return originalGetSourceFile.call.apply(originalGetSourceFile, __spreadArrays([compilerHost], args));
        }), originalReadFile = _a.originalReadFile, originalFileExists = _a.originalFileExists, originalDirectoryExists = _a.originalDirectoryExists, originalCreateDirectory = _a.originalCreateDirectory, originalWriteFile = _a.originalWriteFile, getSourceFileWithCache = _a.getSourceFileWithCache, readFileWithCache = _a.readFileWithCache;
        state.readFileWithCache = readFileWithCache;
        compilerHost.getSourceFile = getSourceFileWithCache;
        state.cache = {
            originalReadFile: originalReadFile,
            originalFileExists: originalFileExists,
            originalDirectoryExists: originalDirectoryExists,
            originalCreateDirectory: originalCreateDirectory,
            originalWriteFile: originalWriteFile,
            originalReadFileWithCache: originalReadFileWithCache,
            originalGetSourceFile: originalGetSourceFile,
        };
    }
    function disableCache(state) {
        if (!state.cache)
            return;
        var cache = state.cache, host = state.host, compilerHost = state.compilerHost, extendedConfigCache = state.extendedConfigCache, moduleResolutionCache = state.moduleResolutionCache;
        host.readFile = cache.originalReadFile;
        host.fileExists = cache.originalFileExists;
        host.directoryExists = cache.originalDirectoryExists;
        host.createDirectory = cache.originalCreateDirectory;
        host.writeFile = cache.originalWriteFile;
        compilerHost.getSourceFile = cache.originalGetSourceFile;
        state.readFileWithCache = cache.originalReadFileWithCache;
        extendedConfigCache.clear();
        if (moduleResolutionCache) {
            moduleResolutionCache.directoryToModuleNameMap.clear();
            moduleResolutionCache.moduleNameToDirectoryMap.clear();
        }
        state.cache = undefined;
    }
    function clearProjectStatus(state, resolved) {
        state.projectStatus.delete(resolved);
        state.diagnostics.delete(resolved);
    }
    function addProjToQueue(_a, proj, reloadLevel) {
        var projectPendingBuild = _a.projectPendingBuild;
        var value = projectPendingBuild.get(proj);
        if (value === undefined) {
            projectPendingBuild.set(proj, reloadLevel);
        }
        else if (value < reloadLevel) {
            projectPendingBuild.set(proj, reloadLevel);
        }
    }
    function setupInitialBuild(state, cancellationToken) {
        // Set initial build if not already built
        if (!state.allProjectBuildPending)
            return;
        state.allProjectBuildPending = false;
        if (state.options.watch) {
            reportWatchStatus(state, ts.Diagnostics.Starting_compilation_in_watch_mode);
        }
        enableCache(state);
        var buildOrder = getBuildOrderFromAnyBuildOrder(getBuildOrder(state));
        buildOrder.forEach(function (configFileName) {
            return state.projectPendingBuild.set(toResolvedConfigFilePath(state, configFileName), ts.ConfigFileProgramReloadLevel.None);
        });
        if (cancellationToken) {
            cancellationToken.throwIfCancellationRequested();
        }
    }
    var InvalidatedProjectKind;
    (function (InvalidatedProjectKind) {
        InvalidatedProjectKind[InvalidatedProjectKind["Build"] = 0] = "Build";
        InvalidatedProjectKind[InvalidatedProjectKind["UpdateBundle"] = 1] = "UpdateBundle";
        InvalidatedProjectKind[InvalidatedProjectKind["UpdateOutputFileStamps"] = 2] = "UpdateOutputFileStamps";
    })(InvalidatedProjectKind = ts.InvalidatedProjectKind || (ts.InvalidatedProjectKind = {}));
    function doneInvalidatedProject(state, projectPath) {
        state.projectPendingBuild.delete(projectPath);
        state.currentInvalidatedProject = undefined;
        return state.diagnostics.has(projectPath) ?
            ts.ExitStatus.DiagnosticsPresent_OutputsSkipped :
            ts.ExitStatus.Success;
    }
    function createUpdateOutputFileStampsProject(state, project, projectPath, config, buildOrder) {
        var updateOutputFileStampsPending = true;
        return {
            kind: InvalidatedProjectKind.UpdateOutputFileStamps,
            project: project,
            projectPath: projectPath,
            buildOrder: buildOrder,
            getCompilerOptions: function () { return config.options; },
            getCurrentDirectory: function () { return state.currentDirectory; },
            updateOutputFileStatmps: function () {
                updateOutputTimestamps(state, config, projectPath);
                updateOutputFileStampsPending = false;
            },
            done: function () {
                if (updateOutputFileStampsPending) {
                    updateOutputTimestamps(state, config, projectPath);
                }
                return doneInvalidatedProject(state, projectPath);
            }
        };
    }
    function createBuildOrUpdateInvalidedProject(kind, state, project, projectPath, projectIndex, config, buildOrder) {
        var Step;
        (function (Step) {
            Step[Step["CreateProgram"] = 0] = "CreateProgram";
            Step[Step["SyntaxDiagnostics"] = 1] = "SyntaxDiagnostics";
            Step[Step["SemanticDiagnostics"] = 2] = "SemanticDiagnostics";
            Step[Step["Emit"] = 3] = "Emit";
            Step[Step["EmitBundle"] = 4] = "EmitBundle";
            Step[Step["BuildInvalidatedProjectOfBundle"] = 5] = "BuildInvalidatedProjectOfBundle";
            Step[Step["QueueReferencingProjects"] = 6] = "QueueReferencingProjects";
            Step[Step["Done"] = 7] = "Done";
        })(Step || (Step = {}));
        var step = kind === InvalidatedProjectKind.Build ? Step.CreateProgram : Step.EmitBundle;
        var program;
        var buildResult;
        var invalidatedProjectOfBundle;
        return kind === InvalidatedProjectKind.Build ?
            {
                kind: kind,
                project: project,
                projectPath: projectPath,
                buildOrder: buildOrder,
                getCompilerOptions: function () { return config.options; },
                getCurrentDirectory: function () { return state.currentDirectory; },
                getBuilderProgram: function () { return withProgramOrUndefined(ts.identity); },
                getProgram: function () {
                    return withProgramOrUndefined(function (program) { return program.getProgramOrUndefined(); });
                },
                getSourceFile: function (fileName) {
                    return withProgramOrUndefined(function (program) { return program.getSourceFile(fileName); });
                },
                getSourceFiles: function () {
                    return withProgramOrEmptyArray(function (program) { return program.getSourceFiles(); });
                },
                getOptionsDiagnostics: function (cancellationToken) {
                    return withProgramOrEmptyArray(function (program) { return program.getOptionsDiagnostics(cancellationToken); });
                },
                getGlobalDiagnostics: function (cancellationToken) {
                    return withProgramOrEmptyArray(function (program) { return program.getGlobalDiagnostics(cancellationToken); });
                },
                getConfigFileParsingDiagnostics: function () {
                    return withProgramOrEmptyArray(function (program) { return program.getConfigFileParsingDiagnostics(); });
                },
                getSyntacticDiagnostics: function (sourceFile, cancellationToken) {
                    return withProgramOrEmptyArray(function (program) { return program.getSyntacticDiagnostics(sourceFile, cancellationToken); });
                },
                getAllDependencies: function (sourceFile) {
                    return withProgramOrEmptyArray(function (program) { return program.getAllDependencies(sourceFile); });
                },
                getSemanticDiagnostics: function (sourceFile, cancellationToken) {
                    return withProgramOrEmptyArray(function (program) { return program.getSemanticDiagnostics(sourceFile, cancellationToken); });
                },
                getSemanticDiagnosticsOfNextAffectedFile: function (cancellationToken, ignoreSourceFile) {
                    return withProgramOrUndefined(function (program) {
                        return (program.getSemanticDiagnosticsOfNextAffectedFile) &&
                            program.getSemanticDiagnosticsOfNextAffectedFile(cancellationToken, ignoreSourceFile);
                    });
                },
                emit: function (targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) {
                    if (targetSourceFile || emitOnlyDtsFiles) {
                        return withProgramOrUndefined(function (program) { return program.emit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers); });
                    }
                    executeSteps(Step.SemanticDiagnostics, cancellationToken);
                    if (step !== Step.Emit)
                        return undefined;
                    return emit(writeFile, cancellationToken, customTransformers);
                },
                done: done
            } :
            {
                kind: kind,
                project: project,
                projectPath: projectPath,
                buildOrder: buildOrder,
                getCompilerOptions: function () { return config.options; },
                getCurrentDirectory: function () { return state.currentDirectory; },
                emit: function (writeFile, customTransformers) {
                    if (step !== Step.EmitBundle)
                        return invalidatedProjectOfBundle;
                    return emitBundle(writeFile, customTransformers);
                },
                done: done,
            };
        function done(cancellationToken, writeFile, customTransformers) {
            executeSteps(Step.Done, cancellationToken, writeFile, customTransformers);
            return doneInvalidatedProject(state, projectPath);
        }
        function withProgramOrUndefined(action) {
            executeSteps(Step.CreateProgram);
            return program && action(program);
        }
        function withProgramOrEmptyArray(action) {
            return withProgramOrUndefined(action) || ts.emptyArray;
        }
        function createProgram() {
            ts.Debug.assert(program === undefined);
            if (state.options.dry) {
                reportStatus(state, ts.Diagnostics.A_non_dry_build_would_build_project_0, project);
                buildResult = BuildResultFlags.Success;
                step = Step.QueueReferencingProjects;
                return;
            }
            if (state.options.verbose)
                reportStatus(state, ts.Diagnostics.Building_project_0, project);
            if (config.fileNames.length === 0) {
                reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                // Nothing to build - must be a solution file, basically
                buildResult = BuildResultFlags.None;
                step = Step.QueueReferencingProjects;
                return;
            }
            var host = state.host, compilerHost = state.compilerHost;
            state.projectCompilerOptions = config.options;
            // Update module resolution cache if needed
            updateModuleResolutionCache(state, project, config);
            // Create program
            program = host.createProgram(config.fileNames, config.options, compilerHost, getOldProgram(state, projectPath, config), ts.getConfigFileParsingDiagnostics(config), config.projectReferences);
            step++;
        }
        function handleDiagnostics(diagnostics, errorFlags, errorType) {
            if (diagnostics.length) {
                buildResult = buildErrors(state, projectPath, program, config, diagnostics, errorFlags, errorType);
                step = Step.QueueReferencingProjects;
            }
            else {
                step++;
            }
        }
        function getSyntaxDiagnostics(cancellationToken) {
            ts.Debug.assertIsDefined(program);
            handleDiagnostics(__spreadArrays(program.getConfigFileParsingDiagnostics(), program.getOptionsDiagnostics(cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSyntacticDiagnostics(/*sourceFile*/ undefined, cancellationToken)), BuildResultFlags.SyntaxErrors, "Syntactic");
        }
        function getSemanticDiagnostics(cancellationToken) {
            handleDiagnostics(ts.Debug.checkDefined(program).getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken), BuildResultFlags.TypeErrors, "Semantic");
        }
        function emit(writeFileCallback, cancellationToken, customTransformers) {
            ts.Debug.assertIsDefined(program);
            ts.Debug.assert(step === Step.Emit);
            // Before emitting lets backup state, so we can revert it back if there are declaration errors to handle emit and declaration errors correctly
            program.backupState();
            var declDiagnostics;
            var reportDeclarationDiagnostics = function (d) { return (declDiagnostics || (declDiagnostics = [])).push(d); };
            var outputFiles = [];
            var emitResult = ts.emitFilesAndReportErrors(program, reportDeclarationDiagnostics, 
            /*writeFileName*/ undefined, 
            /*reportSummary*/ undefined, function (name, text, writeByteOrderMark) { return outputFiles.push({ name: name, text: text, writeByteOrderMark: writeByteOrderMark }); }, cancellationToken, 
            /*emitOnlyDts*/ false, customTransformers).emitResult;
            // Don't emit .d.ts if there are decl file errors
            if (declDiagnostics) {
                program.restoreState();
                buildResult = buildErrors(state, projectPath, program, config, declDiagnostics, BuildResultFlags.DeclarationEmitErrors, "Declaration file");
                step = Step.QueueReferencingProjects;
                return {
                    emitSkipped: true,
                    diagnostics: emitResult.diagnostics
                };
            }
            // Actual Emit
            var host = state.host, compilerHost = state.compilerHost;
            var resultFlags = BuildResultFlags.DeclarationOutputUnchanged;
            var newestDeclarationFileContentChangedTime = minimumDate;
            var anyDtsChanged = false;
            var emitterDiagnostics = ts.createDiagnosticCollection();
            var emittedOutputs = ts.createMap();
            outputFiles.forEach(function (_a) {
                var name = _a.name, text = _a.text, writeByteOrderMark = _a.writeByteOrderMark;
                var priorChangeTime;
                if (!anyDtsChanged && isDeclarationFile(name)) {
                    // Check for unchanged .d.ts files
                    if (host.fileExists(name) && state.readFileWithCache(name) === text) {
                        priorChangeTime = host.getModifiedTime(name);
                    }
                    else {
                        resultFlags &= ~BuildResultFlags.DeclarationOutputUnchanged;
                        anyDtsChanged = true;
                    }
                }
                emittedOutputs.set(toPath(state, name), name);
                ts.writeFile(writeFileCallback ? { writeFile: writeFileCallback } : compilerHost, emitterDiagnostics, name, text, writeByteOrderMark);
                if (priorChangeTime !== undefined) {
                    newestDeclarationFileContentChangedTime = newer(priorChangeTime, newestDeclarationFileContentChangedTime);
                }
            });
            finishEmit(emitterDiagnostics, emittedOutputs, newestDeclarationFileContentChangedTime, 
            /*newestDeclarationFileContentChangedTimeIsMaximumDate*/ anyDtsChanged, outputFiles.length ? outputFiles[0].name : ts.getFirstProjectOutput(config, !host.useCaseSensitiveFileNames()), resultFlags);
            return emitResult;
        }
        function finishEmit(emitterDiagnostics, emittedOutputs, priorNewestUpdateTime, newestDeclarationFileContentChangedTimeIsMaximumDate, oldestOutputFileName, resultFlags) {
            var emitDiagnostics = emitterDiagnostics.getDiagnostics();
            if (emitDiagnostics.length) {
                buildResult = buildErrors(state, projectPath, program, config, emitDiagnostics, BuildResultFlags.EmitErrors, "Emit");
                step = Step.QueueReferencingProjects;
                return emitDiagnostics;
            }
            if (state.writeFileName) {
                emittedOutputs.forEach(function (name) { return listEmittedFile(state, config, name); });
                if (program)
                    ts.listFiles(program, state.writeFileName);
            }
            // Update time stamps for rest of the outputs
            var newestDeclarationFileContentChangedTime = updateOutputTimestampsWorker(state, config, priorNewestUpdateTime, ts.Diagnostics.Updating_unchanged_output_timestamps_of_project_0, emittedOutputs);
            state.diagnostics.delete(projectPath);
            state.projectStatus.set(projectPath, {
                type: ts.UpToDateStatusType.UpToDate,
                newestDeclarationFileContentChangedTime: newestDeclarationFileContentChangedTimeIsMaximumDate ?
                    maximumDate :
                    newestDeclarationFileContentChangedTime,
                oldestOutputFileName: oldestOutputFileName
            });
            afterProgramDone(state, projectPath, program, config);
            state.projectCompilerOptions = state.baseCompilerOptions;
            step = Step.QueueReferencingProjects;
            buildResult = resultFlags;
            return emitDiagnostics;
        }
        function emitBundle(writeFileCallback, customTransformers) {
            ts.Debug.assert(kind === InvalidatedProjectKind.UpdateBundle);
            if (state.options.dry) {
                reportStatus(state, ts.Diagnostics.A_non_dry_build_would_update_output_of_project_0, project);
                buildResult = BuildResultFlags.Success;
                step = Step.QueueReferencingProjects;
                return undefined;
            }
            if (state.options.verbose)
                reportStatus(state, ts.Diagnostics.Updating_output_of_project_0, project);
            // Update js, and source map
            var compilerHost = state.compilerHost;
            state.projectCompilerOptions = config.options;
            var outputFiles = ts.emitUsingBuildInfo(config, compilerHost, function (ref) {
                var refName = resolveProjectName(state, ref.path);
                return parseConfigFile(state, refName, toResolvedConfigFilePath(state, refName));
            }, customTransformers);
            if (ts.isString(outputFiles)) {
                reportStatus(state, ts.Diagnostics.Cannot_update_output_of_project_0_because_there_was_error_reading_file_1, project, relName(state, outputFiles));
                step = Step.BuildInvalidatedProjectOfBundle;
                return invalidatedProjectOfBundle = createBuildOrUpdateInvalidedProject(InvalidatedProjectKind.Build, state, project, projectPath, projectIndex, config, buildOrder);
            }
            // Actual Emit
            ts.Debug.assert(!!outputFiles.length);
            var emitterDiagnostics = ts.createDiagnosticCollection();
            var emittedOutputs = ts.createMap();
            outputFiles.forEach(function (_a) {
                var name = _a.name, text = _a.text, writeByteOrderMark = _a.writeByteOrderMark;
                emittedOutputs.set(toPath(state, name), name);
                ts.writeFile(writeFileCallback ? { writeFile: writeFileCallback } : compilerHost, emitterDiagnostics, name, text, writeByteOrderMark);
            });
            var emitDiagnostics = finishEmit(emitterDiagnostics, emittedOutputs, minimumDate, 
            /*newestDeclarationFileContentChangedTimeIsMaximumDate*/ false, outputFiles[0].name, BuildResultFlags.DeclarationOutputUnchanged);
            return { emitSkipped: false, diagnostics: emitDiagnostics };
        }
        function executeSteps(till, cancellationToken, writeFile, customTransformers) {
            while (step <= till && step < Step.Done) {
                var currentStep = step;
                switch (step) {
                    case Step.CreateProgram:
                        createProgram();
                        break;
                    case Step.SyntaxDiagnostics:
                        getSyntaxDiagnostics(cancellationToken);
                        break;
                    case Step.SemanticDiagnostics:
                        getSemanticDiagnostics(cancellationToken);
                        break;
                    case Step.Emit:
                        emit(writeFile, cancellationToken, customTransformers);
                        break;
                    case Step.EmitBundle:
                        emitBundle(writeFile, customTransformers);
                        break;
                    case Step.BuildInvalidatedProjectOfBundle:
                        ts.Debug.checkDefined(invalidatedProjectOfBundle).done(cancellationToken);
                        step = Step.Done;
                        break;
                    case Step.QueueReferencingProjects:
                        queueReferencingProjects(state, project, projectPath, projectIndex, config, buildOrder, ts.Debug.checkDefined(buildResult));
                        step++;
                        break;
                    // Should never be done
                    case Step.Done:
                    default:
                        ts.assertType(step);
                }
                ts.Debug.assert(step > currentStep);
            }
        }
    }
    function needsBuild(_a, status, config) {
        var options = _a.options;
        if (status.type !== ts.UpToDateStatusType.OutOfDateWithPrepend || options.force)
            return true;
        return config.fileNames.length === 0 ||
            !!ts.getConfigFileParsingDiagnostics(config).length ||
            !ts.isIncrementalCompilation(config.options);
    }
    function getNextInvalidatedProject(state, buildOrder, reportQueue) {
        if (!state.projectPendingBuild.size)
            return undefined;
        if (isCircularBuildOrder(buildOrder))
            return undefined;
        if (state.currentInvalidatedProject) {
            // Only if same buildOrder the currentInvalidated project can be sent again
            return ts.arrayIsEqualTo(state.currentInvalidatedProject.buildOrder, buildOrder) ?
                state.currentInvalidatedProject :
                undefined;
        }
        var options = state.options, projectPendingBuild = state.projectPendingBuild;
        for (var projectIndex = 0; projectIndex < buildOrder.length; projectIndex++) {
            var project = buildOrder[projectIndex];
            var projectPath = toResolvedConfigFilePath(state, project);
            var reloadLevel = state.projectPendingBuild.get(projectPath);
            if (reloadLevel === undefined)
                continue;
            if (reportQueue) {
                reportQueue = false;
                reportBuildQueue(state, buildOrder);
            }
            var config = parseConfigFile(state, project, projectPath);
            if (!config) {
                reportParseConfigFileDiagnostic(state, projectPath);
                projectPendingBuild.delete(projectPath);
                continue;
            }
            if (reloadLevel === ts.ConfigFileProgramReloadLevel.Full) {
                watchConfigFile(state, project, projectPath, config);
                watchWildCardDirectories(state, project, projectPath, config);
                watchInputFiles(state, project, projectPath, config);
            }
            else if (reloadLevel === ts.ConfigFileProgramReloadLevel.Partial) {
                // Update file names
                var result = ts.getFileNamesFromConfigSpecs(config.configFileSpecs, ts.getDirectoryPath(project), config.options, state.parseConfigFileHost);
                ts.updateErrorForNoInputFiles(result, project, config.configFileSpecs, config.errors, ts.canJsonReportNoInutFiles(config.raw));
                config.fileNames = result.fileNames;
                watchInputFiles(state, project, projectPath, config);
            }
            var status = getUpToDateStatus(state, config, projectPath);
            verboseReportProjectStatus(state, project, status);
            if (!options.force) {
                if (status.type === ts.UpToDateStatusType.UpToDate) {
                    reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                    projectPendingBuild.delete(projectPath);
                    // Up to date, skip
                    if (options.dry) {
                        // In a dry build, inform the user of this fact
                        reportStatus(state, ts.Diagnostics.Project_0_is_up_to_date, project);
                    }
                    continue;
                }
                if (status.type === ts.UpToDateStatusType.UpToDateWithUpstreamTypes) {
                    reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                    return createUpdateOutputFileStampsProject(state, project, projectPath, config, buildOrder);
                }
            }
            if (status.type === ts.UpToDateStatusType.UpstreamBlocked) {
                reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                projectPendingBuild.delete(projectPath);
                if (options.verbose) {
                    reportStatus(state, status.upstreamProjectBlocked ?
                        ts.Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_was_not_built :
                        ts.Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, project, status.upstreamProjectName);
                }
                continue;
            }
            if (status.type === ts.UpToDateStatusType.ContainerOnly) {
                reportAndStoreErrors(state, projectPath, ts.getConfigFileParsingDiagnostics(config));
                projectPendingBuild.delete(projectPath);
                // Do nothing
                continue;
            }
            return createBuildOrUpdateInvalidedProject(needsBuild(state, status, config) ?
                InvalidatedProjectKind.Build :
                InvalidatedProjectKind.UpdateBundle, state, project, projectPath, projectIndex, config, buildOrder);
        }
        return undefined;
    }
    function listEmittedFile(_a, proj, file) {
        var writeFileName = _a.writeFileName;
        if (writeFileName && proj.options.listEmittedFiles) {
            writeFileName("TSFILE: " + file);
        }
    }
    function getOldProgram(_a, proj, parsed) {
        var options = _a.options, builderPrograms = _a.builderPrograms, compilerHost = _a.compilerHost;
        if (options.force)
            return undefined;
        var value = builderPrograms.get(proj);
        if (value)
            return value;
        return ts.readBuilderProgram(parsed.options, compilerHost);
    }
    function afterProgramDone(_a, proj, program, config) {
        var host = _a.host, watch = _a.watch, builderPrograms = _a.builderPrograms;
        if (program) {
            if (host.afterProgramEmitAndDiagnostics) {
                host.afterProgramEmitAndDiagnostics(program);
            }
            if (watch) {
                program.releaseProgram();
                builderPrograms.set(proj, program);
            }
        }
        else if (host.afterEmitBundle) {
            host.afterEmitBundle(config);
        }
    }
    function buildErrors(state, resolvedPath, program, config, diagnostics, errorFlags, errorType) {
        reportAndStoreErrors(state, resolvedPath, diagnostics);
        // List files if any other build error using program (emit errors already report files)
        if (program && state.writeFileName)
            ts.listFiles(program, state.writeFileName);
        state.projectStatus.set(resolvedPath, { type: ts.UpToDateStatusType.Unbuildable, reason: errorType + " errors" });
        afterProgramDone(state, resolvedPath, program, config);
        state.projectCompilerOptions = state.baseCompilerOptions;
        return errorFlags;
    }
    function updateModuleResolutionCache(state, proj, config) {
        if (!state.moduleResolutionCache)
            return;
        // Update module resolution cache if needed
        var moduleResolutionCache = state.moduleResolutionCache;
        var projPath = toPath(state, proj);
        if (moduleResolutionCache.directoryToModuleNameMap.redirectsMap.size === 0) {
            // The own map will be for projectCompilerOptions
            ts.Debug.assert(moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.size === 0);
            moduleResolutionCache.directoryToModuleNameMap.redirectsMap.set(projPath, moduleResolutionCache.directoryToModuleNameMap.ownMap);
            moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.set(projPath, moduleResolutionCache.moduleNameToDirectoryMap.ownMap);
        }
        else {
            // Set correct own map
            ts.Debug.assert(moduleResolutionCache.moduleNameToDirectoryMap.redirectsMap.size > 0);
            var ref = {
                sourceFile: config.options.configFile,
                commandLine: config
            };
            moduleResolutionCache.directoryToModuleNameMap.setOwnMap(moduleResolutionCache.directoryToModuleNameMap.getOrCreateMapOfCacheRedirects(ref));
            moduleResolutionCache.moduleNameToDirectoryMap.setOwnMap(moduleResolutionCache.moduleNameToDirectoryMap.getOrCreateMapOfCacheRedirects(ref));
        }
        moduleResolutionCache.directoryToModuleNameMap.setOwnOptions(config.options);
        moduleResolutionCache.moduleNameToDirectoryMap.setOwnOptions(config.options);
    }
    function checkConfigFileUpToDateStatus(state, configFile, oldestOutputFileTime, oldestOutputFileName) {
        // Check tsconfig time
        var tsconfigTime = state.host.getModifiedTime(configFile) || ts.missingFileModifiedTime;
        if (oldestOutputFileTime < tsconfigTime) {
            return {
                type: ts.UpToDateStatusType.OutOfDateWithSelf,
                outOfDateOutputFileName: oldestOutputFileName,
                newerInputFileName: configFile
            };
        }
    }
    function getUpToDateStatusWorker(state, project, resolvedPath) {
        var newestInputFileName = undefined;
        var newestInputFileTime = minimumDate;
        var host = state.host;
        // Get timestamps of input files
        for (var _i = 0, _a = project.fileNames; _i < _a.length; _i++) {
            var inputFile = _a[_i];
            if (!host.fileExists(inputFile)) {
                return {
                    type: ts.UpToDateStatusType.Unbuildable,
                    reason: inputFile + " does not exist"
                };
            }
            var inputTime = host.getModifiedTime(inputFile) || ts.missingFileModifiedTime;
            if (inputTime > newestInputFileTime) {
                newestInputFileName = inputFile;
                newestInputFileTime = inputTime;
            }
        }
        // Container if no files are specified in the project
        if (!project.fileNames.length && !ts.canJsonReportNoInutFiles(project.raw)) {
            return {
                type: ts.UpToDateStatusType.ContainerOnly
            };
        }
        // Collect the expected outputs of this project
        var outputs = ts.getAllProjectOutputs(project, !host.useCaseSensitiveFileNames());
        // Now see if all outputs are newer than the newest input
        var oldestOutputFileName = "(none)";
        var oldestOutputFileTime = maximumDate;
        var newestOutputFileName = "(none)";
        var newestOutputFileTime = minimumDate;
        var missingOutputFileName;
        var newestDeclarationFileContentChangedTime = minimumDate;
        var isOutOfDateWithInputs = false;
        for (var _b = 0, outputs_1 = outputs; _b < outputs_1.length; _b++) {
            var output = outputs_1[_b];
            // Output is missing; can stop checking
            // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
            if (!host.fileExists(output)) {
                missingOutputFileName = output;
                break;
            }
            var outputTime = host.getModifiedTime(output) || ts.missingFileModifiedTime;
            if (outputTime < oldestOutputFileTime) {
                oldestOutputFileTime = outputTime;
                oldestOutputFileName = output;
            }
            // If an output is older than the newest input, we can stop checking
            // Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
            if (outputTime < newestInputFileTime) {
                isOutOfDateWithInputs = true;
                break;
            }
            if (outputTime > newestOutputFileTime) {
                newestOutputFileTime = outputTime;
                newestOutputFileName = output;
            }
            // Keep track of when the most recent time a .d.ts file was changed.
            // In addition to file timestamps, we also keep track of when a .d.ts file
            // had its file touched but not had its contents changed - this allows us
            // to skip a downstream typecheck
            if (isDeclarationFile(output)) {
                var outputModifiedTime = host.getModifiedTime(output) || ts.missingFileModifiedTime;
                newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime);
            }
        }
        var pseudoUpToDate = false;
        var usesPrepend = false;
        var upstreamChangedProject;
        if (project.projectReferences) {
            state.projectStatus.set(resolvedPath, { type: ts.UpToDateStatusType.ComputingUpstream });
            for (var _c = 0, _d = project.projectReferences; _c < _d.length; _c++) {
                var ref = _d[_c];
                usesPrepend = usesPrepend || !!(ref.prepend);
                var resolvedRef = ts.resolveProjectReferencePath(ref);
                var resolvedRefPath = toResolvedConfigFilePath(state, resolvedRef);
                var refStatus = getUpToDateStatus(state, parseConfigFile(state, resolvedRef, resolvedRefPath), resolvedRefPath);
                // Its a circular reference ignore the status of this project
                if (refStatus.type === ts.UpToDateStatusType.ComputingUpstream ||
                    refStatus.type === ts.UpToDateStatusType.ContainerOnly) { // Container only ignore this project
                    continue;
                }
                // An upstream project is blocked
                if (refStatus.type === ts.UpToDateStatusType.Unbuildable ||
                    refStatus.type === ts.UpToDateStatusType.UpstreamBlocked) {
                    return {
                        type: ts.UpToDateStatusType.UpstreamBlocked,
                        upstreamProjectName: ref.path,
                        upstreamProjectBlocked: refStatus.type === ts.UpToDateStatusType.UpstreamBlocked
                    };
                }
                // If the upstream project is out of date, then so are we (someone shouldn't have asked, though?)
                if (refStatus.type !== ts.UpToDateStatusType.UpToDate) {
                    return {
                        type: ts.UpToDateStatusType.UpstreamOutOfDate,
                        upstreamProjectName: ref.path
                    };
                }
                // Check oldest output file name only if there is no missing output file name
                if (!missingOutputFileName) {
                    // If the upstream project's newest file is older than our oldest output, we
                    // can't be out of date because of it
                    if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) {
                        continue;
                    }
                    // If the upstream project has only change .d.ts files, and we've built
                    // *after* those files, then we're "psuedo up to date" and eligible for a fast rebuild
                    if (refStatus.newestDeclarationFileContentChangedTime && refStatus.newestDeclarationFileContentChangedTime <= oldestOutputFileTime) {
                        pseudoUpToDate = true;
                        upstreamChangedProject = ref.path;
                        continue;
                    }
                    // We have an output older than an upstream output - we are out of date
                    ts.Debug.assert(oldestOutputFileName !== undefined, "Should have an oldest output filename here");
                    return {
                        type: ts.UpToDateStatusType.OutOfDateWithUpstream,
                        outOfDateOutputFileName: oldestOutputFileName,
                        newerProjectName: ref.path
                    };
                }
            }
        }
        if (missingOutputFileName !== undefined) {
            return {
                type: ts.UpToDateStatusType.OutputMissing,
                missingOutputFileName: missingOutputFileName
            };
        }
        if (isOutOfDateWithInputs) {
            return {
                type: ts.UpToDateStatusType.OutOfDateWithSelf,
                outOfDateOutputFileName: oldestOutputFileName,
                newerInputFileName: newestInputFileName
            };
        }
        else {
            // Check tsconfig time
            var configStatus = checkConfigFileUpToDateStatus(state, project.options.configFilePath, oldestOutputFileTime, oldestOutputFileName);
            if (configStatus)
                return configStatus;
            // Check extended config time
            var extendedConfigStatus = ts.forEach(project.options.configFile.extendedSourceFiles || ts.emptyArray, function (configFile) { return checkConfigFileUpToDateStatus(state, configFile, oldestOutputFileTime, oldestOutputFileName); });
            if (extendedConfigStatus)
                return extendedConfigStatus;
        }
        if (!state.buildInfoChecked.has(resolvedPath)) {
            state.buildInfoChecked.set(resolvedPath, true);
            var buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(project.options);
            if (buildInfoPath) {
                var value = state.readFileWithCache(buildInfoPath);
                var buildInfo = value && ts.getBuildInfo(value);
                if (buildInfo && (buildInfo.bundle || buildInfo.program) && buildInfo.version !== ts.version) {
                    return {
                        type: ts.UpToDateStatusType.TsVersionOutputOfDate,
                        version: buildInfo.version
                    };
                }
            }
        }
        if (usesPrepend && pseudoUpToDate) {
            return {
                type: ts.UpToDateStatusType.OutOfDateWithPrepend,
                outOfDateOutputFileName: oldestOutputFileName,
                newerProjectName: upstreamChangedProject
            };
        }
        // Up to date
        return {
            type: pseudoUpToDate ? ts.UpToDateStatusType.UpToDateWithUpstreamTypes : ts.UpToDateStatusType.UpToDate,
            newestDeclarationFileContentChangedTime: newestDeclarationFileContentChangedTime,
            newestInputFileTime: newestInputFileTime,
            newestOutputFileTime: newestOutputFileTime,
            newestInputFileName: newestInputFileName,
            newestOutputFileName: newestOutputFileName,
            oldestOutputFileName: oldestOutputFileName
        };
    }
    function getUpToDateStatus(state, project, resolvedPath) {
        if (project === undefined) {
            return { type: ts.UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" };
        }
        var prior = state.projectStatus.get(resolvedPath);
        if (prior !== undefined) {
            return prior;
        }
        var actual = getUpToDateStatusWorker(state, project, resolvedPath);
        state.projectStatus.set(resolvedPath, actual);
        return actual;
    }
    function updateOutputTimestampsWorker(state, proj, priorNewestUpdateTime, verboseMessage, skipOutputs) {
        var host = state.host;
        var outputs = ts.getAllProjectOutputs(proj, !host.useCaseSensitiveFileNames());
        if (!skipOutputs || outputs.length !== skipOutputs.size) {
            var reportVerbose = !!state.options.verbose;
            var now = host.now ? host.now() : new Date();
            for (var _i = 0, outputs_2 = outputs; _i < outputs_2.length; _i++) {
                var file = outputs_2[_i];
                if (skipOutputs && skipOutputs.has(toPath(state, file))) {
                    continue;
                }
                if (reportVerbose) {
                    reportVerbose = false;
                    reportStatus(state, verboseMessage, proj.options.configFilePath);
                }
                if (isDeclarationFile(file)) {
                    priorNewestUpdateTime = newer(priorNewestUpdateTime, host.getModifiedTime(file) || ts.missingFileModifiedTime);
                }
                host.setModifiedTime(file, now);
            }
        }
        return priorNewestUpdateTime;
    }
    function updateOutputTimestamps(state, proj, resolvedPath) {
        if (state.options.dry) {
            return reportStatus(state, ts.Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath);
        }
        var priorNewestUpdateTime = updateOutputTimestampsWorker(state, proj, minimumDate, ts.Diagnostics.Updating_output_timestamps_of_project_0);
        state.projectStatus.set(resolvedPath, {
            type: ts.UpToDateStatusType.UpToDate,
            newestDeclarationFileContentChangedTime: priorNewestUpdateTime,
            oldestOutputFileName: ts.getFirstProjectOutput(proj, !state.host.useCaseSensitiveFileNames())
        });
    }
    function queueReferencingProjects(state, project, projectPath, projectIndex, config, buildOrder, buildResult) {
        // Queue only if there are no errors
        if (buildResult & BuildResultFlags.AnyErrors)
            return;
        // Only composite projects can be referenced by other projects
        if (!config.options.composite)
            return;
        // Always use build order to queue projects
        for (var index = projectIndex + 1; index < buildOrder.length; index++) {
            var nextProject = buildOrder[index];
            var nextProjectPath = toResolvedConfigFilePath(state, nextProject);
            if (state.projectPendingBuild.has(nextProjectPath))
                continue;
            var nextProjectConfig = parseConfigFile(state, nextProject, nextProjectPath);
            if (!nextProjectConfig || !nextProjectConfig.projectReferences)
                continue;
            for (var _i = 0, _a = nextProjectConfig.projectReferences; _i < _a.length; _i++) {
                var ref = _a[_i];
                var resolvedRefPath = resolveProjectName(state, ref.path);
                if (toResolvedConfigFilePath(state, resolvedRefPath) !== projectPath)
                    continue;
                // If the project is referenced with prepend, always build downstream projects,
                // If declaration output is changed, build the project
                // otherwise mark the project UpToDateWithUpstreamTypes so it updates output time stamps
                var status = state.projectStatus.get(nextProjectPath);
                if (status) {
                    switch (status.type) {
                        case ts.UpToDateStatusType.UpToDate:
                            if (buildResult & BuildResultFlags.DeclarationOutputUnchanged) {
                                if (ref.prepend) {
                                    state.projectStatus.set(nextProjectPath, {
                                        type: ts.UpToDateStatusType.OutOfDateWithPrepend,
                                        outOfDateOutputFileName: status.oldestOutputFileName,
                                        newerProjectName: project
                                    });
                                }
                                else {
                                    status.type = ts.UpToDateStatusType.UpToDateWithUpstreamTypes;
                                }
                                break;
                            }
                        // falls through
                        case ts.UpToDateStatusType.UpToDateWithUpstreamTypes:
                        case ts.UpToDateStatusType.OutOfDateWithPrepend:
                            if (!(buildResult & BuildResultFlags.DeclarationOutputUnchanged)) {
                                state.projectStatus.set(nextProjectPath, {
                                    type: ts.UpToDateStatusType.OutOfDateWithUpstream,
                                    outOfDateOutputFileName: status.type === ts.UpToDateStatusType.OutOfDateWithPrepend ? status.outOfDateOutputFileName : status.oldestOutputFileName,
                                    newerProjectName: project
                                });
                            }
                            break;
                        case ts.UpToDateStatusType.UpstreamBlocked:
                            if (toResolvedConfigFilePath(state, resolveProjectName(state, status.upstreamProjectName)) === projectPath) {
                                clearProjectStatus(state, nextProjectPath);
                            }
                            break;
                    }
                }
                addProjToQueue(state, nextProjectPath, ts.ConfigFileProgramReloadLevel.None);
                break;
            }
        }
    }
    function build(state, project, cancellationToken, onlyReferences) {
        var buildOrder = getBuildOrderFor(state, project, onlyReferences);
        if (!buildOrder)
            return ts.ExitStatus.InvalidProject_OutputsSkipped;
        setupInitialBuild(state, cancellationToken);
        var reportQueue = true;
        var successfulProjects = 0;
        while (true) {
            var invalidatedProject = getNextInvalidatedProject(state, buildOrder, reportQueue);
            if (!invalidatedProject)
                break;
            reportQueue = false;
            invalidatedProject.done(cancellationToken);
            if (!state.diagnostics.has(invalidatedProject.projectPath))
                successfulProjects++;
        }
        disableCache(state);
        reportErrorSummary(state, buildOrder);
        startWatching(state, buildOrder);
        return isCircularBuildOrder(buildOrder)
            ? ts.ExitStatus.ProjectReferenceCycle_OutputsSkipped
            : !buildOrder.some(function (p) { return state.diagnostics.has(toResolvedConfigFilePath(state, p)); })
                ? ts.ExitStatus.Success
                : successfulProjects
                    ? ts.ExitStatus.DiagnosticsPresent_OutputsGenerated
                    : ts.ExitStatus.DiagnosticsPresent_OutputsSkipped;
    }
    function clean(state, project, onlyReferences) {
        var buildOrder = getBuildOrderFor(state, project, onlyReferences);
        if (!buildOrder)
            return ts.ExitStatus.InvalidProject_OutputsSkipped;
        if (isCircularBuildOrder(buildOrder)) {
            reportErrors(state, buildOrder.circularDiagnostics);
            return ts.ExitStatus.ProjectReferenceCycle_OutputsSkipped;
        }
        var options = state.options, host = state.host;
        var filesToDelete = options.dry ? [] : undefined;
        for (var _i = 0, buildOrder_1 = buildOrder; _i < buildOrder_1.length; _i++) {
            var proj = buildOrder_1[_i];
            var resolvedPath = toResolvedConfigFilePath(state, proj);
            var parsed = parseConfigFile(state, proj, resolvedPath);
            if (parsed === undefined) {
                // File has gone missing; fine to ignore here
                reportParseConfigFileDiagnostic(state, resolvedPath);
                continue;
            }
            var outputs = ts.getAllProjectOutputs(parsed, !host.useCaseSensitiveFileNames());
            for (var _a = 0, outputs_3 = outputs; _a < outputs_3.length; _a++) {
                var output = outputs_3[_a];
                if (host.fileExists(output)) {
                    if (filesToDelete) {
                        filesToDelete.push(output);
                    }
                    else {
                        host.deleteFile(output);
                        invalidateProject(state, resolvedPath, ts.ConfigFileProgramReloadLevel.None);
                    }
                }
            }
        }
        if (filesToDelete) {
            reportStatus(state, ts.Diagnostics.A_non_dry_build_would_delete_the_following_files_Colon_0, filesToDelete.map(function (f) { return "\r\n * " + f; }).join(""));
        }
        return ts.ExitStatus.Success;
    }
    function invalidateProject(state, resolved, reloadLevel) {
        // If host implements getParsedCommandLine, we cant get list of files from parseConfigFileHost
        if (state.host.getParsedCommandLine && reloadLevel === ts.ConfigFileProgramReloadLevel.Partial) {
            reloadLevel = ts.ConfigFileProgramReloadLevel.Full;
        }
        if (reloadLevel === ts.ConfigFileProgramReloadLevel.Full) {
            state.configFileCache.delete(resolved);
            state.buildOrder = undefined;
        }
        state.needsSummary = true;
        clearProjectStatus(state, resolved);
        addProjToQueue(state, resolved, reloadLevel);
        enableCache(state);
    }
    function invalidateProjectAndScheduleBuilds(state, resolvedPath, reloadLevel) {
        state.reportFileChangeDetected = true;
        invalidateProject(state, resolvedPath, reloadLevel);
        scheduleBuildInvalidatedProject(state);
    }
    function scheduleBuildInvalidatedProject(state) {
        var hostWithWatch = state.hostWithWatch;
        if (!hostWithWatch.setTimeout || !hostWithWatch.clearTimeout) {
            return;
        }
        if (state.timerToBuildInvalidatedProject) {
            hostWithWatch.clearTimeout(state.timerToBuildInvalidatedProject);
        }
        state.timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildNextInvalidatedProject, 250, state);
    }
    function buildNextInvalidatedProject(state) {
        state.timerToBuildInvalidatedProject = undefined;
        if (state.reportFileChangeDetected) {
            state.reportFileChangeDetected = false;
            state.projectErrorsReported.clear();
            reportWatchStatus(state, ts.Diagnostics.File_change_detected_Starting_incremental_compilation);
        }
        var buildOrder = getBuildOrder(state);
        var invalidatedProject = getNextInvalidatedProject(state, buildOrder, /*reportQueue*/ false);
        if (invalidatedProject) {
            invalidatedProject.done();
            if (state.projectPendingBuild.size) {
                // Schedule next project for build
                if (state.watch && !state.timerToBuildInvalidatedProject) {
                    scheduleBuildInvalidatedProject(state);
                }
                return;
            }
        }
        disableCache(state);
        reportErrorSummary(state, buildOrder);
    }
    function watchConfigFile(state, resolved, resolvedPath, parsed) {
        if (!state.watch || state.allWatchedConfigFiles.has(resolvedPath))
            return;
        state.allWatchedConfigFiles.set(resolvedPath, state.watchFile(state.hostWithWatch, resolved, function () {
            invalidateProjectAndScheduleBuilds(state, resolvedPath, ts.ConfigFileProgramReloadLevel.Full);
        }, ts.PollingInterval.High, parsed === null || parsed === void 0 ? void 0 : parsed.watchOptions, ts.WatchType.ConfigFile, resolved));
    }
    function isSameFile(state, file1, file2) {
        return ts.comparePaths(file1, file2, state.currentDirectory, !state.host.useCaseSensitiveFileNames()) === 0 /* EqualTo */;
    }
    function isOutputFile(state, fileName, configFile) {
        if (configFile.options.noEmit)
            return false;
        // ts or tsx files are not output
        if (!ts.fileExtensionIs(fileName, ".d.ts" /* Dts */) &&
            (ts.fileExtensionIs(fileName, ".ts" /* Ts */) || ts.fileExtensionIs(fileName, ".tsx" /* Tsx */))) {
            return false;
        }
        // If options have --outFile or --out, check if its that
        var out = configFile.options.outFile || configFile.options.out;
        if (out && (isSameFile(state, fileName, out) || isSameFile(state, fileName, ts.removeFileExtension(out) + ".d.ts" /* Dts */))) {
            return true;
        }
        // If declarationDir is specified, return if its a file in that directory
        if (configFile.options.declarationDir && ts.containsPath(configFile.options.declarationDir, fileName, state.currentDirectory, !state.host.useCaseSensitiveFileNames())) {
            return true;
        }
        // If --outDir, check if file is in that directory
        if (configFile.options.outDir && ts.containsPath(configFile.options.outDir, fileName, state.currentDirectory, !state.host.useCaseSensitiveFileNames())) {
            return true;
        }
        return !ts.forEach(configFile.fileNames, function (inputFile) { return isSameFile(state, fileName, inputFile); });
    }
    function watchWildCardDirectories(state, resolved, resolvedPath, parsed) {
        if (!state.watch)
            return;
        ts.updateWatchingWildcardDirectories(getOrCreateValueMapFromConfigFileMap(state.allWatchedWildcardDirectories, resolvedPath), ts.createMapFromTemplate(parsed.configFileSpecs.wildcardDirectories), function (dir, flags) { return state.watchDirectory(state.hostWithWatch, dir, function (fileOrDirectory) {
            var fileOrDirectoryPath = toPath(state, fileOrDirectory);
            if (fileOrDirectoryPath !== toPath(state, dir) && ts.hasExtension(fileOrDirectoryPath) && !ts.isSupportedSourceFileName(fileOrDirectory, parsed.options)) {
                state.writeLog("Project: " + resolved + " Detected file add/remove of non supported extension: " + fileOrDirectory);
                return;
            }
            if (isOutputFile(state, fileOrDirectory, parsed)) {
                state.writeLog(fileOrDirectory + " is output file");
                return;
            }
            invalidateProjectAndScheduleBuilds(state, resolvedPath, ts.ConfigFileProgramReloadLevel.Partial);
        }, flags, parsed === null || parsed === void 0 ? void 0 : parsed.watchOptions, ts.WatchType.WildcardDirectory, resolved); });
    }
    function watchInputFiles(state, resolved, resolvedPath, parsed) {
        if (!state.watch)
            return;
        ts.mutateMap(getOrCreateValueMapFromConfigFileMap(state.allWatchedInputFiles, resolvedPath), ts.arrayToMap(parsed.fileNames, function (fileName) { return toPath(state, fileName); }), {
            createNewValue: function (path, input) { return state.watchFilePath(state.hostWithWatch, input, function () { return invalidateProjectAndScheduleBuilds(state, resolvedPath, ts.ConfigFileProgramReloadLevel.None); }, ts.PollingInterval.Low, parsed === null || parsed === void 0 ? void 0 : parsed.watchOptions, path, ts.WatchType.SourceFile, resolved); },
            onDeleteValue: ts.closeFileWatcher,
        });
    }
    function startWatching(state, buildOrder) {
        if (!state.watchAllProjectsPending)
            return;
        state.watchAllProjectsPending = false;
        for (var _i = 0, _a = getBuildOrderFromAnyBuildOrder(buildOrder); _i < _a.length; _i++) {
            var resolved = _a[_i];
            var resolvedPath = toResolvedConfigFilePath(state, resolved);
            var cfg = parseConfigFile(state, resolved, resolvedPath);
            // Watch this file
            watchConfigFile(state, resolved, resolvedPath, cfg);
            if (cfg) {
                // Update watchers for wildcard directories
                watchWildCardDirectories(state, resolved, resolvedPath, cfg);
                // Watch input files
                watchInputFiles(state, resolved, resolvedPath, cfg);
            }
        }
    }
    function stopWatching(state) {
        ts.clearMap(state.allWatchedConfigFiles, ts.closeFileWatcher);
        ts.clearMap(state.allWatchedWildcardDirectories, function (watchedWildcardDirectories) { return ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcherOf); });
        ts.clearMap(state.allWatchedInputFiles, function (watchedWildcardDirectories) { return ts.clearMap(watchedWildcardDirectories, ts.closeFileWatcher); });
    }
    function createSolutionBuilderWorker(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions) {
        var state = createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options, baseWatchOptions);
        return {
            build: function (project, cancellationToken) { return build(state, project, cancellationToken); },
            clean: function (project) { return clean(state, project); },
            buildReferences: function (project, cancellationToken) { return build(state, project, cancellationToken, /*onlyReferences*/ true); },
            cleanReferences: function (project) { return clean(state, project, /*onlyReferences*/ true); },
            getNextInvalidatedProject: function (cancellationToken) {
                setupInitialBuild(state, cancellationToken);
                return getNextInvalidatedProject(state, getBuildOrder(state), /*reportQueue*/ false);
            },
            getBuildOrder: function () { return getBuildOrder(state); },
            getUpToDateStatusOfProject: function (project) {
                var configFileName = resolveProjectName(state, project);
                var configFilePath = toResolvedConfigFilePath(state, configFileName);
                return getUpToDateStatus(state, parseConfigFile(state, configFileName, configFilePath), configFilePath);
            },
            invalidateProject: function (configFilePath, reloadLevel) { return invalidateProject(state, configFilePath, reloadLevel || ts.ConfigFileProgramReloadLevel.None); },
            buildNextInvalidatedProject: function () { return buildNextInvalidatedProject(state); },
            getAllParsedConfigs: function () { return ts.arrayFrom(ts.mapDefinedIterator(state.configFileCache.values(), function (config) { return isParsedCommandLine(config) ? config : undefined; })); },
            close: function () { return stopWatching(state); },
        };
    }
    function relName(state, path) {
        return ts.convertToRelativePath(path, state.currentDirectory, function (f) { return state.getCanonicalFileName(f); });
    }
    function reportStatus(state, message) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        state.host.reportSolutionBuilderStatus(ts.createCompilerDiagnostic.apply(void 0, __spreadArrays([message], args)));
    }
    function reportWatchStatus(state, message) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        if (state.hostWithWatch.onWatchStatusChange) {
            state.hostWithWatch.onWatchStatusChange(ts.createCompilerDiagnostic.apply(void 0, __spreadArrays([message], args)), state.host.getNewLine(), state.baseCompilerOptions);
        }
    }
    function reportErrors(_a, errors) {
        var host = _a.host;
        errors.forEach(function (err) { return host.reportDiagnostic(err); });
    }
    function reportAndStoreErrors(state, proj, errors) {
        reportErrors(state, errors);
        state.projectErrorsReported.set(proj, true);
        if (errors.length) {
            state.diagnostics.set(proj, errors);
        }
    }
    function reportParseConfigFileDiagnostic(state, proj) {
        reportAndStoreErrors(state, proj, [state.configFileCache.get(proj)]);
    }
    function reportErrorSummary(state, buildOrder) {
        if (!state.needsSummary)
            return;
        state.needsSummary = false;
        var canReportSummary = state.watch || !!state.host.reportErrorSummary;
        var diagnostics = state.diagnostics;
        var totalErrors = 0;
        if (isCircularBuildOrder(buildOrder)) {
            reportBuildQueue(state, buildOrder.buildOrder);
            reportErrors(state, buildOrder.circularDiagnostics);
            if (canReportSummary)
                totalErrors += ts.getErrorCountForSummary(buildOrder.circularDiagnostics);
        }
        else {
            // Report errors from the other projects
            buildOrder.forEach(function (project) {
                var projectPath = toResolvedConfigFilePath(state, project);
                if (!state.projectErrorsReported.has(projectPath)) {
                    reportErrors(state, diagnostics.get(projectPath) || ts.emptyArray);
                }
            });
            if (canReportSummary)
                diagnostics.forEach(function (singleProjectErrors) { return totalErrors += ts.getErrorCountForSummary(singleProjectErrors); });
        }
        if (state.watch) {
            reportWatchStatus(state, ts.getWatchErrorSummaryDiagnosticMessage(totalErrors), totalErrors);
        }
        else if (state.host.reportErrorSummary) {
            state.host.reportErrorSummary(totalErrors);
        }
    }
    /**
     * Report the build ordering inferred from the current project graph if we're in verbose mode
     */
    function reportBuildQueue(state, buildQueue) {
        if (state.options.verbose) {
            reportStatus(state, ts.Diagnostics.Projects_in_this_build_Colon_0, buildQueue.map(function (s) { return "\r\n    * " + relName(state, s); }).join(""));
        }
    }
    function reportUpToDateStatus(state, configFileName, status) {
        switch (status.type) {
            case ts.UpToDateStatusType.OutOfDateWithSelf:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relName(state, configFileName), relName(state, status.outOfDateOutputFileName), relName(state, status.newerInputFileName));
            case ts.UpToDateStatusType.OutOfDateWithUpstream:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, relName(state, configFileName), relName(state, status.outOfDateOutputFileName), relName(state, status.newerProjectName));
            case ts.UpToDateStatusType.OutputMissing:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, relName(state, configFileName), relName(state, status.missingOutputFileName));
            case ts.UpToDateStatusType.UpToDate:
                if (status.newestInputFileTime !== undefined) {
                    return reportStatus(state, ts.Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, relName(state, configFileName), relName(state, status.newestInputFileName || ""), relName(state, status.oldestOutputFileName || ""));
                }
                // Don't report anything for "up to date because it was already built" -- too verbose
                break;
            case ts.UpToDateStatusType.OutOfDateWithPrepend:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_output_of_its_dependency_1_has_changed, relName(state, configFileName), relName(state, status.newerProjectName));
            case ts.UpToDateStatusType.UpToDateWithUpstreamTypes:
                return reportStatus(state, ts.Diagnostics.Project_0_is_up_to_date_with_d_ts_files_from_its_dependencies, relName(state, configFileName));
            case ts.UpToDateStatusType.UpstreamOutOfDate:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_its_dependency_1_is_out_of_date, relName(state, configFileName), relName(state, status.upstreamProjectName));
            case ts.UpToDateStatusType.UpstreamBlocked:
                return reportStatus(state, status.upstreamProjectBlocked ?
                    ts.Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_was_not_built :
                    ts.Diagnostics.Project_0_can_t_be_built_because_its_dependency_1_has_errors, relName(state, configFileName), relName(state, status.upstreamProjectName));
            case ts.UpToDateStatusType.Unbuildable:
                return reportStatus(state, ts.Diagnostics.Failed_to_parse_file_0_Colon_1, relName(state, configFileName), status.reason);
            case ts.UpToDateStatusType.TsVersionOutputOfDate:
                return reportStatus(state, ts.Diagnostics.Project_0_is_out_of_date_because_output_for_it_was_generated_with_version_1_that_differs_with_current_version_2, relName(state, configFileName), status.version, ts.version);
            case ts.UpToDateStatusType.ContainerOnly:
            // Don't report status on "solution" projects
            // falls through
            case ts.UpToDateStatusType.ComputingUpstream:
                // Should never leak from getUptoDateStatusWorker
                break;
            default:
                ts.assertType(status);
        }
    }
    /**
     * Report the up-to-date status of a project if we're in verbose mode
     */
    function verboseReportProjectStatus(state, configFileName, status) {
        if (state.options.verbose) {
            reportUpToDateStatus(state, configFileName, status);
        }
    }
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        /* @internal */
        server.ActionSet = "action::set";
        /* @internal */
        server.ActionInvalidate = "action::invalidate";
        /* @internal */
        server.ActionPackageInstalled = "action::packageInstalled";
        /* @internal */
        server.EventTypesRegistry = "event::typesRegistry";
        /* @internal */
        server.EventBeginInstallTypes = "event::beginInstallTypes";
        /* @internal */
        server.EventEndInstallTypes = "event::endInstallTypes";
        /* @internal */
        server.EventInitializationFailed = "event::initializationFailed";
        /* @internal */
        var Arguments;
        (function (Arguments) {
            Arguments.GlobalCacheLocation = "--globalTypingsCacheLocation";
            Arguments.LogFile = "--logFile";
            Arguments.EnableTelemetry = "--enableTelemetry";
            Arguments.TypingSafeListLocation = "--typingSafeListLocation";
            Arguments.TypesMapLocation = "--typesMapLocation";
            /**
             * This argument specifies the location of the NPM executable.
             * typingsInstaller will run the command with `${npmLocation} install ...`.
             */
            Arguments.NpmLocation = "--npmLocation";
            /**
             * Flag indicating that the typings installer should try to validate the default npm location.
             * If the default npm is not found when this flag is enabled, fallback to `npm install`
             */
            Arguments.ValidateDefaultNpmLocation = "--validateDefaultNpmLocation";
        })(Arguments = server.Arguments || (server.Arguments = {}));
        /* @internal */
        function hasArgument(argumentName) {
            return ts.sys.args.indexOf(argumentName) >= 0;
        }
        server.hasArgument = hasArgument;
        /* @internal */
        function findArgument(argumentName) {
            var index = ts.sys.args.indexOf(argumentName);
            return index >= 0 && index < ts.sys.args.length - 1
                ? ts.sys.args[index + 1]
                : undefined;
        }
        server.findArgument = findArgument;
        /* @internal */
        function nowString() {
            // E.g. "12:34:56.789"
            var d = new Date();
            return d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds() + "." + d.getMilliseconds();
        }
        server.nowString = nowString;
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
/* @internal */
var ts;
(function (ts) {
    var JsTyping;
    (function (JsTyping) {
        function isTypingUpToDate(cachedTyping, availableTypingVersions) {
            var availableVersion = new ts.Version(ts.getProperty(availableTypingVersions, "ts" + ts.versionMajorMinor) || ts.getProperty(availableTypingVersions, "latest"));
            return availableVersion.compareTo(cachedTyping.version) <= 0;
        }
        JsTyping.isTypingUpToDate = isTypingUpToDate;
        JsTyping.nodeCoreModuleList = [
            "assert",
            "async_hooks",
            "buffer",
            "child_process",
            "cluster",
            "console",
            "constants",
            "crypto",
            "dgram",
            "dns",
            "domain",
            "events",
            "fs",
            "http",
            "https",
            "http2",
            "inspector",
            "net",
            "os",
            "path",
            "perf_hooks",
            "process",
            "punycode",
            "querystring",
            "readline",
            "repl",
            "stream",
            "string_decoder",
            "timers",
            "tls",
            "tty",
            "url",
            "util",
            "v8",
            "vm",
            "zlib"
        ];
        JsTyping.nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList);
        function nonRelativeModuleNameForTypingCache(moduleName) {
            return JsTyping.nodeCoreModules.has(moduleName) ? "node" : moduleName;
        }
        JsTyping.nonRelativeModuleNameForTypingCache = nonRelativeModuleNameForTypingCache;
        function loadSafeList(host, safeListPath) {
            var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); });
            return ts.createMapFromTemplate(result.config);
        }
        JsTyping.loadSafeList = loadSafeList;
        function loadTypesMap(host, typesMapPath) {
            var result = ts.readConfigFile(typesMapPath, function (path) { return host.readFile(path); });
            if (result.config) {
                return ts.createMapFromTemplate(result.config.simpleMap);
            }
            return undefined;
        }
        JsTyping.loadTypesMap = loadTypesMap;
        /**
         * @param host is the object providing I/O related operations.
         * @param fileNames are the file names that belong to the same project
         * @param projectRootPath is the path to the project root directory
         * @param safeListPath is the path used to retrieve the safe list
         * @param packageNameToTypingLocation is the map of package names to their cached typing locations and installed versions
         * @param typeAcquisition is used to customize the typing acquisition process
         * @param compilerOptions are used as a source for typing inference
         */
        function discoverTypings(host, log, fileNames, projectRootPath, safeList, packageNameToTypingLocation, typeAcquisition, unresolvedImports, typesRegistry) {
            if (!typeAcquisition || !typeAcquisition.enable) {
                return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] };
            }
            // A typing name to typing file path mapping
            var inferredTypings = ts.createMap();
            // Only infer typings for .js and .jsx files
            fileNames = ts.mapDefined(fileNames, function (fileName) {
                var path = ts.normalizePath(fileName);
                if (ts.hasJSFileExtension(path)) {
                    return path;
                }
            });
            var filesToWatch = [];
            if (typeAcquisition.include)
                addInferredTypings(typeAcquisition.include, "Explicitly included types");
            var exclude = typeAcquisition.exclude || [];
            // Directories to search for package.json, bower.json and other typing information
            var possibleSearchDirs = ts.arrayToSet(fileNames, ts.getDirectoryPath);
            possibleSearchDirs.set(projectRootPath, true);
            possibleSearchDirs.forEach(function (_true, searchDir) {
                var packageJsonPath = ts.combinePaths(searchDir, "package.json");
                getTypingNamesFromJson(packageJsonPath, filesToWatch);
                var bowerJsonPath = ts.combinePaths(searchDir, "bower.json");
                getTypingNamesFromJson(bowerJsonPath, filesToWatch);
                var bowerComponentsPath = ts.combinePaths(searchDir, "bower_components");
                getTypingNamesFromPackagesFolder(bowerComponentsPath, filesToWatch);
                var nodeModulesPath = ts.combinePaths(searchDir, "node_modules");
                getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch);
            });
            getTypingNamesFromSourceFileNames(fileNames);
            // add typings for unresolved imports
            if (unresolvedImports) {
                var module_1 = ts.deduplicate(unresolvedImports.map(nonRelativeModuleNameForTypingCache), ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive);
                addInferredTypings(module_1, "Inferred typings from unresolved imports");
            }
            // Add the cached typing locations for inferred typings that are already installed
            packageNameToTypingLocation.forEach(function (typing, name) {
                var registryEntry = typesRegistry.get(name);
                if (inferredTypings.has(name) && inferredTypings.get(name) === undefined && registryEntry !== undefined && isTypingUpToDate(typing, registryEntry)) {
                    inferredTypings.set(name, typing.typingLocation);
                }
            });
            // Remove typings that the user has added to the exclude list
            for (var _i = 0, exclude_1 = exclude; _i < exclude_1.length; _i++) {
                var excludeTypingName = exclude_1[_i];
                var didDelete = inferredTypings.delete(excludeTypingName);
                if (didDelete && log)
                    log("Typing for " + excludeTypingName + " is in exclude list, will be ignored.");
            }
            var newTypingNames = [];
            var cachedTypingPaths = [];
            inferredTypings.forEach(function (inferred, typing) {
                if (inferred !== undefined) {
                    cachedTypingPaths.push(inferred);
                }
                else {
                    newTypingNames.push(typing);
                }
            });
            var result = { cachedTypingPaths: cachedTypingPaths, newTypingNames: newTypingNames, filesToWatch: filesToWatch };
            if (log)
                log("Result: " + JSON.stringify(result));
            return result;
            function addInferredTyping(typingName) {
                if (!inferredTypings.has(typingName)) {
                    inferredTypings.set(typingName, undefined); // TODO: GH#18217
                }
            }
            function addInferredTypings(typingNames, message) {
                if (log)
                    log(message + ": " + JSON.stringify(typingNames));
                ts.forEach(typingNames, addInferredTyping);
            }
            /**
             * Get the typing info from common package manager json files like package.json or bower.json
             */
            function getTypingNamesFromJson(jsonPath, filesToWatch) {
                if (!host.fileExists(jsonPath)) {
                    return;
                }
                filesToWatch.push(jsonPath);
                var jsonConfig = ts.readConfigFile(jsonPath, function (path) { return host.readFile(path); }).config;
                var jsonTypingNames = ts.flatMap([jsonConfig.dependencies, jsonConfig.devDependencies, jsonConfig.optionalDependencies, jsonConfig.peerDependencies], ts.getOwnKeys);
                addInferredTypings(jsonTypingNames, "Typing names in '" + jsonPath + "' dependencies");
            }
            /**
             * Infer typing names from given file names. For example, the file name "jquery-min.2.3.4.js"
             * should be inferred to the 'jquery' typing name; and "angular-route.1.2.3.js" should be inferred
             * to the 'angular-route' typing name.
             * @param fileNames are the names for source files in the project
             */
            function getTypingNamesFromSourceFileNames(fileNames) {
                var fromFileNames = ts.mapDefined(fileNames, function (j) {
                    if (!ts.hasJSFileExtension(j))
                        return undefined;
                    var inferredTypingName = ts.removeFileExtension(ts.getBaseFileName(j.toLowerCase()));
                    var cleanedTypingName = ts.removeMinAndVersionNumbers(inferredTypingName);
                    return safeList.get(cleanedTypingName);
                });
                if (fromFileNames.length) {
                    addInferredTypings(fromFileNames, "Inferred typings from file names");
                }
                var hasJsxFile = ts.some(fileNames, function (f) { return ts.fileExtensionIs(f, ".jsx" /* Jsx */); });
                if (hasJsxFile) {
                    if (log)
                        log("Inferred 'react' typings due to presence of '.jsx' extension");
                    addInferredTyping("react");
                }
            }
            /**
             * Infer typing names from packages folder (ex: node_module, bower_components)
             * @param packagesFolderPath is the path to the packages folder
             */
            function getTypingNamesFromPackagesFolder(packagesFolderPath, filesToWatch) {
                filesToWatch.push(packagesFolderPath);
                // Todo: add support for ModuleResolutionHost too
                if (!host.directoryExists(packagesFolderPath)) {
                    return;
                }
                // depth of 2, so we access `node_modules/foo` but not `node_modules/foo/bar`
                var fileNames = host.readDirectory(packagesFolderPath, [".json" /* Json */], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2);
                if (log)
                    log("Searching for typing names in " + packagesFolderPath + "; all files: " + JSON.stringify(fileNames));
                var packageNames = [];
                for (var _i = 0, fileNames_1 = fileNames; _i < fileNames_1.length; _i++) {
                    var fileName = fileNames_1[_i];
                    var normalizedFileName = ts.normalizePath(fileName);
                    var baseFileName = ts.getBaseFileName(normalizedFileName);
                    if (baseFileName !== "package.json" && baseFileName !== "bower.json") {
                        continue;
                    }
                    var result_1 = ts.readConfigFile(normalizedFileName, function (path) { return host.readFile(path); });
                    var packageJson = result_1.config;
                    // npm 3's package.json contains a "_requiredBy" field
                    // we should include all the top level module names for npm 2, and only module names whose
                    // "_requiredBy" field starts with "#" or equals "/" for npm 3.
                    if (baseFileName === "package.json" && packageJson._requiredBy &&
                        ts.filter(packageJson._requiredBy, function (r) { return r[0] === "#" || r === "/"; }).length === 0) {
                        continue;
                    }
                    // If the package has its own d.ts typings, those will take precedence. Otherwise the package name will be used
                    // to download d.ts files from DefinitelyTyped
                    if (!packageJson.name) {
                        continue;
                    }
                    var ownTypes = packageJson.types || packageJson.typings;
                    if (ownTypes) {
                        var absolutePath = ts.getNormalizedAbsolutePath(ownTypes, ts.getDirectoryPath(normalizedFileName));
                        if (log)
                            log("    Package '" + packageJson.name + "' provides its own types.");
                        inferredTypings.set(packageJson.name, absolutePath);
                    }
                    else {
                        packageNames.push(packageJson.name);
                    }
                }
                addInferredTypings(packageNames, "    Found package names");
            }
        }
        JsTyping.discoverTypings = discoverTypings;
        var NameValidationResult;
        (function (NameValidationResult) {
            NameValidationResult[NameValidationResult["Ok"] = 0] = "Ok";
            NameValidationResult[NameValidationResult["EmptyName"] = 1] = "EmptyName";
            NameValidationResult[NameValidationResult["NameTooLong"] = 2] = "NameTooLong";
            NameValidationResult[NameValidationResult["NameStartsWithDot"] = 3] = "NameStartsWithDot";
            NameValidationResult[NameValidationResult["NameStartsWithUnderscore"] = 4] = "NameStartsWithUnderscore";
            NameValidationResult[NameValidationResult["NameContainsNonURISafeCharacters"] = 5] = "NameContainsNonURISafeCharacters";
        })(NameValidationResult = JsTyping.NameValidationResult || (JsTyping.NameValidationResult = {}));
        var maxPackageNameLength = 214;
        /**
         * Validates package name using rules defined at https://docs.npmjs.com/files/package.json
         */
        function validatePackageName(packageName) {
            return validatePackageNameWorker(packageName, /*supportScopedPackage*/ true);
        }
        JsTyping.validatePackageName = validatePackageName;
        function validatePackageNameWorker(packageName, supportScopedPackage) {
            if (!packageName) {
                return 1 /* EmptyName */;
            }
            if (packageName.length > maxPackageNameLength) {
                return 2 /* NameTooLong */;
            }
            if (packageName.charCodeAt(0) === 46 /* dot */) {
                return 3 /* NameStartsWithDot */;
            }
            if (packageName.charCodeAt(0) === 95 /* _ */) {
                return 4 /* NameStartsWithUnderscore */;
            }
            // check if name is scope package like: starts with @ and has one '/' in the middle
            // scoped packages are not currently supported
            if (supportScopedPackage) {
                var matches = /^@([^/]+)\/([^/]+)$/.exec(packageName);
                if (matches) {
                    var scopeResult = validatePackageNameWorker(matches[1], /*supportScopedPackage*/ false);
                    if (scopeResult !== 0 /* Ok */) {
                        return { name: matches[1], isScopeName: true, result: scopeResult };
                    }
                    var packageResult = validatePackageNameWorker(matches[2], /*supportScopedPackage*/ false);
                    if (packageResult !== 0 /* Ok */) {
                        return { name: matches[2], isScopeName: false, result: packageResult };
                    }
                    return 0 /* Ok */;
                }
            }
            if (encodeURIComponent(packageName) !== packageName) {
                return 5 /* NameContainsNonURISafeCharacters */;
            }
            return 0 /* Ok */;
        }
        function renderPackageNameValidationFailure(result, typing) {
            return typeof result === "object" ?
                renderPackageNameValidationFailureWorker(typing, result.result, result.name, result.isScopeName) :
                renderPackageNameValidationFailureWorker(typing, result, typing, /*isScopeName*/ false);
        }
        JsTyping.renderPackageNameValidationFailure = renderPackageNameValidationFailure;
        function renderPackageNameValidationFailureWorker(typing, result, name, isScopeName) {
            var kind = isScopeName ? "Scope" : "Package";
            switch (result) {
                case 1 /* EmptyName */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' cannot be empty";
                case 2 /* NameTooLong */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' should be less than " + maxPackageNameLength + " characters";
                case 3 /* NameStartsWithDot */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' cannot start with '.'";
                case 4 /* NameStartsWithUnderscore */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' cannot start with '_'";
                case 5 /* NameContainsNonURISafeCharacters */:
                    return "'" + typing + "':: " + kind + " name '" + name + "' contains non URI safe characters";
                case 0 /* Ok */:
                    return ts.Debug.fail(); // Shouldn't have called this.
                default:
                    throw ts.Debug.assertNever(result);
            }
        }
    })(JsTyping = ts.JsTyping || (ts.JsTyping = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        var typingsInstaller;
        (function (typingsInstaller) {
            var nullLog = {
                isEnabled: function () { return false; },
                writeLine: ts.noop
            };
            function typingToFileName(cachePath, packageName, installTypingHost, log) {
                try {
                    var result = ts.resolveModuleName(packageName, ts.combinePaths(cachePath, "index.d.ts"), { moduleResolution: ts.ModuleResolutionKind.NodeJs }, installTypingHost);
                    return result.resolvedModule && result.resolvedModule.resolvedFileName;
                }
                catch (e) {
                    if (log.isEnabled()) {
                        log.writeLine("Failed to resolve " + packageName + " in folder '" + cachePath + "': " + e.message);
                    }
                    return undefined;
                }
            }
            /*@internal*/
            function installNpmPackages(npmPath, tsVersion, packageNames, install) {
                var hasError = false;
                for (var remaining = packageNames.length; remaining > 0;) {
                    var result = getNpmCommandForInstallation(npmPath, tsVersion, packageNames, remaining);
                    remaining = result.remaining;
                    hasError = install(result.command) || hasError;
                }
                return hasError;
            }
            typingsInstaller.installNpmPackages = installNpmPackages;
            /*@internal*/
            function getNpmCommandForInstallation(npmPath, tsVersion, packageNames, remaining) {
                var sliceStart = packageNames.length - remaining;
                var command, toSlice = remaining;
                while (true) {
                    command = npmPath + " install --ignore-scripts " + (toSlice === packageNames.length ? packageNames : packageNames.slice(sliceStart, sliceStart + toSlice)).join(" ") + " --save-dev --user-agent=\"typesInstaller/" + tsVersion + "\"";
                    if (command.length < 8000) {
                        break;
                    }
                    toSlice = toSlice - Math.floor(toSlice / 2);
                }
                return { command: command, remaining: remaining - toSlice };
            }
            typingsInstaller.getNpmCommandForInstallation = getNpmCommandForInstallation;
            function endsWith(str, suffix, caseSensitive) {
                var expectedPos = str.length - suffix.length;
                return expectedPos >= 0 &&
                    (str.indexOf(suffix, expectedPos) === expectedPos ||
                        (!caseSensitive && ts.compareStringsCaseInsensitive(str.substr(expectedPos), suffix) === 0 /* EqualTo */));
            }
            function isPackageOrBowerJson(fileName, caseSensitive) {
                return endsWith(fileName, "/package.json", caseSensitive) || endsWith(fileName, "/bower.json", caseSensitive);
            }
            function sameFiles(a, b, caseSensitive) {
                return a === b || (!caseSensitive && ts.compareStringsCaseInsensitive(a, b) === 0 /* EqualTo */);
            }
            var ProjectWatcherType;
            (function (ProjectWatcherType) {
                ProjectWatcherType["FileWatcher"] = "FileWatcher";
                ProjectWatcherType["DirectoryWatcher"] = "DirectoryWatcher";
            })(ProjectWatcherType || (ProjectWatcherType = {}));
            var TypingsInstaller = /** @class */ (function () {
                function TypingsInstaller(installTypingHost, globalCachePath, safeListPath, typesMapLocation, throttleLimit, log) {
                    if (log === void 0) { log = nullLog; }
                    this.installTypingHost = installTypingHost;
                    this.globalCachePath = globalCachePath;
                    this.safeListPath = safeListPath;
                    this.typesMapLocation = typesMapLocation;
                    this.throttleLimit = throttleLimit;
                    this.log = log;
                    this.packageNameToTypingLocation = ts.createMap();
                    this.missingTypingsSet = ts.createMap();
                    this.knownCachesSet = ts.createMap();
                    this.projectWatchers = ts.createMap();
                    this.pendingRunRequests = [];
                    this.installRunCount = 1;
                    this.inFlightRequestCount = 0;
                    this.latestDistTag = "latest";
                    this.toCanonicalFileName = ts.createGetCanonicalFileName(installTypingHost.useCaseSensitiveFileNames);
                    this.globalCachePackageJsonPath = ts.combinePaths(globalCachePath, "package.json");
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Global cache location '" + globalCachePath + "', safe file path '" + safeListPath + "', types map path " + typesMapLocation);
                    }
                    this.processCacheLocation(this.globalCachePath);
                }
                TypingsInstaller.prototype.closeProject = function (req) {
                    this.closeWatchers(req.projectName);
                };
                TypingsInstaller.prototype.closeWatchers = function (projectName) {
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Closing file watchers for project '" + projectName + "'");
                    }
                    var watchers = this.projectWatchers.get(projectName);
                    if (!watchers) {
                        if (this.log.isEnabled()) {
                            this.log.writeLine("No watchers are registered for project '" + projectName + "'");
                        }
                        return;
                    }
                    ts.clearMap(watchers, ts.closeFileWatcher);
                    this.projectWatchers.delete(projectName);
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Closing file watchers for project '" + projectName + "' - done.");
                    }
                };
                TypingsInstaller.prototype.install = function (req) {
                    var _this = this;
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Got install request " + JSON.stringify(req));
                    }
                    // load existing typing information from the cache
                    if (req.cachePath) {
                        if (this.log.isEnabled()) {
                            this.log.writeLine("Request specifies cache path '" + req.cachePath + "', loading cached information...");
                        }
                        this.processCacheLocation(req.cachePath);
                    }
                    if (this.safeList === undefined) {
                        this.initializeSafeList();
                    }
                    var discoverTypingsResult = ts.JsTyping.discoverTypings(this.installTypingHost, this.log.isEnabled() ? (function (s) { return _this.log.writeLine(s); }) : undefined, req.fileNames, req.projectRootPath, this.safeList, this.packageNameToTypingLocation, req.typeAcquisition, req.unresolvedImports, this.typesRegistry);
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Finished typings discovery: " + JSON.stringify(discoverTypingsResult));
                    }
                    // start watching files
                    this.watchFiles(req.projectName, discoverTypingsResult.filesToWatch, req.projectRootPath, req.watchOptions);
                    // install typings
                    if (discoverTypingsResult.newTypingNames.length) {
                        this.installTypings(req, req.cachePath || this.globalCachePath, discoverTypingsResult.cachedTypingPaths, discoverTypingsResult.newTypingNames);
                    }
                    else {
                        this.sendResponse(this.createSetTypings(req, discoverTypingsResult.cachedTypingPaths));
                        if (this.log.isEnabled()) {
                            this.log.writeLine("No new typings were requested as a result of typings discovery");
                        }
                    }
                };
                TypingsInstaller.prototype.initializeSafeList = function () {
                    // Prefer the safe list from the types map if it exists
                    if (this.typesMapLocation) {
                        var safeListFromMap = ts.JsTyping.loadTypesMap(this.installTypingHost, this.typesMapLocation);
                        if (safeListFromMap) {
                            this.log.writeLine("Loaded safelist from types map file '" + this.typesMapLocation + "'");
                            this.safeList = safeListFromMap;
                            return;
                        }
                        this.log.writeLine("Failed to load safelist from types map file '" + this.typesMapLocation + "'");
                    }
                    this.safeList = ts.JsTyping.loadSafeList(this.installTypingHost, this.safeListPath);
                };
                TypingsInstaller.prototype.processCacheLocation = function (cacheLocation) {
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Processing cache location '" + cacheLocation + "'");
                    }
                    if (this.knownCachesSet.has(cacheLocation)) {
                        if (this.log.isEnabled()) {
                            this.log.writeLine("Cache location was already processed...");
                        }
                        return;
                    }
                    var packageJson = ts.combinePaths(cacheLocation, "package.json");
                    var packageLockJson = ts.combinePaths(cacheLocation, "package-lock.json");
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Trying to find '" + packageJson + "'...");
                    }
                    if (this.installTypingHost.fileExists(packageJson) && this.installTypingHost.fileExists(packageLockJson)) {
                        var npmConfig = JSON.parse(this.installTypingHost.readFile(packageJson)); // TODO: GH#18217
                        var npmLock = JSON.parse(this.installTypingHost.readFile(packageLockJson)); // TODO: GH#18217
                        if (this.log.isEnabled()) {
                            this.log.writeLine("Loaded content of '" + packageJson + "': " + JSON.stringify(npmConfig));
                            this.log.writeLine("Loaded content of '" + packageLockJson + "'");
                        }
                        if (npmConfig.devDependencies && npmLock.dependencies) {
                            for (var key in npmConfig.devDependencies) {
                                if (!ts.hasProperty(npmLock.dependencies, key)) {
                                    // if package in package.json but not package-lock.json, skip adding to cache so it is reinstalled on next use
                                    continue;
                                }
                                // key is @types/<package name>
                                var packageName = ts.getBaseFileName(key);
                                if (!packageName) {
                                    continue;
                                }
                                var typingFile = typingToFileName(cacheLocation, packageName, this.installTypingHost, this.log);
                                if (!typingFile) {
                                    this.missingTypingsSet.set(packageName, true);
                                    continue;
                                }
                                var existingTypingFile = this.packageNameToTypingLocation.get(packageName);
                                if (existingTypingFile) {
                                    if (existingTypingFile.typingLocation === typingFile) {
                                        continue;
                                    }
                                    if (this.log.isEnabled()) {
                                        this.log.writeLine("New typing for package " + packageName + " from '" + typingFile + "' conflicts with existing typing file '" + existingTypingFile + "'");
                                    }
                                }
                                if (this.log.isEnabled()) {
                                    this.log.writeLine("Adding entry into typings cache: '" + packageName + "' => '" + typingFile + "'");
                                }
                                var info = ts.getProperty(npmLock.dependencies, key);
                                var version_1 = info && info.version;
                                if (!version_1) {
                                    continue;
                                }
                                var newTyping = { typingLocation: typingFile, version: new ts.Version(version_1) };
                                this.packageNameToTypingLocation.set(packageName, newTyping);
                            }
                        }
                    }
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Finished processing cache location '" + cacheLocation + "'");
                    }
                    this.knownCachesSet.set(cacheLocation, true);
                };
                TypingsInstaller.prototype.filterTypings = function (typingsToInstall) {
                    var _this = this;
                    return ts.mapDefined(typingsToInstall, function (typing) {
                        var typingKey = ts.mangleScopedPackageName(typing);
                        if (_this.missingTypingsSet.get(typingKey)) {
                            if (_this.log.isEnabled())
                                _this.log.writeLine("'" + typing + "':: '" + typingKey + "' is in missingTypingsSet - skipping...");
                            return undefined;
                        }
                        var validationResult = ts.JsTyping.validatePackageName(typing);
                        if (validationResult !== 0 /* Ok */) {
                            // add typing name to missing set so we won't process it again
                            _this.missingTypingsSet.set(typingKey, true);
                            if (_this.log.isEnabled())
                                _this.log.writeLine(ts.JsTyping.renderPackageNameValidationFailure(validationResult, typing));
                            return undefined;
                        }
                        if (!_this.typesRegistry.has(typingKey)) {
                            if (_this.log.isEnabled())
                                _this.log.writeLine("'" + typing + "':: Entry for package '" + typingKey + "' does not exist in local types registry - skipping...");
                            return undefined;
                        }
                        if (_this.packageNameToTypingLocation.get(typingKey) && ts.JsTyping.isTypingUpToDate(_this.packageNameToTypingLocation.get(typingKey), _this.typesRegistry.get(typingKey))) {
                            if (_this.log.isEnabled())
                                _this.log.writeLine("'" + typing + "':: '" + typingKey + "' already has an up-to-date typing - skipping...");
                            return undefined;
                        }
                        return typingKey;
                    });
                };
                TypingsInstaller.prototype.ensurePackageDirectoryExists = function (directory) {
                    var npmConfigPath = ts.combinePaths(directory, "package.json");
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Npm config file: " + npmConfigPath);
                    }
                    if (!this.installTypingHost.fileExists(npmConfigPath)) {
                        if (this.log.isEnabled()) {
                            this.log.writeLine("Npm config file: '" + npmConfigPath + "' is missing, creating new one...");
                        }
                        this.ensureDirectoryExists(directory, this.installTypingHost);
                        this.installTypingHost.writeFile(npmConfigPath, '{ "private": true }');
                    }
                };
                TypingsInstaller.prototype.installTypings = function (req, cachePath, currentlyCachedTypings, typingsToInstall) {
                    var _this = this;
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Installing typings " + JSON.stringify(typingsToInstall));
                    }
                    var filteredTypings = this.filterTypings(typingsToInstall);
                    if (filteredTypings.length === 0) {
                        if (this.log.isEnabled()) {
                            this.log.writeLine("All typings are known to be missing or invalid - no need to install more typings");
                        }
                        this.sendResponse(this.createSetTypings(req, currentlyCachedTypings));
                        return;
                    }
                    this.ensurePackageDirectoryExists(cachePath);
                    var requestId = this.installRunCount;
                    this.installRunCount++;
                    // send progress event
                    this.sendResponse({
                        kind: server.EventBeginInstallTypes,
                        eventId: requestId,
                        // qualified explicitly to prevent occasional shadowing
                        // eslint-disable-next-line @typescript-eslint/no-unnecessary-qualifier
                        typingsInstallerVersion: ts.version,
                        projectName: req.projectName
                    });
                    var scopedTypings = filteredTypings.map(typingsName);
                    this.installTypingsAsync(requestId, scopedTypings, cachePath, function (ok) {
                        try {
                            if (!ok) {
                                if (_this.log.isEnabled()) {
                                    _this.log.writeLine("install request failed, marking packages as missing to prevent repeated requests: " + JSON.stringify(filteredTypings));
                                }
                                for (var _i = 0, filteredTypings_1 = filteredTypings; _i < filteredTypings_1.length; _i++) {
                                    var typing = filteredTypings_1[_i];
                                    _this.missingTypingsSet.set(typing, true);
                                }
                                return;
                            }
                            // TODO: watch project directory
                            if (_this.log.isEnabled()) {
                                _this.log.writeLine("Installed typings " + JSON.stringify(scopedTypings));
                            }
                            var installedTypingFiles = [];
                            for (var _a = 0, filteredTypings_2 = filteredTypings; _a < filteredTypings_2.length; _a++) {
                                var packageName = filteredTypings_2[_a];
                                var typingFile = typingToFileName(cachePath, packageName, _this.installTypingHost, _this.log);
                                if (!typingFile) {
                                    _this.missingTypingsSet.set(packageName, true);
                                    continue;
                                }
                                // packageName is guaranteed to exist in typesRegistry by filterTypings
                                var distTags = _this.typesRegistry.get(packageName);
                                var newVersion = new ts.Version(distTags["ts" + ts.versionMajorMinor] || distTags[_this.latestDistTag]);
                                var newTyping = { typingLocation: typingFile, version: newVersion };
                                _this.packageNameToTypingLocation.set(packageName, newTyping);
                                installedTypingFiles.push(typingFile);
                            }
                            if (_this.log.isEnabled()) {
                                _this.log.writeLine("Installed typing files " + JSON.stringify(installedTypingFiles));
                            }
                            _this.sendResponse(_this.createSetTypings(req, currentlyCachedTypings.concat(installedTypingFiles)));
                        }
                        finally {
                            var response = {
                                kind: server.EventEndInstallTypes,
                                eventId: requestId,
                                projectName: req.projectName,
                                packagesToInstall: scopedTypings,
                                installSuccess: ok,
                                // qualified explicitly to prevent occasional shadowing
                                // eslint-disable-next-line @typescript-eslint/no-unnecessary-qualifier
                                typingsInstallerVersion: ts.version
                            };
                            _this.sendResponse(response);
                        }
                    });
                };
                TypingsInstaller.prototype.ensureDirectoryExists = function (directory, host) {
                    var directoryName = ts.getDirectoryPath(directory);
                    if (!host.directoryExists(directoryName)) {
                        this.ensureDirectoryExists(directoryName, host);
                    }
                    if (!host.directoryExists(directory)) {
                        host.createDirectory(directory);
                    }
                };
                TypingsInstaller.prototype.watchFiles = function (projectName, files, projectRootPath, options) {
                    var _this = this;
                    if (!files.length) {
                        // shut down existing watchers
                        this.closeWatchers(projectName);
                        return;
                    }
                    var watchers = this.projectWatchers.get(projectName);
                    var toRemove = ts.createMap();
                    if (!watchers) {
                        watchers = ts.createMap();
                        this.projectWatchers.set(projectName, watchers);
                    }
                    else {
                        ts.copyEntries(watchers, toRemove);
                    }
                    // handler should be invoked once for the entire set of files since it will trigger full rediscovery of typings
                    watchers.isInvoked = false;
                    var isLoggingEnabled = this.log.isEnabled();
                    var createProjectWatcher = function (path, projectWatcherType) {
                        var canonicalPath = _this.toCanonicalFileName(path);
                        toRemove.delete(canonicalPath);
                        if (watchers.has(canonicalPath)) {
                            return;
                        }
                        if (isLoggingEnabled) {
                            _this.log.writeLine(projectWatcherType + ":: Added:: WatchInfo: " + path);
                        }
                        var watcher = projectWatcherType === "FileWatcher" /* FileWatcher */ ?
                            _this.installTypingHost.watchFile(path, function (f, eventKind) {
                                if (isLoggingEnabled) {
                                    _this.log.writeLine("FileWatcher:: Triggered with " + f + " eventKind: " + ts.FileWatcherEventKind[eventKind] + ":: WatchInfo: " + path + ":: handler is already invoked '" + watchers.isInvoked + "'");
                                }
                                if (!watchers.isInvoked) {
                                    watchers.isInvoked = true;
                                    _this.sendResponse({ projectName: projectName, kind: server.ActionInvalidate });
                                }
                            }, /*pollingInterval*/ 2000, options) :
                            _this.installTypingHost.watchDirectory(path, function (f) {
                                if (isLoggingEnabled) {
                                    _this.log.writeLine("DirectoryWatcher:: Triggered with " + f + " :: WatchInfo: " + path + " recursive :: handler is already invoked '" + watchers.isInvoked + "'");
                                }
                                if (watchers.isInvoked || !ts.fileExtensionIs(f, ".json" /* Json */)) {
                                    return;
                                }
                                if (isPackageOrBowerJson(f, _this.installTypingHost.useCaseSensitiveFileNames) &&
                                    !sameFiles(f, _this.globalCachePackageJsonPath, _this.installTypingHost.useCaseSensitiveFileNames)) {
                                    watchers.isInvoked = true;
                                    _this.sendResponse({ projectName: projectName, kind: server.ActionInvalidate });
                                }
                            }, /*recursive*/ true, options);
                        watchers.set(canonicalPath, isLoggingEnabled ? {
                            close: function () {
                                _this.log.writeLine(projectWatcherType + ":: Closed:: WatchInfo: " + path);
                                watcher.close();
                            }
                        } : watcher);
                    };
                    // Create watches from list of files
                    for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
                        var file = files_1[_i];
                        if (file.endsWith("/package.json") || file.endsWith("/bower.json")) {
                            // package.json or bower.json exists, watch the file to detect changes and update typings
                            createProjectWatcher(file, "FileWatcher" /* FileWatcher */);
                            continue;
                        }
                        // path in projectRoot, watch project root
                        if (ts.containsPath(projectRootPath, file, projectRootPath, !this.installTypingHost.useCaseSensitiveFileNames)) {
                            var subDirectory = file.indexOf(ts.directorySeparator, projectRootPath.length + 1);
                            if (subDirectory !== -1) {
                                // Watch subDirectory
                                createProjectWatcher(file.substr(0, subDirectory), "DirectoryWatcher" /* DirectoryWatcher */);
                            }
                            else {
                                // Watch the directory itself
                                createProjectWatcher(file, "DirectoryWatcher" /* DirectoryWatcher */);
                            }
                            continue;
                        }
                        // path in global cache, watch global cache
                        if (ts.containsPath(this.globalCachePath, file, projectRootPath, !this.installTypingHost.useCaseSensitiveFileNames)) {
                            createProjectWatcher(this.globalCachePath, "DirectoryWatcher" /* DirectoryWatcher */);
                            continue;
                        }
                        // watch node_modules or bower_components
                        createProjectWatcher(file, "DirectoryWatcher" /* DirectoryWatcher */);
                    }
                    // Remove unused watches
                    toRemove.forEach(function (watch, path) {
                        watch.close();
                        watchers.delete(path);
                    });
                };
                TypingsInstaller.prototype.createSetTypings = function (request, typings) {
                    return {
                        projectName: request.projectName,
                        typeAcquisition: request.typeAcquisition,
                        compilerOptions: request.compilerOptions,
                        typings: typings,
                        unresolvedImports: request.unresolvedImports,
                        kind: server.ActionSet
                    };
                };
                TypingsInstaller.prototype.installTypingsAsync = function (requestId, packageNames, cwd, onRequestCompleted) {
                    this.pendingRunRequests.unshift({ requestId: requestId, packageNames: packageNames, cwd: cwd, onRequestCompleted: onRequestCompleted });
                    this.executeWithThrottling();
                };
                TypingsInstaller.prototype.executeWithThrottling = function () {
                    var _this = this;
                    var _loop_1 = function () {
                        this_1.inFlightRequestCount++;
                        var request = this_1.pendingRunRequests.pop();
                        this_1.installWorker(request.requestId, request.packageNames, request.cwd, function (ok) {
                            _this.inFlightRequestCount--;
                            request.onRequestCompleted(ok);
                            _this.executeWithThrottling();
                        });
                    };
                    var this_1 = this;
                    while (this.inFlightRequestCount < this.throttleLimit && this.pendingRunRequests.length) {
                        _loop_1();
                    }
                };
                return TypingsInstaller;
            }());
            typingsInstaller.TypingsInstaller = TypingsInstaller;
            /* @internal */
            function typingsName(packageName) {
                return "@types/" + packageName + "@ts" + ts.versionMajorMinor;
            }
            typingsInstaller.typingsName = typingsName;
        })(typingsInstaller = server.typingsInstaller || (server.typingsInstaller = {}));
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
var ts;
(function (ts) {
    var server;
    (function (server) {
        var typingsInstaller;
        (function (typingsInstaller) {
            var fs = require("fs");
            var path = require("path");
            var FileLog = (function () {
                function FileLog(logFile) {
                    var _this = this;
                    this.logFile = logFile;
                    this.isEnabled = function () {
                        return typeof _this.logFile === "string";
                    };
                    this.writeLine = function (text) {
                        if (typeof _this.logFile !== "string")
                            return;
                        try {
                            fs.appendFileSync(_this.logFile, "[" + server.nowString() + "] " + text + ts.sys.newLine);
                        }
                        catch (e) {
                            _this.logFile = undefined;
                        }
                    };
                }
                return FileLog;
            }());
            function getDefaultNPMLocation(processName, validateDefaultNpmLocation, host) {
                if (path.basename(processName).indexOf("node") === 0) {
                    var npmPath = path.join(path.dirname(process.argv[0]), "npm");
                    if (!validateDefaultNpmLocation) {
                        return npmPath;
                    }
                    if (host.fileExists(npmPath)) {
                        return "\"" + npmPath + "\"";
                    }
                }
                return "npm";
            }
            function loadTypesRegistryFile(typesRegistryFilePath, host, log) {
                if (!host.fileExists(typesRegistryFilePath)) {
                    if (log.isEnabled()) {
                        log.writeLine("Types registry file '" + typesRegistryFilePath + "' does not exist");
                    }
                    return ts.createMap();
                }
                try {
                    var content = JSON.parse(host.readFile(typesRegistryFilePath));
                    return ts.createMapFromTemplate(content.entries);
                }
                catch (e) {
                    if (log.isEnabled()) {
                        log.writeLine("Error when loading types registry file '" + typesRegistryFilePath + "': " + e.message + ", " + e.stack);
                    }
                    return ts.createMap();
                }
            }
            var typesRegistryPackageName = "types-registry";
            function getTypesRegistryFileLocation(globalTypingsCacheLocation) {
                return ts.combinePaths(ts.normalizeSlashes(globalTypingsCacheLocation), "node_modules/" + typesRegistryPackageName + "/index.json");
            }
            var NodeTypingsInstaller = (function (_super) {
                __extends(NodeTypingsInstaller, _super);
                function NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, validateDefaultNpmLocation, throttleLimit, log) {
                    var _this = _super.call(this, ts.sys, globalTypingsCacheLocation, typingSafeListLocation ? ts.toPath(typingSafeListLocation, "", ts.createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames)) : ts.toPath("typingSafeList.json", __dirname, ts.createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames)), typesMapLocation ? ts.toPath(typesMapLocation, "", ts.createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames)) : ts.toPath("typesMap.json", __dirname, ts.createGetCanonicalFileName(ts.sys.useCaseSensitiveFileNames)), throttleLimit, log) || this;
                    _this.npmPath = npmLocation !== undefined ? npmLocation : getDefaultNPMLocation(process.argv[0], validateDefaultNpmLocation, _this.installTypingHost);
                    if (ts.stringContains(_this.npmPath, " ") && _this.npmPath[0] !== "\"") {
                        _this.npmPath = "\"" + _this.npmPath + "\"";
                    }
                    if (_this.log.isEnabled()) {
                        _this.log.writeLine("Process id: " + process.pid);
                        _this.log.writeLine("NPM location: " + _this.npmPath + " (explicit '" + server.Arguments.NpmLocation + "' " + (npmLocation === undefined ? "not " : "") + " provided)");
                        _this.log.writeLine("validateDefaultNpmLocation: " + validateDefaultNpmLocation);
                    }
                    (_this.nodeExecSync = require("child_process").execSync);
                    _this.ensurePackageDirectoryExists(globalTypingsCacheLocation);
                    try {
                        if (_this.log.isEnabled()) {
                            _this.log.writeLine("Updating " + typesRegistryPackageName + " npm package...");
                        }
                        _this.execSyncAndLog(_this.npmPath + " install --ignore-scripts " + typesRegistryPackageName + "@" + _this.latestDistTag, { cwd: globalTypingsCacheLocation });
                        if (_this.log.isEnabled()) {
                            _this.log.writeLine("Updated " + typesRegistryPackageName + " npm package");
                        }
                    }
                    catch (e) {
                        if (_this.log.isEnabled()) {
                            _this.log.writeLine("Error updating " + typesRegistryPackageName + " package: " + e.message);
                        }
                        _this.delayedInitializationError = {
                            kind: "event::initializationFailed",
                            message: e.message
                        };
                    }
                    _this.typesRegistry = loadTypesRegistryFile(getTypesRegistryFileLocation(globalTypingsCacheLocation), _this.installTypingHost, _this.log);
                    return _this;
                }
                NodeTypingsInstaller.prototype.listen = function () {
                    var _this = this;
                    process.on("message", function (req) {
                        if (_this.delayedInitializationError) {
                            _this.sendResponse(_this.delayedInitializationError);
                            _this.delayedInitializationError = undefined;
                        }
                        switch (req.kind) {
                            case "discover":
                                _this.install(req);
                                break;
                            case "closeProject":
                                _this.closeProject(req);
                                break;
                            case "typesRegistry": {
                                var typesRegistry_1 = {};
                                _this.typesRegistry.forEach(function (value, key) {
                                    typesRegistry_1[key] = value;
                                });
                                var response = { kind: server.EventTypesRegistry, typesRegistry: typesRegistry_1 };
                                _this.sendResponse(response);
                                break;
                            }
                            case "installPackage": {
                                var fileName = req.fileName, packageName_1 = req.packageName, projectName_1 = req.projectName, projectRootPath = req.projectRootPath;
                                var cwd = getDirectoryOfPackageJson(fileName, _this.installTypingHost) || projectRootPath;
                                if (cwd) {
                                    _this.installWorker(-1, [packageName_1], cwd, function (success) {
                                        var message = success ? "Package " + packageName_1 + " installed." : "There was an error installing " + packageName_1 + ".";
                                        var response = { kind: server.ActionPackageInstalled, projectName: projectName_1, success: success, message: message };
                                        _this.sendResponse(response);
                                    });
                                }
                                else {
                                    var response = { kind: server.ActionPackageInstalled, projectName: projectName_1, success: false, message: "Could not determine a project root path." };
                                    _this.sendResponse(response);
                                }
                                break;
                            }
                            default:
                                ts.Debug.assertNever(req);
                        }
                    });
                };
                NodeTypingsInstaller.prototype.sendResponse = function (response) {
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Sending response:\n    " + JSON.stringify(response));
                    }
                    process.send(response);
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Response has been sent.");
                    }
                };
                NodeTypingsInstaller.prototype.installWorker = function (requestId, packageNames, cwd, onRequestCompleted) {
                    var _this = this;
                    if (this.log.isEnabled()) {
                        this.log.writeLine("#" + requestId + " with arguments'" + JSON.stringify(packageNames) + "'.");
                    }
                    var start = Date.now();
                    var hasError = typingsInstaller.installNpmPackages(this.npmPath, ts.version, packageNames, function (command) { return _this.execSyncAndLog(command, { cwd: cwd }); });
                    if (this.log.isEnabled()) {
                        this.log.writeLine("npm install #" + requestId + " took: " + (Date.now() - start) + " ms");
                    }
                    onRequestCompleted(!hasError);
                };
                NodeTypingsInstaller.prototype.execSyncAndLog = function (command, options) {
                    if (this.log.isEnabled()) {
                        this.log.writeLine("Exec: " + command);
                    }
                    try {
                        var stdout = this.nodeExecSync(command, __assign(__assign({}, options), { encoding: "utf-8" }));
                        if (this.log.isEnabled()) {
                            this.log.writeLine("    Succeeded. stdout:" + indent(ts.sys.newLine, stdout));
                        }
                        return false;
                    }
                    catch (error) {
                        var stdout = error.stdout, stderr = error.stderr;
                        this.log.writeLine("    Failed. stdout:" + indent(ts.sys.newLine, stdout) + ts.sys.newLine + "    stderr:" + indent(ts.sys.newLine, stderr));
                        return true;
                    }
                };
                return NodeTypingsInstaller;
            }(typingsInstaller.TypingsInstaller));
            typingsInstaller.NodeTypingsInstaller = NodeTypingsInstaller;
            function getDirectoryOfPackageJson(fileName, host) {
                return ts.forEachAncestorDirectory(ts.getDirectoryPath(fileName), function (directory) {
                    if (host.fileExists(ts.combinePaths(directory, "package.json"))) {
                        return directory;
                    }
                });
            }
            var logFilePath = server.findArgument(server.Arguments.LogFile);
            var globalTypingsCacheLocation = server.findArgument(server.Arguments.GlobalCacheLocation);
            var typingSafeListLocation = server.findArgument(server.Arguments.TypingSafeListLocation);
            var typesMapLocation = server.findArgument(server.Arguments.TypesMapLocation);
            var npmLocation = server.findArgument(server.Arguments.NpmLocation);
            var validateDefaultNpmLocation = server.hasArgument(server.Arguments.ValidateDefaultNpmLocation);
            var log = new FileLog(logFilePath);
            if (log.isEnabled()) {
                process.on("uncaughtException", function (e) {
                    log.writeLine("Unhandled exception: " + e + " at " + e.stack);
                });
            }
            process.on("disconnect", function () {
                if (log.isEnabled()) {
                    log.writeLine("Parent process has exited, shutting down...");
                }
                process.exit(0);
            });
            var installer = new NodeTypingsInstaller(globalTypingsCacheLocation, typingSafeListLocation, typesMapLocation, npmLocation, validateDefaultNpmLocation, 5, log);
            installer.listen();
            function indent(newline, str) {
                return newline + "    " + str.replace(/\r?\n/, newline + "    ");
            }
        })(typingsInstaller = server.typingsInstaller || (server.typingsInstaller = {}));
    })(server = ts.server || (ts.server = {}));
})(ts || (ts = {}));
//# sourceMappingURL=typingsInstaller.js.map