UNPKG

atom-languageclient

Version:
208 lines 26.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const ls = require("./languageclient"); const atom_1 = require("atom"); // eslint-disable-next-line import/no-deprecated const diagnostic_adapter_1 = require("./adapters/diagnostic-adapter"); /** * Public: Class that contains a number of helper methods for general conversions between the language server protocol * and Atom/Atom packages. */ class Convert { /** * Public: Convert a path to a Uri. * * @param filePath A file path to convert to a Uri. * @returns The Uri corresponding to the path. e.g. file:///a/b/c.txt */ static pathToUri(filePath) { if (new URL(filePath, "file://").protocol !== "file:") { return filePath; } let newPath = filePath.replace(/\\/g, "/"); if (newPath[0] !== "/") { newPath = `/${newPath}`; } return encodeURI(`file://${newPath}`).replace(/[#?]/g, encodeURIComponent); } /** * Public: Convert a Uri to a path. * * @param uri A Uri to convert to a file path. * @returns A file path corresponding to the Uri. e.g. /a/b/c.txt If the Uri does not begin file: then it is returned * as-is to allow Atom to deal with http/https sources in the future. */ static uriToPath(uri) { const url = new URL(uri, "file://"); if (url.protocol !== "file:" || url.pathname == null) { return uri; } let filePath = decodeURIComponent(url.pathname); if (process.platform === "win32") { // Deal with Windows drive names if (filePath[0] === "/") { filePath = filePath.substr(1); } return filePath.replace(/\//g, "\\"); } return filePath; } /** * Public: Convert an Atom {Point} to a language server {Position}. * * @param point An Atom {Point} to convert from. * @returns The {Position} representation of the Atom {PointObject}. */ static pointToPosition(point) { return { line: point.row, character: point.column }; } /** * Public: Convert a language server {Position} into an Atom {PointObject}. * * @param position A language server {Position} to convert from. * @returns The Atom {PointObject} representation of the given {Position}. */ static positionToPoint(position) { return new atom_1.Point(position.line, position.character); } /** * Public: Convert a language server {Range} into an Atom {Range}. * * @param range A language server {Range} to convert from. * @returns The Atom {Range} representation of the given language server {Range}. */ static lsRangeToAtomRange(range) { return new atom_1.Range(Convert.positionToPoint(range.start), Convert.positionToPoint(range.end)); } /** * Public: Convert an Atom {Range} into an language server {Range}. * * @param range An Atom {Range} to convert from. * @returns The language server {Range} representation of the given Atom {Range}. */ static atomRangeToLSRange(range) { return { start: Convert.pointToPosition(range.start), end: Convert.pointToPosition(range.end), }; } /** * Public: Create a {TextDocumentIdentifier} from an Atom {TextEditor}. * * @param editor A {TextEditor} that will be used to form the uri property. * @returns A {TextDocumentIdentifier} that has a `uri` property with the Uri for the given editor's path. */ static editorToTextDocumentIdentifier(editor) { return { uri: Convert.pathToUri(editor.getPath() || "") }; } /** * Public: Create a {TextDocumentPositionParams} from a {TextEditor} and optional {Point}. * * @param editor A {TextEditor} that will be used to form the uri property. * @param point An optional {Point} that will supply the position property. If not specified the current cursor * position will be used. * @returns A {TextDocumentPositionParams} that has textDocument property with the editors {TextDocumentIdentifier} * and a position property with the supplied point (or current cursor position when not specified). */ static editorToTextDocumentPositionParams(editor, point) { return { textDocument: Convert.editorToTextDocumentIdentifier(editor), position: Convert.pointToPosition(point != null ? point : editor.getCursorBufferPosition()), }; } /** * Public: Create a string of scopes for the atom text editor using the data-grammar selector from an {Array} of * grammarScope strings. * * @param grammarScopes An {Array} of grammar scope string to convert from. * @returns A single comma-separated list of CSS selectors targetting the grammars of Atom text editors. e.g. `['c', * 'cpp']` => `'atom-text-editor[data-grammar='c'], atom-text-editor[data-grammar='cpp']` */ static grammarScopesToTextEditorScopes(grammarScopes) { return grammarScopes .map((g) => `atom-text-editor[data-grammar="${Convert.encodeHTMLAttribute(g.replace(/\./g, " "))}"]`) .join(", "); } /** * Public: Encode a string so that it can be safely used within a HTML attribute - i.e. replacing all quoted values * with their HTML entity encoded versions. e.g. `Hello"` becomes `Hello&quot;` * * @param s A string to be encoded. * @returns A string that is HTML attribute encoded by replacing &, <, >, " and ' with their HTML entity named equivalents. */ static encodeHTMLAttribute(s) { const attributeMap = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&apos;", }; return s.replace(/["&'<>]/g, (c) => attributeMap[c]); } /** * Public: Convert an Atom File Event as received from atom.project.onDidChangeFiles and convert it into an Array of * Language Server Protocol {FileEvent} objects. Normally this will be a 1-to-1 but renames will be represented by a * deletion and a subsequent creation as LSP does not know about renames. * * @param fileEvent An {atom$ProjectFileEvent} to be converted. * @returns An array of LSP {ls.FileEvent} objects that equivalent conversions to the fileEvent parameter. */ static atomFileEventToLSFileEvents(fileEvent) { switch (fileEvent.action) { case "created": return [{ uri: Convert.pathToUri(fileEvent.path), type: ls.FileChangeType.Created }]; case "modified": return [{ uri: Convert.pathToUri(fileEvent.path), type: ls.FileChangeType.Changed }]; case "deleted": return [{ uri: Convert.pathToUri(fileEvent.path), type: ls.FileChangeType.Deleted }]; case "renamed": { const results = []; if (fileEvent.oldPath) { results.push({ uri: Convert.pathToUri(fileEvent.oldPath), type: ls.FileChangeType.Deleted }); } if (fileEvent.path) { results.push({ uri: Convert.pathToUri(fileEvent.path), type: ls.FileChangeType.Created }); } return results; } default: return []; } } /** @deprecated Use Linter V2 service */ static atomIdeDiagnosticToLSDiagnostic(diagnostic) { // eslint-disable-next-line import/no-deprecated return diagnostic_adapter_1.atomIdeDiagnosticToLSDiagnostic(diagnostic); } /** @deprecated Use Linter V2 service */ static diagnosticTypeToLSSeverity(type) { // eslint-disable-next-line import/no-deprecated return diagnostic_adapter_1.diagnosticTypeToLSSeverity(type); } /** * Public: Convert an array of language server protocol {atomIde.TextEdit} objects to an equivalent array of Atom * {atomIde.TextEdit} objects. * * @param textEdits The language server protocol {atomIde.TextEdit} objects to convert. * @returns An {Array} of Atom {atomIde.TextEdit} objects. */ static convertLsTextEdits(textEdits) { return (textEdits || []).map(Convert.convertLsTextEdit); } /** * Public: Convert a language server protocol {atomIde.TextEdit} object to the Atom equivalent {atomIde.TextEdit}. * * @param textEdits The language server protocol {atomIde.TextEdit} objects to convert. * @returns An Atom {atomIde.TextEdit} object. */ static convertLsTextEdit(textEdit) { // TODO: support annotations return { oldRange: Convert.lsRangeToAtomRange(textEdit.range), newText: textEdit.newText, }; } } exports.default = Convert; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9jb252ZXJ0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQ0EsdUNBQXNDO0FBQ3RDLCtCQUFpRTtBQUVqRSxnREFBZ0Q7QUFDaEQsc0VBQTJHO0FBRTNHOzs7R0FHRztBQUNILE1BQXFCLE9BQU87SUFDMUI7Ozs7O09BS0c7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUFDLFFBQWdCO1FBQ3RDLElBQUksSUFBSSxHQUFHLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUU7WUFDckQsT0FBTyxRQUFRLENBQUE7U0FDaEI7UUFDRCxJQUFJLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQTtRQUMxQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUU7WUFDdEIsT0FBTyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7U0FDeEI7UUFDRCxPQUFPLFNBQVMsQ0FBQyxVQUFVLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxrQkFBa0IsQ0FBQyxDQUFBO0lBQzVFLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQVc7UUFDakMsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFBO1FBQ25DLElBQUksR0FBRyxDQUFDLFFBQVEsS0FBSyxPQUFPLElBQUksR0FBRyxDQUFDLFFBQVEsSUFBSSxJQUFJLEVBQUU7WUFDcEQsT0FBTyxHQUFHLENBQUE7U0FDWDtRQUVELElBQUksUUFBUSxHQUFHLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUMvQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxFQUFFO1lBQ2hDLGdDQUFnQztZQUNoQyxJ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QUFBO1NBQ1o7SUFDSCxDQUFDO0lBRUQsd0NBQXdDO0lBQ2pDLE1BQU0sQ0FBQywrQkFBK0IsQ0FBQyxVQUE4QjtRQUMxRSxnREFBZ0Q7UUFDaEQsT0FBTyxvREFBK0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtJQUNwRCxDQUFDO0lBRUQsd0NBQXdDO0lBQ2pDLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQyxJQUE0QjtRQUNuRSxnREFBZ0Q7UUFDaEQsT0FBTywrQ0FBMEIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUN6QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksTUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQWdDO1FBQy9ELE9BQU8sQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO0lBQ3pELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxRQUFxQjtRQUNuRCw0QkFBNEI7UUFDNUIsT0FBTztZQUNMLFFBQVEsRUFBRSxPQUFPLENBQUMsa0JBQWtCLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztZQUNwRCxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87U0FDMUIsQ0FBQTtJQUNILENBQUM7Q0FDRjtBQWxORCwwQkFrTkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSAqIGFzIGF0b21JZGUgZnJvbSBcImF0b20taWRlLWJhc2VcIlxuaW1wb3J0ICogYXMgbHMgZnJvbSBcIi4vbGFuZ3VhZ2VjbGllbnRcIlxuaW1wb3J0IHsgUG9pbnQsIEZpbGVzeXN0ZW1DaGFuZ2UsIFJhbmdlLCBUZXh0RWRpdG9yIH0gZnJvbSBcImF0b21cIlxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWRlcHJlY2F0ZWRcbmltcG9ydCB7IGRpYWdub3N0aWNUeXBlVG9MU1NldmVyaXR5LCBhdG9tSWRlRGlhZ25vc3RpY1RvTFNEaWFnbm9zdGljIH0gZnJvbSBcIi4vYWRhcHRlcnMvZGlhZ25vc3RpYy1hZGFwdGVyXCJcblxuLyoqXG4gKiBQdWJsaWM6IENsYXNzIHRoYXQgY29udGFpbnMgYSBudW1iZXIgb2YgaGVscGVyIG1ldGhvZHMgZm9yIGdlbmVyYWwgY29udmVyc2lvbnMgYmV0d2VlbiB0aGUgbGFuZ3VhZ2Ugc2VydmVyIHByb3RvY29sXG4gKiBhbmQgQXRvbS9BdG9tIHBhY2thZ2VzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDb252ZXJ0IHtcbiAgLyoqXG4gICAqIFB1YmxpYzogQ29udmVydCBhIHBhdGggdG8gYSBVcmkuXG4gICAqXG4gICAqIEBwYXJhbSBmaWxlUGF0aCBBIGZpbGUgcGF0aCB0byBjb252ZXJ0IHRvIGEgVXJpLlxuICAgKiBAcmV0dXJucyBUaGUgVXJpIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHBhdGguIGUuZy4gZmlsZTovLy9hL2IvYy50eHRcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcGF0aFRvVXJpKGZpbGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmIChuZXcgVVJMKGZpbGVQYXRoLCBcImZpbGU6Ly9cIikucHJvdG9jb2wgIT09IFwiZmlsZTpcIikge1xuICAgICAgcmV0dXJuIGZpbGVQYXRoXG4gICAgfVxuICAgIGxldCBuZXdQYXRoID0gZmlsZVBhdGgucmVwbGFjZSgvXFxcXC9nLCBcIi9cIilcbiAgICBpZiAobmV3UGF0aFswXSAhPT0gXCIvXCIpIHtcbiAgICAgIG5ld1BhdGggPSBgLyR7bmV3UGF0aH1gXG4gICAgfVxuICAgIHJldHVybiBlbmNvZGVVUkkoYGZpbGU6Ly8ke25ld1BhdGh9YCkucmVwbGFjZSgvWyM/XS9nLCBlbmNvZGVVUklDb21wb25lbnQpXG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBDb252ZXJ0IGEgVXJpIHRvIGEgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHVyaSBBIFVyaSB0byBjb252ZXJ0IHRvIGEgZmlsZSBwYXRoLlxuICAgKiBAcmV0dXJucyBBIGZpbGUgcGF0aCBjb3JyZXNwb25kaW5nIHRvIHRoZSBVcmkuIGUuZy4gL2EvYi9jLnR4dCBJZiB0aGUgVXJpIGRvZXMgbm90IGJlZ2luIGZpbGU6IHRoZW4gaXQgaXMgcmV0dXJuZWRcbiAgICogICBhcy1pcyB0byBhbGxvdyBBdG9tIHRvIGRlYWwgd2l0aCBodHRwL2h0dHBzIHNvdXJjZXMgaW4gdGhlIGZ1dHVyZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgdXJpVG9QYXRoKHVyaTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHVyaSwgXCJmaWxlOi8vXCIpXG4gICAgaWYgKHVybC5wcm90b2NvbCAhPT0gXCJmaWxlOlwiIHx8IHVybC5wYXRobmFtZSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdXJpXG4gICAgfVxuXG4gICAgbGV0IGZpbGVQYXRoID0gZGVjb2RlVVJJQ29tcG9uZW50KHVybC5wYXRobmFtZSlcbiAgICBpZiAocHJvY2Vzcy5wbGF0Zm9ybSA9PT0gXCJ3aW4zMlwiKSB7XG4gICAgICAvLyBEZWFsIHdpdGggV2luZG93cyBkcml2ZSBuYW1lc1xuICAgICAgaWYgKGZpbGVQYXRoWzBdID09PSBcIi9cIikge1xuICAgICAgICBmaWxlUGF0aCA9IGZpbGVQYXRoLnN1YnN0cigxKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZpbGVQYXRoLnJlcGxhY2UoL1xcLy9nLCBcIlxcXFxcIilcbiAgICB9XG4gICAgcmV0dXJuIGZpbGVQYXRoXG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBDb252ZXJ0IGFuIEF0b20ge1BvaW50fSB0byBhIGxhbmd1YWdlIHNlcnZlciB7UG9zaXRpb259LlxuICAgKlxuICAgKiBAcGFyYW0gcG9pbnQgQW4gQXRvbSB7UG9pbnR9IHRvIGNvbnZlcnQgZnJvbS5cbiAgICogQHJldHVybnMgVGhlIHtQb3NpdGlvbn0gcmVwcmVzZW50YXRpb24gb2YgdGhlIEF0b20ge1BvaW50T2JqZWN0fS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcG9pbnRUb1Bvc2l0aW9uKHBvaW50OiBQb2ludCk6IGxzLlBvc2l0aW9uIHtcbiAgICByZXR1cm4geyBsaW5lOiBwb2ludC5yb3csIGNoYXJhY3RlcjogcG9pbnQuY29sdW1uIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IENvbnZlcnQgYSBsYW5ndWFnZSBzZXJ2ZXIge1Bvc2l0aW9ufSBpbnRvIGFuIEF0b20ge1BvaW50T2JqZWN0fS5cbiAgICpcbiAgICogQHBhcmFtIHBvc2l0aW9uIEEgbGFuZ3VhZ2Ugc2VydmVyIHtQb3NpdGlvbn0gdG8gY29udmVydCBmcm9tLlxuICAgKiBAcmV0dXJucyBUaGUgQXRvbSB7UG9pbnRPYmplY3R9IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBnaXZlbiB7UG9zaXRpb259LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBwb3NpdGlvblRvUG9pbnQocG9zaXRpb246IGxzLlBvc2l0aW9uKTogUG9pbnQge1xuICAgIHJldHVybiBuZXcgUG9pbnQocG9zaXRpb24ubGluZSwgcG9zaXRpb24uY2hhcmFjdGVyKVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogQ29udmVydCBhIGxhbmd1YWdlIHNlcnZlciB7UmFuZ2V9IGludG8gYW4gQXRvbSB7UmFuZ2V9LlxuICAgKlxuICAgKiBAcGFyYW0gcmFuZ2UgQSBsYW5ndWFnZSBzZXJ2ZXIge1JhbmdlfSB0byBjb252ZXJ0IGZyb20uXG4gICAqIEByZXR1cm5zIFRoZSBBdG9tIHtSYW5nZX0gcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIGxhbmd1YWdlIHNlcnZlciB7UmFuZ2V9LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBsc1JhbmdlVG9BdG9tUmFuZ2UocmFuZ2U6IGxzLlJhbmdlKTogUmFuZ2Uge1xuICAgIHJldHVybiBuZXcgUmFuZ2UoQ29udmVydC5wb3NpdGlvblRvUG9pbnQocmFuZ2Uuc3RhcnQpLCBDb252ZXJ0LnBvc2l0aW9uVG9Qb2ludChyYW5nZS5lbmQpKVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogQ29udmVydCBhbiBBdG9tIHtSYW5nZX0gaW50byBhbiBsYW5ndWFnZSBzZXJ2ZXIge1JhbmdlfS5cbiAgICpcbiAgICogQHBhcmFtIHJhbmdlIEFuIEF0b20ge1JhbmdlfSB0byBjb252ZXJ0IGZyb20uXG4gICAqIEByZXR1cm5zIFRoZSBsYW5ndWFnZSBzZXJ2ZXIge1JhbmdlfSByZXByZXNlbnRhdGlvbiBvZiB0aGUgZ2l2ZW4gQXRvbSB7UmFuZ2V9LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhdG9tUmFuZ2VUb0xTUmFuZ2UocmFuZ2U6IFJhbmdlKTogbHMuUmFuZ2Uge1xuICAgIHJldHVybiB7XG4gICAgICBzdGFydDogQ29udmVydC5wb2ludFRvUG9zaXRpb24ocmFuZ2Uuc3RhcnQpLFxuICAgICAgZW5kOiBDb252ZXJ0LnBvaW50VG9Qb3NpdGlvbihyYW5nZS5lbmQpLFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IENyZWF0ZSBhIHtUZXh0RG9jdW1lbnRJZGVudGlmaWVyfSBmcm9tIGFuIEF0b20ge1RleHRFZGl0b3J9LlxuICAgKlxuICAgKiBAcGFyYW0gZWRpdG9yIEEge1RleHRFZGl0b3J9IHRoYXQgd2lsbCBiZSB1c2VkIHRvIGZvcm0gdGhlIHVyaSBwcm9wZXJ0eS5cbiAgICogQHJldHVybnMgQSB7VGV4dERvY3VtZW50SWRlbnRpZmllcn0gdGhhdCBoYXMgYSBgdXJpYCBwcm9wZXJ0eSB3aXRoIHRoZSBVcmkgZm9yIHRoZSBnaXZlbiBlZGl0b3IncyBwYXRoLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBlZGl0b3JUb1RleHREb2N1bWVudElkZW50aWZpZXIoZWRpdG9yOiBUZXh0RWRpdG9yKTogbHMuVGV4dERvY3VtZW50SWRlbnRpZmllciB7XG4gICAgcmV0dXJuIHsgdXJpOiBDb252ZXJ0LnBhdGhUb1VyaShlZGl0b3IuZ2V0UGF0aCgpIHx8IFwiXCIpIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IENyZWF0ZSBhIHtUZXh0RG9jdW1lbnRQb3NpdGlvblBhcmFtc30gZnJvbSBhIHtUZXh0RWRpdG9yfSBhbmQgb3B0aW9uYWwge1BvaW50fS5cbiAgICpcbiAgICogQHBhcmFtIGVkaXRvciBBIHtUZXh0RWRpdG9yfSB0aGF0IHdpbGwgYmUgdXNlZCB0byBmb3JtIHRoZSB1cmkgcHJvcGVydHkuXG4gICAqIEBwYXJhbSBwb2ludCBBbiBvcHRpb25hbCB7UG9pbnR9IHRoYXQgd2lsbCBzdXBwbHkgdGhlIHBvc2l0aW9uIHByb3BlcnR5LiBJZiBub3Qgc3BlY2lmaWVkIHRoZSBjdXJyZW50IGN1cnNvclxuICAgKiAgIHBvc2l0aW9uIHdpbGwgYmUgdXNlZC5cbiAgICogQHJldHVybnMgQSB7VGV4dERvY3VtZW50UG9zaXRpb25QYXJhbXN9IHRoYXQgaGFzIHRleHREb2N1bWVudCBwcm9wZXJ0eSB3aXRoIHRoZSBlZGl0b3JzIHtUZXh0RG9jdW1lbnRJZGVudGlmaWVyfVxuICAgKiAgIGFuZCBhIHBvc2l0aW9uIHByb3BlcnR5IHdpdGggdGhlIHN1cHBsaWVkIHBvaW50IChvciBjdXJyZW50IGN1cnNvciBwb3NpdGlvbiB3aGVuIG5vdCBzcGVjaWZpZWQpLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBlZGl0b3JUb1RleHREb2N1bWVudFBvc2l0aW9uUGFyYW1zKGVkaXRvcjogVGV4dEVkaXRvciwgcG9pbnQ/OiBQb2ludCk6IGxzLlRleHREb2N1bWVudFBvc2l0aW9uUGFyYW1zIHtcbiAgICByZXR1cm4ge1xuICAgICAgdGV4dERvY3VtZW50OiBDb252ZXJ0LmVkaXRvclRvVGV4dERvY3VtZW50SWRlbnRpZmllcihlZGl0b3IpLFxuICAgICAgcG9zaXRpb246IENvbnZlcnQucG9pbnRUb1Bvc2l0aW9uKHBvaW50ICE9IG51bGwgPyBwb2ludCA6IGVkaXRvci5nZXRDdXJzb3JCdWZmZXJQb3NpdGlvbigpKSxcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBDcmVhdGUgYSBzdHJpbmcgb2Ygc2NvcGVzIGZvciB0aGUgYXRvbSB0ZXh0IGVkaXRvciB1c2luZyB0aGUgZGF0YS1ncmFtbWFyIHNlbGVjdG9yIGZyb20gYW4ge0FycmF5fSBvZlxuICAgKiBncmFtbWFyU2NvcGUgc3RyaW5ncy5cbiAgICpcbiAgICogQHBhcmFtIGdyYW1tYXJTY29wZXMgQW4ge0FycmF5fSBvZiBncmFtbWFyIHNjb3BlIHN0cmluZyB0byBjb252ZXJ0IGZyb20uXG4gICAqIEByZXR1cm5zIEEgc2luZ2xlIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIENTUyBzZWxlY3RvcnMgdGFyZ2V0dGluZyB0aGUgZ3JhbW1hcnMgb2YgQXRvbSB0ZXh0IGVkaXRvcnMuIGUuZy4gYFsnYycsXG4gICAqICAgJ2NwcCddYCA9PiBgJ2F0b20tdGV4dC1lZGl0b3JbZGF0YS1ncmFtbWFyPSdjJ10sIGF0b20tdGV4dC1lZGl0b3JbZGF0YS1ncmFtbWFyPSdjcHAnXWBcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZ3JhbW1hclNjb3Blc1RvVGV4dEVkaXRvclNjb3BlcyhncmFtbWFyU2NvcGVzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdyYW1tYXJTY29wZXNcbiAgICAgIC5tYXAoKGcpID0+IGBhdG9tLXRleHQtZWRpdG9yW2RhdGEtZ3JhbW1hcj1cIiR7Q29udmVydC5lbmNvZGVIVE1MQXR0cmlidXRlKGcucmVwbGFjZSgvXFwuL2csIFwiIFwiKSl9XCJdYClcbiAgICAgIC5qb2luKFwiLCBcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaWM6IEVuY29kZSBhIHN0cmluZyBzbyB0aGF0IGl0IGNhbiBiZSBzYWZlbHkgdXNlZCB3aXRoaW4gYSBIVE1MIGF0dHJpYnV0ZSAtIGkuZS4gcmVwbGFjaW5nIGFsbCBxdW90ZWQgdmFsdWVzXG4gICAqIHdpdGggdGhlaXIgSFRNTCBlbnRpdHkgZW5jb2RlZCB2ZXJzaW9ucy4gZS5nLiBgSGVsbG9cImAgYmVjb21lcyBgSGVsbG8mcXVvdDtgXG4gICAqXG4gICAqIEBwYXJhbSBzIEEgc3RyaW5nIHRvIGJlIGVuY29kZWQuXG4gICAqIEByZXR1cm5zIEEgc3RyaW5nIHRoYXQgaXMgSFRNTCBhdHRyaWJ1dGUgZW5jb2RlZCBieSByZXBsYWNpbmcgJiwgPCwgPiwgXCIgYW5kICcgd2l0aCB0aGVpciBIVE1MIGVudGl0eSBuYW1lZCBlcXVpdmFsZW50cy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZW5jb2RlSFRNTEF0dHJpYnV0ZShzOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGF0dHJpYnV0ZU1hcDogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgIFwiJlwiOiBcIiZhbXA7XCIsXG4gICAgICBcIjxcIjogXCImbHQ7XCIsXG4gICAgICBcIj5cIjogXCImZ3Q7XCIsXG4gICAgICAnXCInOiBcIiZxdW90O1wiLFxuICAgICAgXCInXCI6IFwiJmFwb3M7XCIsXG4gICAgfVxuICAgIHJldHVybiBzLnJlcGxhY2UoL1tcIiYnPD5dL2csIChjKSA9PiBhdHRyaWJ1dGVNYXBbY10pXG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBDb252ZXJ0IGFuIEF0b20gRmlsZSBFdmVudCBhcyByZWNlaXZlZCBmcm9tIGF0b20ucHJvamVjdC5vbkRpZENoYW5nZUZpbGVzIGFuZCBjb252ZXJ0IGl0IGludG8gYW4gQXJyYXkgb2ZcbiAgICogTGFuZ3VhZ2UgU2VydmVyIFByb3RvY29sIHtGaWxlRXZlbnR9IG9iamVjdHMuIE5vcm1hbGx5IHRoaXMgd2lsbCBiZSBhIDEtdG8tMSBidXQgcmVuYW1lcyB3aWxsIGJlIHJlcHJlc2VudGVkIGJ5IGFcbiAgICogZGVsZXRpb24gYW5kIGEgc3Vic2VxdWVudCBjcmVhdGlvbiBhcyBMU1AgZG9lcyBub3Qga25vdyBhYm91dCByZW5hbWVzLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsZUV2ZW50IEFuIHthdG9tJFByb2plY3RGaWxlRXZlbnR9IHRvIGJlIGNvbnZlcnRlZC5cbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgTFNQIHtscy5GaWxlRXZlbnR9IG9iamVjdHMgdGhhdCBlcXVpdmFsZW50IGNvbnZlcnNpb25zIHRvIHRoZSBmaWxlRXZlbnQgcGFyYW1ldGVyLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhdG9tRmlsZUV2ZW50VG9MU0ZpbGVFdmVudHMoZmlsZUV2ZW50OiBGaWxlc3lzdGVtQ2hhbmdlKTogbHMuRmlsZUV2ZW50W10ge1xuICAgIHN3aXRjaCAoZmlsZUV2ZW50LmFjdGlvbikge1xuICAgICAgY2FzZSBcImNyZWF0ZWRcIjpcbiAgICAgICAgcmV0dXJuIFt7IHVyaTogQ29udmVydC5wYXRoVG9VcmkoZmlsZUV2ZW50LnBhdGgpLCB0eXBlOiBscy5GaWxlQ2hhbmdlVHlwZS5DcmVhdGVkIH1dXG4gICAgICBjYXNlIFwibW9kaWZpZWRcIjpcbiAgICAgICAgcmV0dXJuIFt7IHVyaTogQ29udmVydC5wYXRoVG9VcmkoZmlsZUV2ZW50LnBhdGgpLCB0eXBlOiBscy5GaWxlQ2hhbmdlVHlwZS5DaGFuZ2VkIH1dXG4gICAgICBjYXNlIFwiZGVsZXRlZFwiOlxuICAgICAgICByZXR1cm4gW3sgdXJpOiBDb252ZXJ0LnBhdGhUb1VyaShmaWxlRXZlbnQucGF0aCksIHR5cGU6IGxzLkZpbGVDaGFuZ2VUeXBlLkRlbGV0ZWQgfV1cbiAgICAgIGNhc2UgXCJyZW5hbWVkXCI6IHtcbiAgICAgICAgY29uc3QgcmVzdWx0czogQXJyYXk8eyB1cmk6IHN0cmluZzsgdHlwZTogbHMuRmlsZUNoYW5nZVR5cGUgfT4gPSBbXVxuICAgICAgICBpZiAoZmlsZUV2ZW50Lm9sZFBhdGgpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2goeyB1cmk6IENvbnZlcnQucGF0aFRvVXJpKGZpbGVFdmVudC5vbGRQYXRoKSwgdHlwZTogbHMuRmlsZUNoYW5nZVR5cGUuRGVsZXRlZCB9KVxuICAgICAgICB9XG4gICAgICAgIGlmIChmaWxlRXZlbnQucGF0aCkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaCh7IHVyaTogQ29udmVydC5wYXRoVG9VcmkoZmlsZUV2ZW50LnBhdGgpLCB0eXBlOiBscy5GaWxlQ2hhbmdlVHlwZS5DcmVhdGVkIH0pXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdHNcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBbXVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAZGVwcmVjYXRlZCBVc2UgTGludGVyIFYyIHNlcnZpY2UgKi9cbiAgcHVibGljIHN0YXRpYyBhdG9tSWRlRGlhZ25vc3RpY1RvTFNEaWFnbm9zdGljKGRpYWdub3N0aWM6IGF0b21JZGUuRGlhZ25vc3RpYyk6IGxzLkRpYWdub3N0aWMge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tZGVwcmVjYXRlZFxuICAgIHJldHVybiBhdG9tSWRlRGlhZ25vc3RpY1RvTFNEaWFnbm9zdGljKGRpYWdub3N0aWMpXG4gIH1cblxuICAvKiogQGRlcHJlY2F0ZWQgVXNlIExpbnRlciBWMiBzZXJ2aWNlICovXG4gIHB1YmxpYyBzdGF0aWMgZGlhZ25vc3RpY1R5cGVUb0xTU2V2ZXJpdHkodHlwZTogYXRvbUlkZS5EaWFnbm9zdGljVHlwZSk6IGxzLkRpYWdub3N0aWNTZXZlcml0eSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1kZXByZWNhdGVkXG4gICAgcmV0dXJuIGRpYWdub3N0aWNUeXBlVG9MU1NldmVyaXR5KHR5cGUpXG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBDb252ZXJ0IGFuIGFycmF5IG9mIGxhbmd1YWdlIHNlcnZlciBwcm90b2NvbCB7YXRvbUlkZS5UZXh0RWRpdH0gb2JqZWN0cyB0byBhbiBlcXVpdmFsZW50IGFycmF5IG9mIEF0b21cbiAgICoge2F0b21JZGUuVGV4dEVkaXR9IG9iamVjdHMuXG4gICAqXG4gICAqIEBwYXJhbSB0ZXh0RWRpdHMgVGhlIGxhbmd1YWdlIHNlcnZlciBwcm90b2NvbCB7YXRvbUlkZS5UZXh0RWRpdH0gb2JqZWN0cyB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyBBbiB7QXJyYXl9IG9mIEF0b20ge2F0b21JZGUuVGV4dEVkaXR9IG9iamVjdHMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnZlcnRMc1RleHRFZGl0cyh0ZXh0RWRpdHM/OiBscy5UZXh0RWRpdFtdIHwgbnVsbCk6IGF0b21JZGUuVGV4dEVkaXRbXSB7XG4gICAgcmV0dXJuICh0ZXh0RWRpdHMgfHwgW10pLm1hcChDb252ZXJ0LmNvbnZlcnRMc1RleHRFZGl0KVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogQ29udmVydCBhIGxhbmd1YWdlIHNlcnZlciBwcm90b2NvbCB7YXRvbUlkZS5UZXh0RWRpdH0gb2JqZWN0IHRvIHRoZSBBdG9tIGVxdWl2YWxlbnQge2F0b21JZGUuVGV4dEVkaXR9LlxuICAgKlxuICAgKiBAcGFyYW0gdGV4dEVkaXRzIFRoZSBsYW5ndWFnZSBzZXJ2ZXIgcHJvdG9jb2wge2F0b21JZGUuVGV4dEVkaXR9IG9iamVjdHMgdG8gY29udmVydC5cbiAgICogQHJldHVybnMgQW4gQXRvbSB7YXRvbUlkZS5UZXh0RWRpdH0gb2JqZWN0LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjb252ZXJ0THNUZXh0RWRpdCh0ZXh0RWRpdDogbHMuVGV4dEVkaXQpOiBhdG9tSWRlLlRleHRFZGl0IHtcbiAgICAvLyBUT0RPOiBzdXBwb3J0IGFubm90YXRpb25zXG4gICAgcmV0dXJuIHtcbiAgICAgIG9sZFJhbmdlOiBDb252ZXJ0LmxzUmFuZ2VUb0F0b21SYW5nZSh0ZXh0RWRpdC5yYW5nZSksXG4gICAgICBuZXdUZXh0OiB0ZXh0RWRpdC5uZXdUZXh0LFxuICAgIH1cbiAgfVxufVxuIl19