atom-languageclient
Version:
Integrate Language Servers with Atom
109 lines • 16.1 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const convert_1 = require("../convert");
const Utils = require("../utils");
const languageclient_1 = require("../languageclient");
const atom_1 = require("atom");
/**
* Public: Adapts the language server definition provider to the Atom IDE UI Definitions package for 'Go To Definition'
* functionality.
*/
class DefinitionAdapter {
/**
* Public: Determine whether this adapter can be used to adapt a language server based on the serverCapabilities
* matrix containing a definitionProvider.
*
* @param serverCapabilities The {ServerCapabilities} of the language server to consider.
* @returns A {Boolean} indicating adapter can adapt the server based on the given serverCapabilities.
*/
static canAdapt(serverCapabilities) {
return serverCapabilities.definitionProvider === true;
}
/**
* Public: Get the definitions for a symbol at a given {Point} within a {TextEditor} including optionally highlighting
* all other references within the document if the langauge server also supports highlighting.
*
* @param connection A {LanguageClientConnection} to the language server that will provide definitions and highlights.
* @param serverCapabilities The {ServerCapabilities} of the language server that will be used.
* @param languageName The name of the programming language.
* @param editor The Atom {TextEditor} containing the symbol and potential highlights.
* @param point The Atom {Point} containing the position of the text that represents the symbol for which the
* definition and highlights should be provided.
* @returns A {Promise} indicating adapter can adapt the server based on the given serverCapabilities.
*/
getDefinition(connection, serverCapabilities, languageName, editor, point) {
return __awaiter(this, void 0, void 0, function* () {
const documentPositionParams = convert_1.default.editorToTextDocumentPositionParams(editor, point);
const definitionLocations = DefinitionAdapter.normalizeLocations(yield connection.gotoDefinition(documentPositionParams));
if (definitionLocations == null || definitionLocations.length === 0) {
return null;
}
let queryRange;
if (serverCapabilities.documentHighlightProvider) {
const highlights = yield connection.documentHighlight(documentPositionParams);
if (highlights != null && highlights.length > 0) {
queryRange = highlights.map((h) => convert_1.default.lsRangeToAtomRange(h.range));
}
}
return {
queryRange: queryRange || [Utils.getWordAtPosition(editor, point)],
definitions: DefinitionAdapter.convertLocationsToDefinitions(definitionLocations, languageName),
};
});
}
/**
* Public: Normalize the locations so a single {Location} becomes an {Array} of just one. The language server protocol
* return either as the protocol evolved between v1 and v2.
*
* @param locationResult Either a single {Location} object or an {Array} of {Locations}.
* @returns An {Array} of {Location}s or {null} if the locationResult was null.
*/
static normalizeLocations(locationResult) {
if (locationResult == null) {
// TODO use ===
return null;
}
// TODO `d.targetRange.start` never becomes `null` according to the types
if (isLocationLinkArray(locationResult)) {
return locationResult.filter((d) => d.targetRange.start != null);
}
return (Array.isArray(locationResult) ? locationResult : [locationResult]).filter((d) => d.range.start != null);
}
/**
* Public: Convert an {Array} of {Location} objects into an Array of {Definition}s.
*
* @param locations An {Array} of {Location} objects to be converted.
* @param languageName The name of the language these objects are written in.
* @returns An {Array} of {Definition}s that represented the converted {Location}s.
*/
static convertLocationsToDefinitions(locations, languageName) {
if (isLocationLinkArray(locations)) {
return locations.map((d) => ({
path: convert_1.default.uriToPath(d.targetUri),
position: convert_1.default.positionToPoint(d.targetRange.start),
range: atom_1.Range.fromObject(convert_1.default.lsRangeToAtomRange(d.targetRange)),
language: languageName,
}));
}
return locations.map((d) => ({
path: convert_1.default.uriToPath(d.uri),
position: convert_1.default.positionToPoint(d.range.start),
range: atom_1.Range.fromObject(convert_1.default.lsRangeToAtomRange(d.range)),
language: languageName,
}));
}
}
exports.default = DefinitionAdapter;
function isLocationLinkArray(value) {
return Array.isArray(value) && languageclient_1.LocationLink.is(value[0]);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmaW5pdGlvbi1hZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL2FkYXB0ZXJzL2RlZmluaXRpb24tYWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUNBLHdDQUFnQztBQUNoQyxrQ0FBaUM7QUFDakMsc0RBQXdHO0FBQ3hHLCtCQUErQztBQUUvQzs7O0dBR0c7QUFDSCxNQUFxQixpQkFBaUI7SUFDcEM7Ozs7OztPQU1HO0lBQ0ksTUFBTSxDQUFDLFFBQVEsQ0FBQyxrQkFBc0M7UUFDM0QsT0FBTyxrQkFBa0IsQ0FBQyxrQkFBa0IsS0FBSyxJQUFJLENBQUE7SUFDdkQsQ0FBQztJQUVEOzs7Ozs7Ozs7OztPQVdHO0lBQ1UsYUFBYSxDQUN4QixVQUFvQyxFQUNwQyxrQkFBc0MsRUFDdEMsWUFBb0IsRUFDcEIsTUFBa0IsRUFDbEIsS0FBWTs7WUFFWixNQUFNLHNCQUFzQixHQUFHLGlCQUFPLENBQUMsa0NBQWtDLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFBO1lBQ3hGLE1BQU0sbUJBQW1CLEdBQUcsaUJBQWlCLENBQUMsa0JBQWtCLENBQzlELE1BQU0sVUFBVSxDQUFDLGNBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUN4RCxDQUFBO1lBQ0QsSUFBSSxtQkFBbUIsSUFBSSxJQUFJLElBQUksbUJBQW1CLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDbkUsT0FBTyxJQUFJLENBQUE7YUFDWjtZQUVELElBQUksVUFBVSxDQUFBO1lBQ2QsSUFBSSxrQkFBa0IsQ0FBQyx5QkFBeUIsRUFBRTtnQkFDaEQsTUFBTSxVQUFVLEdBQUcsTUFBTSxVQUFVLENBQUMsaUJBQWlCLENBQUMsc0JBQXNCLENBQUMsQ0FBQTtnQkFDN0UsSUFBSSxVQUFVLElBQUksSUFBSSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO29CQUMvQyxVQUFVLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsaUJBQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTtpQkFDeEU7YUFDRjtZQUVELE9BQU87Z0JBQ0wsVUFBVSxFQUFFLFVBQVUsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ2xFLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQyw2QkFBNkIsQ0FBQyxtQkFBbUIsRUFBRSxZQUFZLENBQUM7YUFDaEcsQ0FBQTtRQUNILENBQUM7S0FBQTtJQUVEOzs7Ozs7T0FNRztJQUNJLE1BQU0sQ0FBQyxrQkFBa0IsQ0FDOUIsY0FBNkQ7UUFFN0QsSUFBSSxjQUFjLElBQUksSUFBSSxFQUFFO1lBQzFCLGVBQWU7WUFDZixPQUFPLElBQUksQ0FBQTtTQUNaO1FBQ0QseUVBQXlFO1FBQ3pFLElBQUksbUJBQW1CLENBQUMsY0FBYyxDQUFDLEVBQUU7WUFDdkMsT0FBTyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQTtTQUNqRTtRQUNELE9BQU8sQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFBO0lBQ2pILENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxNQUFNLENBQUMsNkJBQTZCLENBQ3pDLFNBQXNDLEVBQ3RDLFlBQW9CO1FBRXBCLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDbEMsT0FBTyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUMzQixJQUFJLEVBQUUsaUJBQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDcEMsUUFBUSxFQUFFLGlCQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDO2dCQUN0RCxLQUFLLEVBQUUsWUFBSyxDQUFDLFVBQVUsQ0FBQyxpQkFBTyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDbEUsUUFBUSxFQUFFLFlBQVk7YUFDdkIsQ0FBQyxDQUFDLENBQUE7U0FDSjtRQUNELE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMzQixJQUFJLEVBQUUsaUJBQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUM5QixRQUFRLEVBQUUsaUJBQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7WUFDaEQsS0FBSyxFQUFFLFlBQUssQ0FBQyxVQUFVLENBQUMsaUJBQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUQsUUFBUSxFQUFFLFlBQVk7U0FDdkIsQ0FBQyxDQUFDLENBQUE7SUFDTCxDQUFDO0NBQ0Y7QUFwR0Qsb0NBb0dDO0FBRUQsU0FBUyxtQkFBbUIsQ0FBQyxLQUFVO0lBQ3JDLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSw2QkFBWSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtBQUMxRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgKiBhcyBhdG9tSWRlIGZyb20gXCJhdG9tLWlkZS1iYXNlXCJcbmltcG9ydCBDb252ZXJ0IGZyb20gXCIuLi9jb252ZXJ0XCJcbmltcG9ydCAqIGFzIFV0aWxzIGZyb20gXCIuLi91dGlsc1wiXG5pbXBvcnQgeyBMYW5ndWFnZUNsaWVudENvbm5lY3Rpb24sIExvY2F0aW9uLCBMb2NhdGlvbkxpbmssIFNlcnZlckNhcGFiaWxpdGllcyB9IGZyb20gXCIuLi9sYW5ndWFnZWNsaWVudFwiXG5pbXBvcnQgeyBQb2ludCwgVGV4dEVkaXRvciwgUmFuZ2UgfSBmcm9tIFwiYXRvbVwiXG5cbi8qKlxuICogUHVibGljOiBBZGFwdHMgdGhlIGxhbmd1YWdlIHNlcnZlciBkZWZpbml0aW9uIHByb3ZpZGVyIHRvIHRoZSBBdG9tIElERSBVSSBEZWZpbml0aW9ucyBwYWNrYWdlIGZvciAnR28gVG8gRGVmaW5pdGlvbidcbiAqIGZ1bmN0aW9uYWxpdHkuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIERlZmluaXRpb25BZGFwdGVyIHtcbiAgLyoqXG4gICAqIFB1YmxpYzogRGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBhZGFwdGVyIGNhbiBiZSB1c2VkIHRvIGFkYXB0IGEgbGFuZ3VhZ2Ugc2VydmVyIGJhc2VkIG9uIHRoZSBzZXJ2ZXJDYXBhYmlsaXRpZXNcbiAgICogbWF0cml4IGNvbnRhaW5pbmcgYSBkZWZpbml0aW9uUHJvdmlkZXIuXG4gICAqXG4gICAqIEBwYXJhbSBzZXJ2ZXJDYXBhYmlsaXRpZXMgVGhlIHtTZXJ2ZXJDYXBhYmlsaXRpZXN9IG9mIHRoZSBsYW5ndWFnZSBzZXJ2ZXIgdG8gY29uc2lkZXIuXG4gICAqIEByZXR1cm5zIEEge0Jvb2xlYW59IGluZGljYXRpbmcgYWRhcHRlciBjYW4gYWRhcHQgdGhlIHNlcnZlciBiYXNlZCBvbiB0aGUgZ2l2ZW4gc2VydmVyQ2FwYWJpbGl0aWVzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBjYW5BZGFwdChzZXJ2ZXJDYXBhYmlsaXRpZXM6IFNlcnZlckNhcGFiaWxpdGllcyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBzZXJ2ZXJDYXBhYmlsaXRpZXMuZGVmaW5pdGlvblByb3ZpZGVyID09PSB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBHZXQgdGhlIGRlZmluaXRpb25zIGZvciBhIHN5bWJvbCBhdCBhIGdpdmVuIHtQb2ludH0gd2l0aGluIGEge1RleHRFZGl0b3J9IGluY2x1ZGluZyBvcHRpb25hbGx5IGhpZ2hsaWdodGluZ1xuICAgKiBhbGwgb3RoZXIgcmVmZXJlbmNlcyB3aXRoaW4gdGhlIGRvY3VtZW50IGlmIHRoZSBsYW5nYXVnZSBzZXJ2ZXIgYWxzbyBzdXBwb3J0cyBoaWdobGlnaHRpbmcuXG4gICAqXG4gICAqIEBwYXJhbSBjb25uZWN0aW9uIEEge0xhbmd1YWdlQ2xpZW50Q29ubmVjdGlvbn0gdG8gdGhlIGxhbmd1YWdlIHNlcnZlciB0aGF0IHdpbGwgcHJvdmlkZSBkZWZpbml0aW9ucyBhbmQgaGlnaGxpZ2h0cy5cbiAgICogQHBhcmFtIHNlcnZlckNhcGFiaWxpdGllcyBUaGUge1NlcnZlckNhcGFiaWxpdGllc30gb2YgdGhlIGxhbmd1YWdlIHNlcnZlciB0aGF0IHdpbGwgYmUgdXNlZC5cbiAgICogQHBhcmFtIGxhbmd1YWdlTmFtZSBUaGUgbmFtZSBvZiB0aGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UuXG4gICAqIEBwYXJhbSBlZGl0b3IgVGhlIEF0b20ge1RleHRFZGl0b3J9IGNvbnRhaW5pbmcgdGhlIHN5bWJvbCBhbmQgcG90ZW50aWFsIGhpZ2hsaWdodHMuXG4gICAqIEBwYXJhbSBwb2ludCBUaGUgQXRvbSB7UG9pbnR9IGNvbnRhaW5pbmcgdGhlIHBvc2l0aW9uIG9mIHRoZSB0ZXh0IHRoYXQgcmVwcmVzZW50cyB0aGUgc3ltYm9sIGZvciB3aGljaCB0aGVcbiAgICogICBkZWZpbml0aW9uIGFuZCBoaWdobGlnaHRzIHNob3VsZCBiZSBwcm92aWRlZC5cbiAgICogQHJldHVybnMgQSB7UHJvbWlzZX0gaW5kaWNhdGluZyBhZGFwdGVyIGNhbiBhZGFwdCB0aGUgc2VydmVyIGJhc2VkIG9uIHRoZSBnaXZlbiBzZXJ2ZXJDYXBhYmlsaXRpZXMuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgZ2V0RGVmaW5pdGlvbihcbiAgICBjb25uZWN0aW9uOiBMYW5ndWFnZUNsaWVudENvbm5lY3Rpb24sXG4gICAgc2VydmVyQ2FwYWJpbGl0aWVzOiBTZXJ2ZXJDYXBhYmlsaXRpZXMsXG4gICAgbGFuZ3VhZ2VOYW1lOiBzdHJpbmcsXG4gICAgZWRpdG9yOiBUZXh0RWRpdG9yLFxuICAgIHBvaW50OiBQb2ludFxuICApOiBQcm9taXNlPGF0b21JZGUuRGVmaW5pdGlvblF1ZXJ5UmVzdWx0IHwgbnVsbD4ge1xuICAgIGNvbnN0IGRvY3VtZW50UG9zaXRpb25QYXJhbXMgPSBDb252ZXJ0LmVkaXRvclRvVGV4dERvY3VtZW50UG9zaXRpb25QYXJhbXMoZWRpdG9yLCBwb2ludClcbiAgICBjb25zdCBkZWZpbml0aW9uTG9jYXRpb25zID0gRGVmaW5pdGlvbkFkYXB0ZXIubm9ybWFsaXplTG9jYXRpb25zKFxuICAgICAgYXdhaXQgY29ubmVjdGlvbi5nb3RvRGVmaW5pdGlvbihkb2N1bWVudFBvc2l0aW9uUGFyYW1zKVxuICAgIClcbiAgICBpZiAoZGVmaW5pdGlvbkxvY2F0aW9ucyA9PSBudWxsIHx8IGRlZmluaXRpb25Mb2NhdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIGxldCBxdWVyeVJhbmdlXG4gICAgaWYgKHNlcnZlckNhcGFiaWxpdGllcy5kb2N1bWVudEhpZ2hsaWdodFByb3ZpZGVyKSB7XG4gICAgICBjb25zdCBoaWdobGlnaHRzID0gYXdhaXQgY29ubmVjdGlvbi5kb2N1bWVudEhpZ2hsaWdodChkb2N1bWVudFBvc2l0aW9uUGFyYW1zKVxuICAgICAgaWYgKGhpZ2hsaWdodHMgIT0gbnVsbCAmJiBoaWdobGlnaHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcXVlcnlSYW5nZSA9IGhpZ2hsaWdodHMubWFwKChoKSA9PiBDb252ZXJ0LmxzUmFuZ2VUb0F0b21SYW5nZShoLnJhbmdlKSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcXVlcnlSYW5nZTogcXVlcnlSYW5nZSB8fCBbVXRpbHMuZ2V0V29yZEF0UG9zaXRpb24oZWRpdG9yLCBwb2ludCldLFxuICAgICAgZGVmaW5pdGlvbnM6IERlZmluaXRpb25BZGFwdGVyLmNvbnZlcnRMb2NhdGlvbnNUb0RlZmluaXRpb25zKGRlZmluaXRpb25Mb2NhdGlvbnMsIGxhbmd1YWdlTmFtZSksXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFB1YmxpYzogTm9ybWFsaXplIHRoZSBsb2NhdGlvbnMgc28gYSBzaW5nbGUge0xvY2F0aW9ufSBiZWNvbWVzIGFuIHtBcnJheX0gb2YganVzdCBvbmUuIFRoZSBsYW5ndWFnZSBzZXJ2ZXIgcHJvdG9jb2xcbiAgICogcmV0dXJuIGVpdGhlciBhcyB0aGUgcHJvdG9jb2wgZXZvbHZlZCBiZXR3ZWVuIHYxIGFuZCB2Mi5cbiAgICpcbiAgICogQHBhcmFtIGxvY2F0aW9uUmVzdWx0IEVpdGhlciBhIHNpbmdsZSB7TG9jYXRpb259IG9iamVjdCBvciBhbiB7QXJyYXl9IG9mIHtMb2NhdGlvbnN9LlxuICAgKiBAcmV0dXJucyBBbiB7QXJyYXl9IG9mIHtMb2NhdGlvbn1zIG9yIHtudWxsfSBpZiB0aGUgbG9jYXRpb25SZXN1bHQgd2FzIG51bGwuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG5vcm1hbGl6ZUxvY2F0aW9ucyhcbiAgICBsb2NhdGlvblJlc3VsdDogTG9jYXRpb24gfCBMb2NhdGlvbltdIHwgTG9jYXRpb25MaW5rW10gfCBudWxsXG4gICk6IExvY2F0aW9uW10gfCBMb2NhdGlvbkxpbmtbXSB8IG51bGwge1xuICAgIGlmIChsb2NhdGlvblJlc3VsdCA9PSBudWxsKSB7XG4gICAgICAvLyBUT0RPIHVzZSA9PT1cbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICAgIC8vIFRPRE8gYGQudGFyZ2V0UmFuZ2Uuc3RhcnRgIG5ldmVyIGJlY29tZXMgYG51bGxgIGFjY29yZGluZyB0byB0aGUgdHlwZXNcbiAgICBpZiAoaXNMb2NhdGlvbkxpbmtBcnJheShsb2NhdGlvblJlc3VsdCkpIHtcbiAgICAgIHJldHVybiBsb2NhdGlvblJlc3VsdC5maWx0ZXIoKGQpID0+IGQudGFyZ2V0UmFuZ2Uuc3RhcnQgIT0gbnVsbClcbiAgICB9XG4gICAgcmV0dXJuIChBcnJheS5pc0FycmF5KGxvY2F0aW9uUmVzdWx0KSA/IGxvY2F0aW9uUmVzdWx0IDogW2xvY2F0aW9uUmVzdWx0XSkuZmlsdGVyKChkKSA9PiBkLnJhbmdlLnN0YXJ0ICE9IG51bGwpXG4gIH1cblxuICAvKipcbiAgICogUHVibGljOiBDb252ZXJ0IGFuIHtBcnJheX0gb2Yge0xvY2F0aW9ufSBvYmplY3RzIGludG8gYW4gQXJyYXkgb2Yge0RlZmluaXRpb259cy5cbiAgICpcbiAgICogQHBhcmFtIGxvY2F0aW9ucyBBbiB7QXJyYXl9IG9mIHtMb2NhdGlvbn0gb2JqZWN0cyB0byBiZSBjb252ZXJ0ZWQuXG4gICAqIEBwYXJhbSBsYW5ndWFnZU5hbWUgVGhlIG5hbWUgb2YgdGhlIGxhbmd1YWdlIHRoZXNlIG9iamVjdHMgYXJlIHdyaXR0ZW4gaW4uXG4gICAqIEByZXR1cm5zIEFuIHtBcnJheX0gb2Yge0RlZmluaXRpb259cyB0aGF0IHJlcHJlc2VudGVkIHRoZSBjb252ZXJ0ZWQge0xvY2F0aW9ufXMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGNvbnZlcnRMb2NhdGlvbnNUb0RlZmluaXRpb25zKFxuICAgIGxvY2F0aW9uczogTG9jYXRpb25bXSB8IExvY2F0aW9uTGlua1tdLFxuICAgIGxhbmd1YWdlTmFtZTogc3RyaW5nXG4gICk6IGF0b21JZGUuRGVmaW5pdGlvbltdIHtcbiAgICBpZiAoaXNMb2NhdGlvbkxpbmtBcnJheShsb2NhdGlvbnMpKSB7XG4gICAgICByZXR1cm4gbG9jYXRpb25zLm1hcCgoZCkgPT4gKHtcbiAgICAgICAgcGF0aDogQ29udmVydC51cmlUb1BhdGgoZC50YXJnZXRVcmkpLFxuICAgICAgICBwb3NpdGlvbjogQ29udmVydC5wb3NpdGlvblRvUG9pbnQoZC50YXJnZXRSYW5nZS5zdGFydCksXG4gICAgICAgIHJhbmdlOiBSYW5nZS5mcm9tT2JqZWN0KENvbnZlcnQubHNSYW5nZVRvQXRvbVJhbmdlKGQudGFyZ2V0UmFuZ2UpKSxcbiAgICAgICAgbGFuZ3VhZ2U6IGxhbmd1YWdlTmFtZSxcbiAgICAgIH0pKVxuICAgIH1cbiAgICByZXR1cm4gbG9jYXRpb25zLm1hcCgoZCkgPT4gKHtcbiAgICAgIHBhdGg6IENvbnZlcnQudXJpVG9QYXRoKGQudXJpKSxcbiAgICAgIHBvc2l0aW9uOiBDb252ZXJ0LnBvc2l0aW9uVG9Qb2ludChkLnJhbmdlLnN0YXJ0KSxcbiAgICAgIHJhbmdlOiBSYW5nZS5mcm9tT2JqZWN0KENvbnZlcnQubHNSYW5nZVRvQXRvbVJhbmdlKGQucmFuZ2UpKSxcbiAgICAgIGxhbmd1YWdlOiBsYW5ndWFnZU5hbWUsXG4gICAgfSkpXG4gIH1cbn1cblxuZnVuY3Rpb24gaXNMb2NhdGlvbkxpbmtBcnJheSh2YWx1ZTogYW55KTogdmFsdWUgaXMgTG9jYXRpb25MaW5rW10ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgTG9jYXRpb25MaW5rLmlzKHZhbHVlWzBdKVxufVxuIl19
;