atom-languageclient
Version:
Integrate Language Servers with Atom
208 lines • 26.7 kB
JavaScript
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"`
*
* @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 = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
};
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
;