function define(modules, cb) {
  function parseStringArray(argName) {
    const index = process.argv.indexOf(argName);
    if (index < 0 || index === process.argv.length - 1) {
        return [];
    }
    const arg = process.argv[index + 1];
    return arg.split(',');
  }
  function resolve(packageName, paths) {
    try {
      return require.resolve(packageName, {paths});
    }
    catch {}
  }
  const TSSERVER = 'typescript/lib/tsserverlibrary';
  const resolvedModules = modules.map(m => {
    if (m === TSSERVER || m === 'typescript') {
      const tsProbeLocations = parseStringArray('--tsProbeLocations');
      m = resolve(TSSERVER, tsProbeLocations) || TSSERVER;
    }
    return require(m);
  });
  cb(...resolvedModules);
}

define(['fs', 'path', 'typescript/lib/tsserverlibrary', 'vscode-languageserver', 'vscode-uri'], function (fs, path, tsserverlibrary, vscodeLanguageserver, vscodeUri) { 'use strict';

	fs = fs && fs.hasOwnProperty('default') ? fs['default'] : fs;
	path = path && path.hasOwnProperty('default') ? path['default'] : path;
	tsserverlibrary = tsserverlibrary && tsserverlibrary.hasOwnProperty('default') ? tsserverlibrary['default'] : tsserverlibrary;
	vscodeLanguageserver = vscodeLanguageserver && vscodeLanguageserver.hasOwnProperty('default') ? vscodeLanguageserver['default'] : vscodeLanguageserver;
	vscodeUri = vscodeUri && vscodeUri.hasOwnProperty('default') ? vscodeUri['default'] : vscodeUri;

	function unwrapExports (x) {
		return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
	}

	function createCommonjsModule(fn, module) {
		return module = { exports: {} }, fn(module, module.exports), module.exports;
	}

	var logger = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });



	/**
	 * Create a logger instance to write to file.
	 * @param options Logging options.
	 */
	function createLogger(options) {
	    let logLevel;
	    switch (options.logVerbosity) {
	        case 'terse':
	            logLevel = tsserverlibrary.server.LogLevel.terse;
	            break;
	        case 'requestTime':
	            logLevel = tsserverlibrary.server.LogLevel.requestTime;
	            break;
	        case 'verbose':
	            logLevel = tsserverlibrary.server.LogLevel.verbose;
	            break;
	        case 'normal':
	            logLevel = tsserverlibrary.server.LogLevel.normal;
	            break;
	        default:
	            logLevel = tsserverlibrary.server.LogLevel.terse;
	            break;
	    }
	    // If logFile is not provided then just trace to console.
	    const traceToConsole = !options.logFile;
	    return new Logger(traceToConsole, logLevel, options.logFile);
	}
	exports.createLogger = createLogger;
	// TODO: Code below is from TypeScript's repository. Maybe create our own
	// implementation.
	// https://github.com/microsoft/TypeScript/blob/ec39d412876d0dcf704fc886d5036cb625220d2f/src/tsserver/server.ts#L120
	function noop(_) { } // tslint:disable-line no-empty
	function nowString() {
	    // E.g. "12:34:56.789"
	    const d = new Date();
	    return `${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}.${d.getMilliseconds()}`;
	}
	class Logger {
	    constructor(traceToConsole, level, logFilename) {
	        this.traceToConsole = traceToConsole;
	        this.level = level;
	        this.logFilename = logFilename;
	        this.fd = -1;
	        this.seq = 0;
	        this.inGroup = false;
	        this.firstInGroup = true;
	        if (logFilename) {
	            try {
	                const dir = path.dirname(logFilename);
	                if (!fs.existsSync(dir)) {
	                    fs.mkdirSync(dir);
	                }
	                this.fd = fs.openSync(logFilename, 'w');
	            }
	            catch (_a) {
	                // swallow the error and keep logging disabled if file cannot be opened
	            }
	        }
	    }
	    static padStringRight(str, padding) {
	        return (str + padding).slice(0, padding.length);
	    }
	    close() {
	        if (this.fd >= 0) {
	            fs.close(this.fd, noop);
	        }
	    }
	    getLogFileName() {
	        return this.logFilename;
	    }
	    perftrc(s) {
	        this.msg(s, tsserverlibrary.server.Msg.Perf);
	    }
	    info(s) {
	        this.msg(s, tsserverlibrary.server.Msg.Info);
	    }
	    err(s) {
	        this.msg(s, tsserverlibrary.server.Msg.Err);
	    }
	    startGroup() {
	        this.inGroup = true;
	        this.firstInGroup = true;
	    }
	    endGroup() {
	        this.inGroup = false;
	    }
	    loggingEnabled() {
	        return !!this.logFilename || this.traceToConsole;
	    }
	    hasLevel(level) {
	        return this.loggingEnabled() && this.level >= level;
	    }
	    msg(s, type = tsserverlibrary.server.Msg.Err) {
	        if (!this.canWrite)
	            return;
	        s = `[${nowString()}] ${s}\n`;
	        if (!this.inGroup || this.firstInGroup) {
	            const prefix = Logger.padStringRight(type + ' ' + this.seq.toString(), '          ');
	            s = prefix + s;
	        }
	        this.write(s);
	        if (!this.inGroup) {
	            this.seq++;
	        }
	    }
	    get canWrite() {
	        return this.fd >= 0 || this.traceToConsole;
	    }
	    write(s) {
	        if (this.fd >= 0) {
	            const buf = Buffer.from(s);
	            // tslint:disable-next-line no-null-keyword
	            fs.writeSync(this.fd, buf, 0, buf.length, /*position*/ null); // TODO: GH#18217
	        }
	        if (this.traceToConsole) {
	            console.warn(s);
	        }
	    }
	}
	exports.Logger = Logger;

	});

	unwrapExports(logger);
	var logger_1 = logger.createLogger;
	var logger_2 = logger.Logger;

	var server_host = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });

	/**
	 * `ServerHost` is a wrapper around `ts.sys` for the Node system. In Node, all
	 * optional methods of `ts.System` are implemented.
	 * See
	 * https://github.com/microsoft/TypeScript/blob/ec39d412876d0dcf704fc886d5036cb625220d2f/src/compiler/sys.ts#L716
	 */
	class ServerHost {
	    constructor() {
	        this.args = tsserverlibrary.sys.args;
	        this.newLine = tsserverlibrary.sys.newLine;
	        this.useCaseSensitiveFileNames = tsserverlibrary.sys.useCaseSensitiveFileNames;
	    }
	    write(s) {
	        tsserverlibrary.sys.write(s);
	    }
	    writeOutputIsTTY() {
	        return tsserverlibrary.sys.writeOutputIsTTY();
	    }
	    readFile(path, encoding) {
	        return tsserverlibrary.sys.readFile(path, encoding);
	    }
	    getFileSize(path) {
	        return tsserverlibrary.sys.getFileSize(path);
	    }
	    writeFile(path, data, writeByteOrderMark) {
	        return tsserverlibrary.sys.writeFile(path, data, writeByteOrderMark);
	    }
	    /**
	     * @pollingInterval - this parameter is used in polling-based watchers and
	     * ignored in watchers that use native OS file watching
	     */
	    watchFile(path, callback, pollingInterval) {
	        return tsserverlibrary.sys.watchFile(path, callback, pollingInterval);
	    }
	    watchDirectory(path, callback, recursive) {
	        return tsserverlibrary.sys.watchDirectory(path, callback, recursive);
	    }
	    resolvePath(path) {
	        return tsserverlibrary.sys.resolvePath(path);
	    }
	    fileExists(path) {
	        return tsserverlibrary.sys.fileExists(path);
	    }
	    directoryExists(path) {
	        return tsserverlibrary.sys.directoryExists(path);
	    }
	    createDirectory(path) {
	        return tsserverlibrary.sys.createDirectory(path);
	    }
	    getExecutingFilePath() {
	        return tsserverlibrary.sys.getExecutingFilePath();
	    }
	    getCurrentDirectory() {
	        return tsserverlibrary.sys.getCurrentDirectory();
	    }
	    getDirectories(path) {
	        return tsserverlibrary.sys.getDirectories(path);
	    }
	    readDirectory(path, extensions, exclude, include, depth) {
	        return tsserverlibrary.sys.readDirectory(path, extensions, exclude, include, depth);
	    }
	    getModifiedTime(path) {
	        return tsserverlibrary.sys.getModifiedTime(path);
	    }
	    setModifiedTime(path, time) {
	        return tsserverlibrary.sys.setModifiedTime(path, time);
	    }
	    deleteFile(path) {
	        return tsserverlibrary.sys.deleteFile(path);
	    }
	    /**
	     * A good implementation is node.js' `crypto.createHash`.
	     * (https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm)
	     */
	    createHash(data) {
	        return tsserverlibrary.sys.createHash(data);
	    }
	    /**
	     * This must be cryptographically secure. Only implement this method using
	     * `crypto.createHash("sha256")`.
	     */
	    createSHA256Hash(data) {
	        return tsserverlibrary.sys.createSHA256Hash(data);
	    }
	    getMemoryUsage() {
	        return tsserverlibrary.sys.getMemoryUsage();
	    }
	    exit(exitCode) {
	        return tsserverlibrary.sys.exit(exitCode);
	    }
	    realpath(path) {
	        return tsserverlibrary.sys.realpath(path);
	    }
	    setTimeout(callback, ms, ...args) {
	        return tsserverlibrary.sys.setTimeout(callback, ms, ...args);
	    }
	    clearTimeout(timeoutId) {
	        return tsserverlibrary.sys.clearTimeout(timeoutId);
	    }
	    clearScreen() {
	        return tsserverlibrary.sys.clearScreen();
	    }
	    base64decode(input) {
	        return tsserverlibrary.sys.base64decode(input);
	    }
	    base64encode(input) {
	        return tsserverlibrary.sys.base64encode(input);
	    }
	    setImmediate(callback, ...args) {
	        return setImmediate(callback, ...args);
	    }
	    clearImmediate(timeoutId) {
	        return clearImmediate(timeoutId);
	    }
	    require(initialPath, moduleName) {
	        try {
	            const modulePath = require.resolve(moduleName, {
	                paths: [initialPath],
	            });
	            return {
	                module: require(modulePath),
	                error: undefined,
	            };
	        }
	        catch (e) {
	            return {
	                module: undefined,
	                error: e,
	            };
	        }
	    }
	}
	exports.ServerHost = ServerHost;

	});

	unwrapExports(server_host);
	var server_host_1 = server_host.ServerHost;

	var completion = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });

	// TODO: Move this to `@angular/language-service`.
	var CompletionKind;
	(function (CompletionKind) {
	    CompletionKind["attribute"] = "attribute";
	    CompletionKind["htmlAttribute"] = "html attribute";
	    CompletionKind["property"] = "property";
	    CompletionKind["component"] = "component";
	    CompletionKind["element"] = "element";
	    CompletionKind["key"] = "key";
	    CompletionKind["method"] = "method";
	    CompletionKind["pipe"] = "pipe";
	    CompletionKind["type"] = "type";
	    CompletionKind["reference"] = "reference";
	    CompletionKind["variable"] = "variable";
	    CompletionKind["entity"] = "entity";
	})(CompletionKind || (CompletionKind = {}));
	/**
	 * Convert Angular's CompletionKind to LSP CompletionItemKind.
	 * @param kind Angular's CompletionKind
	 */
	function ngCompletionKindToLspCompletionItemKind(kind) {
	    switch (kind) {
	        case CompletionKind.attribute:
	        case CompletionKind.htmlAttribute:
	        case CompletionKind.property:
	            return vscodeLanguageserver.CompletionItemKind.Property;
	        case CompletionKind.component:
	        case CompletionKind.element:
	        case CompletionKind.key:
	            return vscodeLanguageserver.CompletionItemKind.Class;
	        case CompletionKind.method:
	            return vscodeLanguageserver.CompletionItemKind.Method;
	        case CompletionKind.pipe:
	            return vscodeLanguageserver.CompletionItemKind.Function;
	        case CompletionKind.type:
	            return vscodeLanguageserver.CompletionItemKind.Interface;
	        case CompletionKind.reference:
	        case CompletionKind.variable:
	            return vscodeLanguageserver.CompletionItemKind.Variable;
	        case CompletionKind.entity:
	        default:
	            return vscodeLanguageserver.CompletionItemKind.Text;
	    }
	}
	/**
	 * Convert ts.CompletionEntry to LSP Completion Item.
	 * @param entry completion entry
	 * @param position position where completion is requested.
	 */
	function tsCompletionEntryToLspCompletionItem(entry, position) {
	    const item = vscodeLanguageserver.CompletionItem.create(entry.name);
	    // Even though `entry.kind` is typed as ts.ScriptElementKind, it's
	    // really Angular's CompletionKind. This is because ts.ScriptElementKind does
	    // not sufficiently capture the HTML entities.
	    // This is a limitation of being a tsserver plugin.
	    const kind = entry.kind;
	    item.kind = ngCompletionKindToLspCompletionItemKind(kind);
	    item.detail = entry.kind;
	    item.sortText = entry.sortText;
	    item.textEdit = vscodeLanguageserver.TextEdit.insert(position, entry.name);
	    return item;
	}
	exports.tsCompletionEntryToLspCompletionItem = tsCompletionEntryToLspCompletionItem;

	});

	unwrapExports(completion);
	var completion_1 = completion.tsCompletionEntryToLspCompletionItem;

	var utils = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });


	var Scheme;
	(function (Scheme) {
	    Scheme["File"] = "file";
	})(Scheme || (Scheme = {}));
	/**
	 * Extract the file path from the specified `uri`.
	 * @param uri
	 */
	function uriToFilePath(uri) {
	    // Note: uri.path is different from uri.fsPath
	    // See
	    // https://github.com/microsoft/vscode-uri/blob/413805221cc6ed167186ab3103d3248d6f7161f2/src/index.ts#L622-L645
	    const { scheme, fsPath } = vscodeUri.URI.parse(uri);
	    if (scheme !== Scheme.File) {
	        return '';
	    }
	    return fsPath;
	}
	exports.uriToFilePath = uriToFilePath;
	/**
	 * Converts the specified `filePath` to a proper URI.
	 * @param filePath
	 */
	function filePathToUri(filePath) {
	    return vscodeUri.URI.file(filePath).toString();
	}
	exports.filePathToUri = filePathToUri;
	/**
	 * Convert ts.TextSpan to lsp.TextSpan. TypeScript keeps track of offset using
	 * 1-based index whereas LSP uses 0-based index.
	 * @param scriptInfo Used to determine the offsets.
	 * @param textSpan
	 */
	function tsTextSpanToLspRange(scriptInfo, textSpan) {
	    const start = scriptInfo.positionToLineOffset(textSpan.start);
	    const end = scriptInfo.positionToLineOffset(textSpan.start + textSpan.length);
	    // ScriptInfo (TS) is 1-based, LSP is 0-based.
	    return vscodeLanguageserver.Range.create(start.line - 1, start.offset - 1, end.line - 1, end.offset - 1);
	}
	exports.tsTextSpanToLspRange = tsTextSpanToLspRange;
	/**
	 * Convert lsp.Position to the absolute offset in the file. LSP keeps track of
	 * offset using 0-based index whereas TypeScript uses 1-based index.
	 * @param scriptInfo Used to determine the offsets.
	 * @param position
	 */
	function lspPositionToTsPosition(scriptInfo, position) {
	    const { line, character } = position;
	    // ScriptInfo (TS) is 1-based, LSP is 0-based.
	    return scriptInfo.lineOffsetToPosition(line + 1, character + 1);
	}
	exports.lspPositionToTsPosition = lspPositionToTsPosition;
	/**
	 * Convert lsp.Range which is made up of `start` and `end` positions to
	 * TypeScript's absolute offsets.
	 * @param scriptInfo Used to determine the offsets.
	 * @param range
	 */
	function lspRangeToTsPositions(scriptInfo, range) {
	    const start = lspPositionToTsPosition(scriptInfo, range.start);
	    const end = lspPositionToTsPosition(scriptInfo, range.end);
	    return [start, end];
	}
	exports.lspRangeToTsPositions = lspRangeToTsPositions;

	});

	unwrapExports(utils);
	var utils_1 = utils.uriToFilePath;
	var utils_2 = utils.filePathToUri;
	var utils_3 = utils.tsTextSpanToLspRange;
	var utils_4 = utils.lspPositionToTsPosition;
	var utils_5 = utils.lspRangeToTsPositions;

	var diagnostic = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });



	/**
	 * Convert ts.DiagnosticCategory to lsp.DiagnosticSeverity
	 * @param category diagnostic category
	 */
	function tsDiagnosticCategoryToLspDiagnosticSeverity(category) {
	    switch (category) {
	        case tsserverlibrary.DiagnosticCategory.Warning:
	            return vscodeLanguageserver.DiagnosticSeverity.Warning;
	        case tsserverlibrary.DiagnosticCategory.Error:
	            return vscodeLanguageserver.DiagnosticSeverity.Error;
	        case tsserverlibrary.DiagnosticCategory.Suggestion:
	            return vscodeLanguageserver.DiagnosticSeverity.Hint;
	        case tsserverlibrary.DiagnosticCategory.Message:
	        default:
	            return vscodeLanguageserver.DiagnosticSeverity.Information;
	    }
	}
	/**
	 * Convert ts.Diagnostic to lsp.Diagnostic
	 * @param tsDiag TS diagnostic
	 * @param scriptInfo Used to compute proper offset.
	 */
	function tsDiagnosticToLspDiagnostic(tsDiag, scriptInfo) {
	    const textSpan = {
	        start: tsDiag.start || 0,
	        length: tsDiag.length || 0,
	    };
	    return vscodeLanguageserver.Diagnostic.create(utils.tsTextSpanToLspRange(scriptInfo, textSpan), tsserverlibrary.flattenDiagnosticMessageText(tsDiag.messageText, '\n'), tsDiagnosticCategoryToLspDiagnosticSeverity(tsDiag.category), tsDiag.code, tsDiag.source);
	}
	exports.tsDiagnosticToLspDiagnostic = tsDiagnosticToLspDiagnostic;

	});

	unwrapExports(diagnostic);
	var diagnostic_1 = diagnostic.tsDiagnosticToLspDiagnostic;

	var project_service = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });

	/**
	 * NOTE:
	 * There are three types of `project`:
	 * 1. Configured project - basically all source files that belong to a tsconfig
	 * 2. Inferred project - other files that do not belong to a tsconfig
	 * 3. External project - not used in this context
	 * For more info, see link below.
	 * https://github.com/Microsoft/TypeScript/wiki/Standalone-Server-%28tsserver%29#project-system
	 */
	/**
	 * `ProjectService` is a singleton service for the entire lifespan of the
	 * language server. This specific implementation is a very thin wrapper
	 * around TypeScript's `ProjectService`. On creation, it spins up tsserver and
	 * loads `@angular/language-service` as a global plugin.
	 * `ProjectService` is used to manage both TS document as well as HTML.
	 * Using tsserver to handle non-TS files is fine as long as the ScriptKind is
	 * configured correctly and `getSourceFile()` is never called on non-TS files.
	 */
	class ProjectService {
	    constructor(options) {
	        this.tsProjSvc = new tsserverlibrary.server.ProjectService(options);
	        this.tsProjSvc.setHostConfiguration({
	            formatOptions: this.tsProjSvc.getHostFormatCodeOptions(),
	            extraFileExtensions: [
	                {
	                    extension: '.html',
	                    isMixedContent: false,
	                    scriptKind: tsserverlibrary.ScriptKind.External,
	                },
	            ],
	        });
	        this.tsProjSvc.configurePlugin({
	            pluginName: '@angular/language-service',
	            configuration: {
	                angularOnly: true,
	            },
	        });
	    }
	    /**
	     * Open file whose contents is managed by the client
	     * @param filename is absolute pathname
	     * @param fileContent is a known version of the file content that is more up to date than the one
	     *     on disk
	     */
	    openClientFile(fileName, fileContent, scriptKind, projectRootPath) {
	        return this.tsProjSvc.openClientFile(fileName, fileContent, scriptKind, projectRootPath);
	    }
	    /**
	     * Close file whose contents is managed by the client
	     * @param filename is absolute pathname
	     */
	    closeClientFile(uncheckedFileName) {
	        this.tsProjSvc.closeClientFile(uncheckedFileName);
	    }
	    findProject(projectName) {
	        return this.tsProjSvc.findProject(projectName);
	    }
	    getScriptInfo(uncheckedFileName) {
	        return this.tsProjSvc.getScriptInfo(uncheckedFileName);
	    }
	    /**
	     * Return the default project for the specified `scriptInfo` if it is already
	     * a configured project. If not, attempt to find a relevant config file and
	     * make that project its default. This method is to ensure HTML files always
	     * belong to a configured project instead of the default behavior of being in
	     * an inferred project.
	     * @param scriptInfo
	     */
	    getDefaultProjectForScriptInfo(scriptInfo) {
	        let project = this.tsProjSvc.getDefaultProjectForFile(scriptInfo.fileName, 
	        // ensureProject tries to find a default project for the scriptInfo if
	        // it does not already have one. It is not needed here because we are
	        // going to assign it a project below if it does not have one.
	        false // ensureProject
	        );
	        // TODO: verify that HTML files are attached to Inferred project by default.
	        // If they are already part of a ConfiguredProject then the following is
	        // not needed.
	        if (!project || project.projectKind !== tsserverlibrary.server.ProjectKind.Configured) {
	            const { configFileName } = this.tsProjSvc.openClientFile(scriptInfo.fileName);
	            if (!configFileName) {
	                // Failed to find a config file. There is nothing we could do.
	                return;
	            }
	            project = this.tsProjSvc.findProject(configFileName);
	            if (!project) {
	                return;
	            }
	            scriptInfo.detachAllProjects();
	            scriptInfo.attachToProject(project);
	        }
	        return project;
	    }
	}
	exports.ProjectService = ProjectService;

	});

	unwrapExports(project_service);
	var project_service_1 = project_service.ProjectService;

	var protocol = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });

	exports.projectLoadingNotification = {
	    start: new vscodeLanguageserver.NotificationType('angular-language-service/projectLoadingStart'),
	    finish: new vscodeLanguageserver.NotificationType('angular-language-service/projectLoadingFinish')
	};

	});

	unwrapExports(protocol);
	var protocol_1 = protocol.projectLoadingNotification;

	var session = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });







	var LanguageId;
	(function (LanguageId) {
	    LanguageId["TS"] = "typescript";
	    LanguageId["HTML"] = "html";
	})(LanguageId || (LanguageId = {}));
	// Empty definition range for files without `scriptInfo`
	const EMPTY_RANGE = vscodeLanguageserver.Range.create(0, 0, 0, 0);
	/**
	 * Session is a wrapper around lsp.IConnection, with all the necessary protocol
	 * handlers installed for Angular language service.
	 */
	class Session {
	    constructor(options) {
	        // Create a connection for the server. The connection uses Node's IPC as a transport.
	        this.connection = vscodeLanguageserver.createConnection();
	        this.addProtocolHandlers(this.connection);
	        this.projectService = new project_service.ProjectService({
	            host: options.host,
	            logger: options.logger,
	            cancellationToken: tsserverlibrary.server.nullCancellationToken,
	            useSingleInferredProject: true,
	            useInferredProjectPerProjectRoot: true,
	            typingsInstaller: tsserverlibrary.server.nullTypingsInstaller,
	            suppressDiagnosticEvents: false,
	            eventHandler: (e) => this.handleProjectServiceEvent(e),
	            globalPlugins: ['@angular/language-service'],
	            pluginProbeLocations: [options.ngProbeLocation],
	            allowLocalPluginLoads: false,
	        });
	    }
	    addProtocolHandlers(conn) {
	        conn.onInitialize(p => this.onInitialize(p));
	        conn.onDidOpenTextDocument(p => this.onDidOpenTextDocument(p));
	        conn.onDidCloseTextDocument(p => this.onDidCloseTextDocument(p));
	        conn.onDidChangeTextDocument(p => this.onDidChangeTextDocument(p));
	        conn.onDidSaveTextDocument(p => this.onDidSaveTextDocument(p));
	        conn.onDefinition(p => this.onDefinition(p));
	        conn.onHover(p => this.onHover(p));
	        conn.onCompletion(p => this.onCompletion(p));
	    }
	    /**
	     * An event handler that gets invoked whenever the program changes and
	     * TS ProjectService sends `ProjectUpdatedInBackgroundEvent`. This particular
	     * event is used to trigger diagnostic checks.
	     * @param event
	     */
	    handleProjectServiceEvent(event) {
	        switch (event.eventName) {
	            case tsserverlibrary.server.ProjectLoadingStartEvent:
	                this.connection.sendNotification(protocol.projectLoadingNotification.start, event.data.project.projectName);
	                break;
	            case tsserverlibrary.server.ProjectLoadingFinishEvent: {
	                const { project } = event.data;
	                if (!isAngularProject(project)) {
	                    project.disableLanguageService();
	                    this.connection.console.info(`Disabling language service for ${project.projectName} because it is not an Angular project.`);
	                }
	                this.connection.sendNotification(protocol.projectLoadingNotification.finish, event.data.project.projectName);
	                break;
	            }
	            case tsserverlibrary.server.ProjectsUpdatedInBackgroundEvent:
	                // ProjectsUpdatedInBackgroundEvent is sent whenever diagnostics are
	                // requested via project.refreshDiagnostics()
	                this.refreshDiagnostics(event.data.openFiles);
	                break;
	        }
	    }
	    /**
	     * Retrieve Angular diagnostics for the specified `openFiles`.
	     * @param openFiles
	     */
	    refreshDiagnostics(openFiles) {
	        for (const fileName of openFiles) {
	            const scriptInfo = this.projectService.getScriptInfo(fileName);
	            if (!scriptInfo) {
	                continue;
	            }
	            const project = this.projectService.getDefaultProjectForScriptInfo(scriptInfo);
	            if (!project || !project.languageServiceEnabled) {
	                continue;
	            }
	            const ngLS = project.getLanguageService();
	            const diagnostics = ngLS.getSemanticDiagnostics(fileName);
	            // Need to send diagnostics even if it's empty otherwise editor state will
	            // not be updated.
	            this.connection.sendDiagnostics({
	                uri: utils.filePathToUri(fileName),
	                diagnostics: diagnostics.map(d => diagnostic.tsDiagnosticToLspDiagnostic(d, scriptInfo)),
	            });
	        }
	    }
	    onInitialize(params) {
	        return {
	            capabilities: {
	                textDocumentSync: vscodeLanguageserver.TextDocumentSyncKind.Incremental,
	                completionProvider: {
	                    /// The server does not provide support to resolve additional information
	                    // for a completion item.
	                    resolveProvider: false,
	                    triggerCharacters: ['<', '.', '*', '[', '(']
	                },
	                definitionProvider: true,
	                hoverProvider: true,
	            },
	        };
	    }
	    onDidOpenTextDocument(params) {
	        const { uri, text, languageId } = params.textDocument;
	        const filePath = utils.uriToFilePath(uri);
	        if (!filePath) {
	            return;
	        }
	        const scriptKind = languageId === LanguageId.TS ? tsserverlibrary.ScriptKind.TS : tsserverlibrary.ScriptKind.External;
	        const result = this.projectService.openClientFile(filePath, text, scriptKind);
	        const { configFileName, configFileErrors } = result;
	        if (configFileErrors && configFileErrors.length) {
	            // configFileErrors is an empty array even if there's no error, so check length.
	            this.connection.console.error(configFileErrors.map(e => e.messageText).join('\n'));
	        }
	        if (!configFileName) {
	            // TODO: This could happen if the first file opened is HTML. Fix this.
	            this.connection.console.error(`No config file for ${filePath}`);
	            return;
	        }
	        const project = this.projectService.findProject(configFileName);
	        if (!project) {
	            this.connection.console.error(`Failed to find project for ${filePath}`);
	            return;
	        }
	        project.refreshDiagnostics(); // Show initial diagnostics
	    }
	    onDidCloseTextDocument(params) {
	        const { textDocument } = params;
	        const filePath = utils.uriToFilePath(textDocument.uri);
	        if (!filePath) {
	            return;
	        }
	        this.projectService.closeClientFile(filePath);
	    }
	    onDidChangeTextDocument(params) {
	        const { contentChanges, textDocument } = params;
	        const filePath = utils.uriToFilePath(textDocument.uri);
	        if (!filePath) {
	            return;
	        }
	        const scriptInfo = this.projectService.getScriptInfo(filePath);
	        if (!scriptInfo) {
	            this.connection.console.log(`Failed to get script info for ${filePath}`);
	            return;
	        }
	        for (const change of contentChanges) {
	            if (change.range) {
	                const [start, end] = utils.lspRangeToTsPositions(scriptInfo, change.range);
	                scriptInfo.editContent(start, end, change.text);
	            }
	        }
	        const project = this.projectService.getDefaultProjectForScriptInfo(scriptInfo);
	        if (!project) {
	            return;
	        }
	        project.refreshDiagnostics();
	    }
	    onDidSaveTextDocument(params) {
	        const { text, textDocument } = params;
	        const filePath = utils.uriToFilePath(textDocument.uri);
	        const scriptInfo = this.projectService.getScriptInfo(filePath);
	        if (!scriptInfo) {
	            return;
	        }
	        if (text) {
	            scriptInfo.open(text);
	        }
	        else {
	            scriptInfo.reloadFromFile();
	        }
	    }
	    onDefinition(params) {
	        const { position, textDocument } = params;
	        const filePath = utils.uriToFilePath(textDocument.uri);
	        const scriptInfo = this.projectService.getScriptInfo(filePath);
	        if (!scriptInfo) {
	            this.connection.console.log(`Script info not found for ${filePath}`);
	            return;
	        }
	        const { fileName } = scriptInfo;
	        const project = this.projectService.getDefaultProjectForScriptInfo(scriptInfo);
	        if (!project || !project.languageServiceEnabled) {
	            return;
	        }
	        const offset = utils.lspPositionToTsPosition(scriptInfo, position);
	        const langSvc = project.getLanguageService();
	        const definition = langSvc.getDefinitionAndBoundSpan(fileName, offset);
	        if (!definition || !definition.definitions) {
	            return;
	        }
	        const originSelectionRange = utils.tsTextSpanToLspRange(scriptInfo, definition.textSpan);
	        const results = [];
	        for (const d of definition.definitions) {
	            const scriptInfo = this.projectService.getScriptInfo(d.fileName);
	            // Some definitions, like definitions of CSS files, may not be recorded files with a
	            // `scriptInfo` but are still valid definitions because they are files that exist. In this
	            // case, check to make sure that the text span of the definition is zero so that the file
	            // doesn't have to be read; if the span is non-zero, we can't do anything with this
	            // definition.
	            if (!scriptInfo && d.textSpan.length > 0) {
	                continue;
	            }
	            const range = scriptInfo ? utils.tsTextSpanToLspRange(scriptInfo, d.textSpan) : EMPTY_RANGE;
	            const targetUri = utils.filePathToUri(d.fileName);
	            results.push({
	                originSelectionRange,
	                targetUri,
	                targetRange: range,
	                targetSelectionRange: range,
	            });
	        }
	        return results;
	    }
	    onHover(params) {
	        const { position, textDocument } = params;
	        const filePath = utils.uriToFilePath(textDocument.uri);
	        if (!filePath) {
	            return;
	        }
	        const scriptInfo = this.projectService.getScriptInfo(filePath);
	        if (!scriptInfo) {
	            return;
	        }
	        const project = this.projectService.getDefaultProjectForScriptInfo(scriptInfo);
	        if (!project || !project.languageServiceEnabled) {
	            return;
	        }
	        const offset = utils.lspPositionToTsPosition(scriptInfo, position);
	        const langSvc = project.getLanguageService();
	        const info = langSvc.getQuickInfoAtPosition(scriptInfo.fileName, offset);
	        if (!info) {
	            return;
	        }
	        const { kind, kindModifiers, textSpan, displayParts, documentation } = info;
	        let desc = kindModifiers ? kindModifiers + ' ' : '';
	        if (displayParts) {
	            // displayParts does not contain info about kindModifiers
	            // but displayParts does contain info about kind
	            desc += displayParts.map(dp => dp.text).join('');
	        }
	        else {
	            desc += kind;
	        }
	        const contents = [{
	                language: 'typescript',
	                value: desc,
	            }];
	        if (documentation) {
	            for (const d of documentation) {
	                contents.push(d.text);
	            }
	        }
	        return {
	            contents,
	            range: utils.tsTextSpanToLspRange(scriptInfo, textSpan),
	        };
	    }
	    onCompletion(params) {
	        const { position, textDocument } = params;
	        const filePath = utils.uriToFilePath(textDocument.uri);
	        if (!filePath) {
	            return;
	        }
	        const scriptInfo = this.projectService.getScriptInfo(filePath);
	        if (!scriptInfo) {
	            return;
	        }
	        const { fileName } = scriptInfo;
	        const project = this.projectService.getDefaultProjectForScriptInfo(scriptInfo);
	        if (!project || !project.languageServiceEnabled) {
	            return;
	        }
	        const offset = utils.lspPositionToTsPosition(scriptInfo, position);
	        const langSvc = project.getLanguageService();
	        const completions = langSvc.getCompletionsAtPosition(fileName, offset, {
	        // options
	        });
	        if (!completions) {
	            return;
	        }
	        return completions.entries.map((e) => completion.tsCompletionEntryToLspCompletionItem(e, position));
	    }
	    /**
	     * Show an error message.
	     *
	     * @param message The message to show.
	     */
	    error(message) {
	        this.connection.console.error(message);
	    }
	    /**
	     * Show a warning message.
	     *
	     * @param message The message to show.
	     */
	    warn(message) {
	        this.connection.console.warn(message);
	    }
	    /**
	     * Show an information message.
	     *
	     * @param message The message to show.
	     */
	    info(message) {
	        this.connection.console.info(message);
	    }
	    /**
	     * Log a message.
	     *
	     * @param message The message to log.
	     */
	    log(message) {
	        this.connection.console.log(message);
	    }
	    /**
	     * Start listening on the input stream for messages to process.
	     */
	    listen() {
	        this.connection.listen();
	    }
	}
	exports.Session = Session;
	/**
	 * Return true if the specified `project` contains the Angular core declaration.
	 * @param project
	 */
	function isAngularProject(project) {
	    project.markAsDirty(); // Must mark project as dirty to rebuild the program.
	    if (project.isNonTsProject()) {
	        return false;
	    }
	    for (const fileName of project.getFileNames()) {
	        if (fileName.endsWith('@angular/core/core.d.ts')) {
	            return true;
	        }
	    }
	    return false;
	}

	});

	unwrapExports(session);
	var session_1 = session.Session;

	var version_provider = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });

	function resolve(packageName, paths) {
	    try {
	        // Here, use native NodeJS require instead of ServerHost.require because
	        // we want the full path of the resolution provided by native
	        // `require.resolve()`, which ServerHost does not provide.
	        const resolvedPath = require.resolve(`${packageName}/package.json`, { paths });
	        const packageJson = require(resolvedPath);
	        return {
	            resolvedPath: path.dirname(resolvedPath),
	            version: packageJson.version,
	        };
	    }
	    catch (_a) {
	    }
	}
	function minVersion(nodeModule, minMajor) {
	    if (!nodeModule.version) {
	        return false;
	    }
	    const [majorStr] = nodeModule.version.split('.');
	    if (!majorStr) {
	        return false;
	    }
	    const major = Number(majorStr);
	    if (isNaN(major)) {
	        return false;
	    }
	    return major >= minMajor;
	}
	/**
	 * Resolve the node module with the specified `packageName` that satisfies
	 * the specified minimum major version.
	 * @param packageName
	 * @param minMajor
	 * @param probeLocations
	 */
	function resolveWithMinMajor(packageName, minMajor, probeLocations) {
	    for (const location of probeLocations) {
	        const nodeModule = resolve(packageName, [location]);
	        if (!nodeModule) {
	            continue;
	        }
	        if (minVersion(nodeModule, minMajor)) {
	            return nodeModule;
	        }
	    }
	    throw new Error(`Failed to resolve '${packageName}' with minimum major version '${minMajor}' from ` +
	        JSON.stringify(probeLocations, null, 2));
	}
	exports.resolveWithMinMajor = resolveWithMinMajor;

	});

	unwrapExports(version_provider);
	var version_provider_1 = version_provider.resolveWithMinMajor;

	var server = createCommonjsModule(function (module, exports) {
	/**
	 * @license
	 * Copyright Google Inc. All Rights Reserved.
	 *
	 * Use of this source code is governed by an MIT-style license that can be
	 * found in the LICENSE file at https://angular.io/license
	 */
	Object.defineProperty(exports, "__esModule", { value: true });




	// Parse command line arguments
	const help = hasArgument('--help');
	const logFile = findArgument('--logFile');
	const logVerbosity = findArgument('--logVerbosity');
	const ngProbeLocations = parseStringArray('--ngProbeLocations');
	const tsProbeLocations = parseStringArray('--tsProbeLocations');
	if (help) {
	    const { argv } = process;
	    console.error(`Angular Language Service that implements the Language Server Protocol (LSP).

Usage: ${argv[0]} ${argv[1]} [options]

Options:
  --help: Prints help message.
  --logFile: Location to log messages. Logging is disabled if not provided.
  --logVerbosity: terse|normal|verbose|requestTime. See ts.server.LogLevel.
  --ngProbeLocations: Path of @angular/language-service. Required.
  --tsProbeLocations: Path of typescript. Required.

Additional options supported by vscode-languageserver:
  --node-ipc: Communicate using Node's IPC. This is the default.
  --stdio: Communicate over stdin/stdout.
  --socket=<number>: Communicate using Unix socket.
`);
	    process.exit(0);
	}
	// Create a logger that logs to file. OK to emit verbose entries.
	const logger$1 = logger.createLogger({ logFile, logVerbosity });
	const ts = version_provider.resolveWithMinMajor('typescript', 3, tsProbeLocations);
	const ng = version_provider.resolveWithMinMajor('@angular/language-service', 9, ngProbeLocations);
	// ServerHost provides native OS functionality
	const host = new server_host.ServerHost();
	// Establish a new server session that encapsulates lsp connection.
	const session$1 = new session.Session({
	    host,
	    logger: logger$1,
	    ngProbeLocation: ng.resolvedPath,
	});
	// Log initialization info
	session$1.info(`Using typescript v${ts.version} from ${ts.resolvedPath}`);
	session$1.info(`Using @angular/language-service v${ng.version} from ${ng.resolvedPath}`);
	session$1.info(`Log file: ${logger$1.getLogFileName()}`);
	if (process.env.NG_DEBUG) {
	    session$1.info('Angular Language Service is running under DEBUG mode');
	}
	if (process.env.TSC_NONPOLLING_WATCHER !== 'true') {
	    session$1.warn(`Using less efficient polling watcher. Set TSC_NONPOLLING_WATCHER to true.`);
	}
	session$1.listen();
	function hasArgument(argName) {
	    return process.argv.includes(argName);
	}
	function findArgument(argName) {
	    const index = process.argv.indexOf(argName);
	    if (index < 0 || index === process.argv.length - 1) {
	        return;
	    }
	    return process.argv[index + 1];
	}
	function parseStringArray(argName) {
	    const arg = findArgument(argName);
	    if (!arg) {
	        return [];
	    }
	    return arg.split(',');
	}

	});

	var server$1 = unwrapExports(server);

	return server$1;

});
